[WIP] Improves (#245)

This commit is contained in:
Guilherme Gazzo 2018-03-02 21:31:44 +00:00 committed by GitHub
parent 4823e3a2e4
commit 9e3714758f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 1766 additions and 1805 deletions

View File

@ -119,7 +119,7 @@ jobs:
ios-build: ios-build:
macos: macos:
xcode: "8.3.3" xcode: "9.0"
environment: environment:
BASH_ENV: "~/.nvm/nvm.sh" BASH_ENV: "~/.nvm/nvm.sh"

View File

@ -18,14 +18,7 @@ exports[`render channel 1`] = `
onResponderTerminate={[Function]} onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]} onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]} onStartShouldSetResponder={[Function]}
style={ style={null}
Array [
Object {
"backgroundColor": "transparent",
},
undefined,
]
}
testID={undefined} testID={undefined}
tvParallaxProperties={undefined} tvParallaxProperties={undefined}
> >
@ -185,14 +178,7 @@ exports[`render no icon 1`] = `
onResponderTerminate={[Function]} onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]} onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]} onStartShouldSetResponder={[Function]}
style={ style={null}
Array [
Object {
"backgroundColor": "transparent",
},
undefined,
]
}
testID={undefined} testID={undefined}
tvParallaxProperties={undefined} tvParallaxProperties={undefined}
> >
@ -352,14 +338,7 @@ exports[`render private group 1`] = `
onResponderTerminate={[Function]} onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]} onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]} onStartShouldSetResponder={[Function]}
style={ style={null}
Array [
Object {
"backgroundColor": "transparent",
},
undefined,
]
}
testID={undefined} testID={undefined}
tvParallaxProperties={undefined} tvParallaxProperties={undefined}
> >
@ -520,14 +499,7 @@ exports[`render unread +999 1`] = `
onResponderTerminate={[Function]} onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]} onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]} onStartShouldSetResponder={[Function]}
style={ style={null}
Array [
Object {
"backgroundColor": "transparent",
},
undefined,
]
}
testID={undefined} testID={undefined}
tvParallaxProperties={undefined} tvParallaxProperties={undefined}
> >
@ -721,14 +693,7 @@ exports[`render unread 1`] = `
onResponderTerminate={[Function]} onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]} onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]} onStartShouldSetResponder={[Function]}
style={ style={null}
Array [
Object {
"backgroundColor": "transparent",
},
undefined,
]
}
testID={undefined} testID={undefined}
tvParallaxProperties={undefined} tvParallaxProperties={undefined}
> >
@ -922,14 +887,7 @@ exports[`renders correctly 1`] = `
onResponderTerminate={[Function]} onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]} onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]} onStartShouldSetResponder={[Function]}
style={ style={null}
Array [
Object {
"backgroundColor": "transparent",
},
undefined,
]
}
testID={undefined} testID={undefined}
tvParallaxProperties={undefined} tvParallaxProperties={undefined}
> >

View File

@ -170,14 +170,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
onResponderTerminate={[Function]} onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]} onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]} onStartShouldSetResponder={[Function]}
style={ style={null}
Array [
Object {
"backgroundColor": "transparent",
},
undefined,
]
}
testID={undefined} testID={undefined}
tvParallaxProperties={undefined} tvParallaxProperties={undefined}
> >
@ -343,14 +336,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
onResponderTerminate={[Function]} onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]} onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]} onStartShouldSetResponder={[Function]}
style={ style={null}
Array [
Object {
"backgroundColor": "transparent",
},
undefined,
]
}
testID={undefined} testID={undefined}
tvParallaxProperties={undefined} tvParallaxProperties={undefined}
> >
@ -520,14 +506,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
onResponderTerminate={[Function]} onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]} onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]} onStartShouldSetResponder={[Function]}
style={ style={null}
Array [
Object {
"backgroundColor": "transparent",
},
undefined,
]
}
testID={undefined} testID={undefined}
tvParallaxProperties={undefined} tvParallaxProperties={undefined}
> >
@ -716,14 +695,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
onResponderTerminate={[Function]} onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]} onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]} onStartShouldSetResponder={[Function]}
style={ style={null}
Array [
Object {
"backgroundColor": "transparent",
},
undefined,
]
}
testID={undefined} testID={undefined}
tvParallaxProperties={undefined} tvParallaxProperties={undefined}
> >
@ -916,14 +888,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
onResponderTerminate={[Function]} onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]} onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]} onStartShouldSetResponder={[Function]}
style={ style={null}
Array [
Object {
"backgroundColor": "transparent",
},
undefined,
]
}
testID={undefined} testID={undefined}
tvParallaxProperties={undefined} tvParallaxProperties={undefined}
> >
@ -1112,14 +1077,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
onResponderTerminate={[Function]} onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]} onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]} onStartShouldSetResponder={[Function]}
style={ style={null}
Array [
Object {
"backgroundColor": "transparent",
},
undefined,
]
}
testID={undefined} testID={undefined}
tvParallaxProperties={undefined} tvParallaxProperties={undefined}
> >
@ -1308,14 +1266,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
onResponderTerminate={[Function]} onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]} onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]} onStartShouldSetResponder={[Function]}
style={ style={null}
Array [
Object {
"backgroundColor": "transparent",
},
undefined,
]
}
testID={undefined} testID={undefined}
tvParallaxProperties={undefined} tvParallaxProperties={undefined}
> >
@ -1504,14 +1455,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
onResponderTerminate={[Function]} onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]} onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]} onStartShouldSetResponder={[Function]}
style={ style={null}
Array [
Object {
"backgroundColor": "transparent",
},
undefined,
]
}
testID={undefined} testID={undefined}
tvParallaxProperties={undefined} tvParallaxProperties={undefined}
> >
@ -1700,14 +1644,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
onResponderTerminate={[Function]} onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]} onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]} onStartShouldSetResponder={[Function]}
style={ style={null}
Array [
Object {
"backgroundColor": "transparent",
},
undefined,
]
}
testID={undefined} testID={undefined}
tvParallaxProperties={undefined} tvParallaxProperties={undefined}
> >
@ -1873,14 +1810,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
onResponderTerminate={[Function]} onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]} onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]} onStartShouldSetResponder={[Function]}
style={ style={null}
Array [
Object {
"backgroundColor": "transparent",
},
undefined,
]
}
testID={undefined} testID={undefined}
tvParallaxProperties={undefined} tvParallaxProperties={undefined}
> >
@ -2046,14 +1976,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
onResponderTerminate={[Function]} onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]} onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]} onStartShouldSetResponder={[Function]}
style={ style={null}
Array [
Object {
"backgroundColor": "transparent",
},
undefined,
]
}
testID={undefined} testID={undefined}
tvParallaxProperties={undefined} tvParallaxProperties={undefined}
> >

View File

@ -17,4 +17,4 @@
# org.gradle.parallel=true # org.gradle.parallel=true
android.useDeprecatedNdk=true android.useDeprecatedNdk=true
# VERSIONCODE=999999999 VERSIONCODE=999999999

View File

@ -19,10 +19,6 @@ export default class Fade extends React.Component {
}; };
} }
componentWillMount() {
this._visibility = new Animated.Value(this.props.visible ? 1 : 0);
}
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
if (nextProps.visible) { if (nextProps.visible) {
this.setState({ visible: true }); this.setState({ visible: true });
@ -36,6 +32,10 @@ export default class Fade extends React.Component {
}); });
} }
UNSAFE_componentWillMount() {
this._visibility = new Animated.Value(this.props.visible ? 1 : 0);
}
render() { render() {
const { style, children, ...rest } = this.props; const { style, children, ...rest } = this.props;

View File

@ -38,14 +38,15 @@ export default class EmojiCategory extends React.Component {
this.size = Math.min(this.props.width || width, height) / (this.props.emojisPerRow || emojisPerRow); this.size = Math.min(this.props.width || width, height) / (this.props.emojisPerRow || emojisPerRow);
this.emojis = []; this.emojis = [];
} }
componentWillMount() {
this.emojis = this.props.emojis;
}
shouldComponentUpdate() { shouldComponentUpdate() {
return false; return false;
} }
UNSAFE_componentWillMount() {
this.emojis = this.props.emojis;
}
renderItem(emoji, size) { renderItem(emoji, size) {
return ( return (
<TouchableOpacity <TouchableOpacity

View File

@ -40,12 +40,6 @@ export default class EmojiPicker extends Component {
// return false; // return false;
// } // }
componentWillMount() {
this.frequentlyUsed.addListener(this.updateFrequentlyUsed);
this.customEmojis.addListener(this.updateCustomEmojis);
this.updateFrequentlyUsed();
this.updateCustomEmojis();
}
componentDidMount() { componentDidMount() {
requestAnimationFrame(() => this.setState({ show: true })); requestAnimationFrame(() => this.setState({ show: true }));
} }
@ -69,6 +63,14 @@ export default class EmojiPicker extends Component {
this.props.onEmojiSelected(emojify(shortname, { output: 'unicode' }), shortname); this.props.onEmojiSelected(emojify(shortname, { output: 'unicode' }), shortname);
} }
} }
UNSAFE_componentWillMount() {
this.frequentlyUsed.addListener(this.updateFrequentlyUsed);
this.customEmojis.addListener(this.updateCustomEmojis);
this.updateFrequentlyUsed();
this.updateCustomEmojis();
}
_addFrequentlyUsed = (emoji) => { _addFrequentlyUsed = (emoji) => {
database.write(() => { database.write(() => {
database.create('frequentlyUsedEmoji', emoji, true); database.create('frequentlyUsedEmoji', emoji, true);
@ -123,7 +125,6 @@ export default class EmojiPicker extends Component {
<ScrollableTabView <ScrollableTabView
renderTabBar={() => <TabBar tabEmojiStyle={this.props.tabEmojiStyle} />} renderTabBar={() => <TabBar tabEmojiStyle={this.props.tabEmojiStyle} />}
contentProps={scrollProps} contentProps={scrollProps}
// prerenderingSiblingsNumber={1}
> >
{ {
categories.tabs.map((tab, i) => ( categories.tabs.map((tab, i) => (

View File

@ -195,22 +195,20 @@ export default class MessageBox extends React.PureComponent {
this.setState({ text: '' }); this.setState({ text: '' });
this.closeEmoji(); this.closeEmoji();
this.stopTrackingMention(); this.stopTrackingMention();
requestAnimationFrame(() => { this.props.typing(false);
this.props.typing(false); if (message.trim() === '') {
if (message.trim() === '') { return;
return; }
} // if is editing a message
// if is editing a message const { editing } = this.props;
const { editing } = this.props; if (editing) {
if (editing) { const { _id, rid } = this.props.message;
const { _id, rid } = this.props.message; this.props.editRequest({ _id, msg: message, rid });
this.props.editRequest({ _id, msg: message, rid }); } else {
} else { // if is submiting a new message
// if is submiting a new message this.props.onSubmit(message);
this.props.onSubmit(message); }
} this.props.clearInput();
this.props.clearInput();
});
} }
_getFixedMentions(keyword) { _getFixedMentions(keyword) {

View File

@ -26,14 +26,11 @@ export default class Routes extends React.Component {
appInit: PropTypes.func.isRequired appInit: PropTypes.func.isRequired
} }
componentWillMount() {
return !this.props.app.ready && this.props.appInit();
}
componentDidMount() { componentDidMount() {
if (this.props.app.ready) { if (this.props.app.ready) {
SplashScreen.hide(); return SplashScreen.hide();
} }
this.props.appInit();
} }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {

View File

@ -35,7 +35,7 @@ const styles = StyleSheet.create({
backgroundColor: '#eeeeee' backgroundColor: '#eeeeee'
} }
}); });
const keyExtractor = item => item.id;
@connect(state => ({ @connect(state => ({
server: state.server.server server: state.server.server
}), dispatch => ({ }), dispatch => ({
@ -52,11 +52,6 @@ export default class Sidebar extends Component {
gotoAddServer: PropTypes.func.isRequired gotoAddServer: PropTypes.func.isRequired
} }
componentWillMount() {
database.databases.serversDB.addListener('change', this.updateState);
this.setState(this.getState());
}
componentWillUnmount() { componentWillUnmount() {
database.databases.serversDB.removeListener('change', this.updateState); database.databases.serversDB.removeListener('change', this.updateState);
} }
@ -77,6 +72,11 @@ export default class Sidebar extends Component {
servers: database.databases.serversDB.objects('servers') servers: database.databases.serversDB.objects('servers')
}) })
UNSAFE_componentWillMount() {
database.databases.serversDB.addListener('change', this.updateState);
this.setState(this.getState());
}
updateState = () => { updateState = () => {
this.setState(this.getState()); this.setState(this.getState());
} }
@ -103,7 +103,7 @@ export default class Sidebar extends Component {
<FlatList <FlatList
data={this.state.servers} data={this.state.servers}
renderItem={this.renderItem} renderItem={this.renderItem}
keyExtractor={item => item.id} keyExtractor={keyExtractor}
/> />
<TouchableHighlight <TouchableHighlight
onPress={() => { this.props.logout(); }} onPress={() => { this.props.logout(); }}

View File

@ -4,7 +4,7 @@ import { View, TouchableHighlight, Text, TouchableOpacity, Vibration, ViewPropTy
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import Icon from 'react-native-vector-icons/MaterialIcons'; import Icon from 'react-native-vector-icons/MaterialIcons';
import moment from 'moment'; import moment from 'moment';
// import equal from 'deep-equal'; import equal from 'deep-equal';
import { KeyboardUtils } from 'react-native-keyboard-input'; import { KeyboardUtils } from 'react-native-keyboard-input';
import { actionsShow, errorActionsShow, toggleReactionPicker } from '../../actions/messages'; import { actionsShow, errorActionsShow, toggleReactionPicker } from '../../actions/messages';
@ -32,6 +32,7 @@ import styles from './styles';
})) }))
export default class Message extends React.Component { export default class Message extends React.Component {
static propTypes = { static propTypes = {
status: PropTypes.any,
item: PropTypes.object.isRequired, item: PropTypes.object.isRequired,
reactions: PropTypes.any.isRequired, reactions: PropTypes.any.isRequired,
baseUrl: PropTypes.string.isRequired, baseUrl: PropTypes.string.isRequired,
@ -44,7 +45,8 @@ export default class Message extends React.Component {
toggleReactionPicker: PropTypes.func, toggleReactionPicker: PropTypes.func,
onReactionPress: PropTypes.func, onReactionPress: PropTypes.func,
style: ViewPropTypes.style, style: ViewPropTypes.style,
onLongPress: PropTypes.func onLongPress: PropTypes.func,
_updatedAt: PropTypes.instanceOf(Date)
} }
constructor(props) { constructor(props) {
@ -53,15 +55,15 @@ export default class Message extends React.Component {
this.onClose = this.onClose.bind(this); this.onClose = this.onClose.bind(this);
} }
// shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
// if (!equal(this.props.reactions, nextProps.reactions)) { if (!equal(this.props.reactions, nextProps.reactions)) {
// return true; return true;
// } }
// if (this.state.reactionsModal !== nextState.reactionsModal) { if (this.state.reactionsModal !== nextState.reactionsModal) {
// return true; return true;
// } }
// return this.props.item._updatedAt.toGMTString() !== nextProps.item._updatedAt.toGMTString() || this.props.item.status !== nextProps.item.status; return this.props._updatedAt.toGMTString() !== nextProps._updatedAt.toGMTString() || this.props.status !== nextProps.status;
// } }
onPress = () => { onPress = () => {
KeyboardUtils.dismiss(); KeyboardUtils.dismiss();

View File

@ -1,5 +1,4 @@
import { NavigationActions } from 'react-navigation'; import { NavigationActions } from 'react-navigation';
import reduxStore from '../../lib/createStore';
const config = {}; const config = {};
@ -30,7 +29,7 @@ export function goRoom({ rid, name }, counter = 0) {
return; return;
} }
if (!config.navigator) { if (!config.navigator) {
return setTimeout(() => goRoom({ rid, name }, counter + 1), 200); return setTimeout(() => goRoom({ rid, name }, counter + 1), 100);
} }
const action = NavigationActions.reset({ const action = NavigationActions.reset({
@ -41,5 +40,5 @@ export function goRoom({ rid, name }, counter = 0) {
] ]
}); });
requestAnimationFrame(() => config.navigator.dispatch(action), reduxStore.getState().app.starting); config.navigator.dispatch(action);
} }

View File

@ -41,6 +41,22 @@ const RocketChat = {
createChannel({ name, users, type }) { createChannel({ name, users, type }) {
return call(type ? 'createChannel' : 'createPrivateGroup', name, users, type); return call(type ? 'createChannel' : 'createPrivateGroup', name, users, type);
}, },
async createDirectMessageAndWait(username) {
const room = await RocketChat.createDirectMessage(username);
return new Promise((resolve) => {
const data = database.objects('subscriptions')
.filtered('rid = $1', room.rid);
if (data.length) {
return resolve(data[0]);
}
data.addListener(() => {
if (!data.length) { return; }
data.removeAllListeners();
resolve(data[0]);
});
});
},
async getUserToken() { async getUserToken() {
try { try {
@ -78,7 +94,7 @@ const RocketChat = {
reduxStore.dispatch(requestActiveUser(this.activeUsers)); reduxStore.dispatch(requestActiveUser(this.activeUsers));
this._setUserTimer = null; this._setUserTimer = null;
return this.activeUsers = {}; return this.activeUsers = {};
}, 1000); }, 5000);
this.activeUsers[ddpMessage.id] = status; this.activeUsers[ddpMessage.id] = status;
}, },
reconnect() { reconnect() {

View File

@ -1,6 +1,6 @@
export default function debounce(func, wait, immediate) { export default function debounce(func, wait, immediate) {
let timeout; let timeout;
return function _debounce(...args) { function _debounce(...args) {
const context = this; const context = this;
const later = function __debounce() { const later = function __debounce() {
timeout = null; timeout = null;
@ -10,5 +10,7 @@ export default function debounce(func, wait, immediate) {
clearTimeout(timeout); clearTimeout(timeout);
timeout = setTimeout(later, wait); timeout = setTimeout(later, wait);
if (callNow) { func.apply(context, args); } if (callNow) { func.apply(context, args); }
}; }
_debounce.stop = () => clearTimeout(timeout);
return _debounce;
} }

View File

@ -27,7 +27,7 @@ class ForgotPasswordView extends React.Component {
}; };
} }
componentWillMount() { componentDidMount() {
this.props.forgotPasswordInit(); this.props.forgotPasswordInit();
} }

View File

@ -88,14 +88,6 @@ export default class ListServerView extends React.Component {
this.data.addListener(this.updateState); this.data.addListener(this.updateState);
} }
componentWillMount() {
zeroconf.on('update', this.updateState);
zeroconf.scan('http', 'tcp', 'local.');
this.setState(this.getState());
}
componentDidUpdate() { componentDidUpdate() {
if (this.props.connected && if (this.props.connected &&
this.props.server && this.props.server &&
@ -148,6 +140,14 @@ export default class ListServerView extends React.Component {
}; };
}; };
UNSAFE_componentWillMount() {
zeroconf.on('update', this.updateState);
zeroconf.scan('http', 'tcp', 'local.');
this.setState(this.getState());
}
updateState = () => { updateState = () => {
this.setState(this.getState()); this.setState(this.getState());
} }
@ -173,6 +173,7 @@ export default class ListServerView extends React.Component {
</View> </View>
); );
renderSectionHeader = ({ section }) => ( renderSectionHeader = ({ section }) => (
<Text style={styles.headerStyle}>{section.title}</Text> <Text style={styles.headerStyle}>{section.title}</Text>
); );

View File

@ -70,10 +70,6 @@ export default class LoginView extends React.Component {
this.redirectRegex = new RegExp(`(?=.*(${ this.props.server }))(?=.*(credentialToken))(?=.*(credentialSecret))`, 'g'); this.redirectRegex = new RegExp(`(?=.*(${ this.props.server }))(?=.*(credentialToken))(?=.*(credentialSecret))`, 'g');
} }
componentWillMount() {
this.props.open();
}
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
if (this.props.services !== nextProps.services) { if (this.props.services !== nextProps.services) {
LayoutAnimation.easeInEaseOut(); LayoutAnimation.easeInEaseOut();
@ -154,6 +150,10 @@ export default class LoginView extends React.Component {
return Base64.encodeURI(JSON.stringify({ loginStyle: 'popup', credentialToken, isCordova: true })); return Base64.encodeURI(JSON.stringify({ loginStyle: 'popup', credentialToken, isCordova: true }));
} }
UNSAFE_componentWillMount() {
this.props.open();
}
openOAuth = (oAuthUrl) => { openOAuth = (oAuthUrl) => {
this.setState({ oAuthUrl, modalVisible: true }); this.setState({ oAuthUrl, modalVisible: true });
} }

View File

@ -34,7 +34,7 @@ export default class RoomHeaderView extends React.PureComponent {
super(props); super(props);
this.state = { this.state = {
room: {}, room: {},
roomName: props.navigation.state.params.name roomName: props.navigation.state.params.room.name
}; };
this.rid = props.navigation.state.params.room.rid; this.rid = props.navigation.state.params.room.rid;
this.room = realm.objects('subscriptions').filtered('rid = $0', this.rid); this.room = realm.objects('subscriptions').filtered('rid = $0', this.rid);
@ -66,8 +66,8 @@ export default class RoomHeaderView extends React.PureComponent {
renderLeft = () => (<HeaderBackButton renderLeft = () => (<HeaderBackButton
onPress={() => { onPress={() => {
this.props.close();
this.props.navigation.goBack(null); this.props.navigation.goBack(null);
requestAnimationFrame(() => this.props.close());
}} }}
tintColor='#292E35' tintColor='#292E35'
title='Back' title='Back'

View File

@ -65,6 +65,7 @@ export class List extends React.Component {
return (<ListView return (<ListView
enableEmptySections enableEmptySections
style={styles.list} style={styles.list}
data={this.data}
onEndReachedThreshold={0.5} onEndReachedThreshold={0.5}
renderFooter={this.props.renderFooter} renderFooter={this.props.renderFooter}
renderHeader={() => <Typing />} renderHeader={() => <Typing />}
@ -84,20 +85,9 @@ export class ListView extends OldList2 {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
curRenderedRowsCount: this.props.initialListSize, curRenderedRowsCount: 20,
highlightedRow: ({}: Object) highlightedRow: ({}: Object)
}; };
this.renderRow = this.renderRow.bind(this);
}
renderRow(_, sectionId, rowId, ...args) {
const { props } = this;
const item = props.dataSource.getRow(sectionId, rowId);
// The item could be null because our data is a snapshot and it was deleted.
return item ? props.renderRow(item, sectionId, rowId, ...args) : null;
} }
getInnerViewNode() { getInnerViewNode() {
@ -115,9 +105,6 @@ export class ListView extends OldList2 {
render() { render() {
const bodyComponents = []; const bodyComponents = [];
const { dataSource } = this.props;
const allRowIDs = dataSource.rowIdentities;
let rowCount = 0;
// const stickySectionHeaderIndices = []; // const stickySectionHeaderIndices = [];
// const { renderSectionHeader } = this.props; // const { renderSectionHeader } = this.props;
@ -126,58 +113,27 @@ export class ListView extends OldList2 {
const footer = this.props.renderFooter && this.props.renderFooter(); const footer = this.props.renderFooter && this.props.renderFooter();
// let totalIndex = header ? 1 : 0; // let totalIndex = header ? 1 : 0;
for (let sectionIdx = 0; sectionIdx < allRowIDs.length; sectionIdx += 1) { const { data } = this.props;
const sectionID = dataSource.sectionIdentities[sectionIdx]; let count = 0;
const rowIDs = allRowIDs[sectionIdx];
if (rowIDs.length === 0) { for (let i = 0; i < this.state.curRenderedRowsCount && i < data.length; i += 1, count += 1) {
const room = data[i];
bodyComponents.push(this.props.renderRow(room));
const nextData = data[i + 1];
if (!nextData) {
continue; // eslint-disable-line continue; // eslint-disable-line
} }
// if (renderSectionHeader) { if (!moment(room.ts).isSame(nextData.ts, 'day')) {
// const element = renderSectionHeader( bodyComponents.push(<DateSeparator key={room.ts.toISOString()} ts={room.ts} />);
// dataSource.getSectionHeaderData(sectionIdx),
// sectionID,
// );
// if (element) {
// bodyComponents.push(React.cloneElement(element, { key: `s_${ sectionID }` }), );
// if (this.props.stickySectionHeadersEnabled) {
// stickySectionHeaderIndices.push(totalIndex);
// }
// totalIndex++;
// }
// }
for (let rowIdx = 0; rowIdx < rowIDs.length; rowIdx += 1) {
const rowID = rowIDs[rowIdx];
const data = dataSource._dataBlob[sectionID][rowID];
bodyComponents.push(this.props.renderRow.bind(
null,
data,
sectionID,
rowID,
this._onRowHighlighted,
)());
if (rowIdx !== rowIDs.length - 1) {
const nextRowID = rowIDs[rowIdx + 1];
const nextData = dataSource._dataBlob[sectionID][nextRowID];
if (!moment(data.ts).isSame(nextData.ts, 'day')) {
bodyComponents.push(<DateSeparator key={data.ts.toISOString()} ts={data.ts} />);
}
if (this.props.lastOpen &&
moment(data.ts).isAfter(this.props.lastOpen) &&
moment(nextData.ts).isBefore(this.props.lastOpen)
) {
bodyComponents.push(<UnreadSeparator key='unread-separator' />);
}
}
// totalIndex += 1;
rowCount += 1;
if (rowCount === this.state.curRenderedRowsCount) {
break;
}
} }
if (rowCount >= this.state.curRenderedRowsCount) { if (this.props.lastOpen &&
break; moment(room.ts).isAfter(this.props.lastOpen) &&
moment(nextData.ts).isBefore(this.props.lastOpen)
) {
bodyComponents.push(<UnreadSeparator key='unread-separator' />);
} }
} }

View File

@ -37,8 +37,9 @@ export default class ReactionPicker extends React.Component {
} }
render() { render() {
const { width, height } = this.props.window; const { width, height, showReactionPicker } = this.props.window;
return (
return (showReactionPicker ?
<Modal <Modal
isVisible={this.props.showReactionPicker} isVisible={this.props.showReactionPicker}
style={{ alignItems: 'center' }} style={{ alignItems: 'center' }}
@ -54,7 +55,7 @@ export default class ReactionPicker extends React.Component {
onEmojiSelected={(emoji, shortname) => this.onEmojiSelected(emoji, shortname)} onEmojiSelected={(emoji, shortname) => this.onEmojiSelected(emoji, shortname)}
/> />
</View> </View>
</Modal> </Modal> : null
); );
} }
} }

View File

@ -73,7 +73,7 @@ export default class RoomView extends React.Component {
this.state = { this.state = {
loaded: true, loaded: true,
joined: typeof props.rid === 'undefined', joined: typeof props.rid === 'undefined',
room: {} room: this.rooms[0]
}; };
this.onReactionPress = this.onReactionPress.bind(this); this.onReactionPress = this.onReactionPress.bind(this);
} }
@ -110,10 +110,6 @@ export default class RoomView extends React.Component {
if (this.props.loading || this.state.end) { if (this.props.loading || this.state.end) {
return; return;
} }
if (!this.state.loaded) {
alert(2);
return;
}
requestAnimationFrame(() => { requestAnimationFrame(() => {
const lastRowData = data[data.length - 1]; const lastRowData = data[data.length - 1];
@ -159,6 +155,8 @@ export default class RoomView extends React.Component {
<Message <Message
key={item._id} key={item._id}
item={item} item={item}
_updatedAt={item._updatedAt}
status={item.status}
reactions={JSON.parse(JSON.stringify(item.reactions))} reactions={JSON.parse(JSON.stringify(item.reactions))}
baseUrl={this.props.Site_Url} baseUrl={this.props.Site_Url}
Message_TimeFormat={this.props.Message_TimeFormat} Message_TimeFormat={this.props.Message_TimeFormat}

View File

@ -20,7 +20,8 @@ import styles from './styles';
}), dispatch => ({ }), dispatch => ({
setSearch: searchText => dispatch(setSearch(searchText)) setSearch: searchText => dispatch(setSearch(searchText))
})) }))
export default class RoomsListHeaderView extends React.Component {
export default class RoomsListHeaderView extends React.PureComponent {
static propTypes = { static propTypes = {
navigation: PropTypes.object.isRequired, navigation: PropTypes.object.isRequired,
user: PropTypes.object.isRequired, user: PropTypes.object.isRequired,

View File

@ -15,6 +15,7 @@ import { goRoom } from '../../containers/routes/NavigationService';
import Header from '../../containers/Header'; import Header from '../../containers/Header';
import RoomsListHeader from './Header'; import RoomsListHeader from './Header';
import styles from './styles'; import styles from './styles';
import debounce from '../../utils/debounce';
const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
@connect(state => ({ @connect(state => ({
@ -63,10 +64,6 @@ export default class RoomsListView extends React.Component {
this.updateState(); this.updateState();
} }
// shouldComponentUpdate() {
// return false;
// }
componentWillReceiveProps(props) { componentWillReceiveProps(props) {
if (this.props.server !== props.server) { if (this.props.server !== props.server) {
this.data.removeListener(this.updateState); this.data.removeListener(this.updateState);
@ -76,10 +73,9 @@ export default class RoomsListView extends React.Component {
this.search(props.searchText); this.search(props.searchText);
} }
} }
// componentWillUpdate() {
// LayoutAnimation.easeInEaseOut();
// }
componentWillUnmount() { componentWillUnmount() {
this.updateState.stop();
this.data.removeAllListeners(); this.data.removeAllListeners();
} }
@ -88,109 +84,65 @@ export default class RoomsListView extends React.Component {
this.search(text); this.search(text);
} }
getLastMessage = (subscription) => { updateState = debounce(() => {
const [room] = database.objects('rooms').filtered('_id = $0', subscription.rid).slice(); this.forceUpdate();
return room && room.lastMessage; }, 1000);
}
search(text) { async search(text) {
const searchText = text.trim(); const searchText = text.trim();
if (searchText === '') { if (searchText === '') {
delete this.oldPromise;
return this.setState({ return this.setState({
dataSource: ds.cloneWithRows(this.data) search: false
}); });
} }
const data = this.data.filtered('name CONTAINS[c] $0', searchText).slice(); let data = this.data.filtered('name CONTAINS[c] $0', searchText).slice(0, 7);
const usernames = []; const usernames = data.map(sub => sub.map);
const dataSource = data.map((sub) => { try {
if (sub.t === 'd') { if (data.length < 7) {
usernames.push(sub.name); if (this.oldPromise) {
this.oldPromise('cancel');
}
const { users, rooms } = await Promise.race([
RocketChat.spotlight(searchText, usernames, { users: true, rooms: true }),
new Promise((resolve, reject) => this.oldPromise = reject)
]);
data = data.concat(users.map(user => ({
...user,
rid: user.username,
name: user.username,
t: 'd',
search: true
})), rooms.map(room => ({
rid: room._id,
...room,
search: true
})));
delete this.oldPromise;
} }
return sub; this.setState({
}); search: data
});
if (dataSource.length < 7) { } catch (e) {
if (this.oldPromise) { // alert(JSON.stringify(e));
this.oldPromise();
}
Promise.race([
RocketChat.spotlight(searchText, usernames),
new Promise((resolve, reject) => this.oldPromise = reject)
])
.then((results) => {
results.users.forEach((user) => {
dataSource.push({
...user,
name: user.username,
t: 'd',
search: true
});
});
results.rooms.forEach((room) => {
dataSource.push({
...room,
search: true
});
});
this.setState({
dataSource: ds.cloneWithRows(dataSource)
});
}, () => console.log('spotlight stopped'))
.then(() => delete this.oldPromise);
} }
this.setState({
dataSource: ds.cloneWithRows(dataSource)
});
} }
updateState = () => { _onPressItem = async(item = {}) => {
this.setState({
dataSource: ds.cloneWithRows(this.data)
});
// this.forceUpdate();
};
_onPressItem = (item = {}) => {
const clearSearch = () => {
this.setState({
searchText: ''
});
};
// if user is using the search we need first to join/create room // if user is using the search we need first to join/create room
if (item.search) { if (!item.search) {
if (item.t === 'd') { return this.props.navigation.navigate({ routeName: 'Room', params: { room: item, ...item } });
RocketChat.createDirectMessage(item.username)
.then(room => new Promise((resolve) => {
const data = database.objects('subscriptions')
.filtered('rid = $1', room.rid);
if (data.length) {
return resolve(data[0]);
}
data.addListener(() => {
if (data.length) {
resolve(data[0]);
data.removeAllListeners();
}
});
}))
.then(sub => goRoom({ room: sub, name: sub.name }))
.then(() => clearSearch());
} else {
clearSearch();
goRoom(item);
}
return;
} }
if (item.t === 'd') {
goRoom(item); const sub = await RocketChat.createDirectMessageAndWait(item.username);
clearSearch(); return goRoom({ room: sub, name: sub.name });
}
return goRoom(item);
} }
_createChannel() { _createChannel() {
@ -236,7 +188,7 @@ export default class RoomsListView extends React.Component {
renderList = () => ( renderList = () => (
<FlatList <FlatList
data={this.data} data={this.state.search ? this.state.search : this.data}
keyExtractor={this._keyExtractor} keyExtractor={this._keyExtractor}
dataSource={this.state.dataSource} dataSource={this.state.dataSource}
style={styles.list} style={styles.list}

1823
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,8 @@
"android": "react-native run-android", "android": "react-native run-android",
"storybook": "storybook start -p 7007", "storybook": "storybook start -p 7007",
"snyk-protect": "snyk protect", "snyk-protect": "snyk protect",
"prepare": "exit 0" "prepare": "exit 0",
"yarn": "yarn"
}, },
"rnpm": { "rnpm": {
"assets": [ "assets": [
@ -33,11 +34,11 @@
"js-base64": "^2.4.3", "js-base64": "^2.4.3",
"lodash": "^4.17.4", "lodash": "^4.17.4",
"moment": "^2.20.1", "moment": "^2.20.1",
"prop-types": "^15.6.0", "prop-types": "^15.6.1",
"react": "^16.2.0", "react": "^16.2.0",
"react-clone-referenced-element": "^1.0.1", "react-clone-referenced-element": "^1.0.1",
"react-emojione": "^5.0.0", "react-emojione": "^5.0.0",
"react-native": "^0.51.0", "react-native": "0.54",
"react-native-action-button": "^2.8.3", "react-native-action-button": "^2.8.3",
"react-native-actionsheet": "^2.3.0", "react-native-actionsheet": "^2.3.0",
"react-native-animatable": "^1.2.4", "react-native-animatable": "^1.2.4",
@ -45,12 +46,12 @@
"react-native-fetch-blob": "^0.10.8", "react-native-fetch-blob": "^0.10.8",
"react-native-image-picker": "^0.26.7", "react-native-image-picker": "^0.26.7",
"react-native-img-cache": "^1.5.2", "react-native-img-cache": "^1.5.2",
"react-native-keyboard-aware-scroll-view": "^0.4.1", "react-native-keyboard-aware-scroll-view": "^0.4.4",
"react-native-keyboard-input": "git+https://github.com/RocketChat/react-native-keyboard-input.git", "react-native-keyboard-input": "git+https://github.com/RocketChat/react-native-keyboard-input.git",
"react-native-keyboard-tracking-view": "git+https://github.com/RocketChat/react-native-keyboard-tracking-view.git", "react-native-keyboard-tracking-view": "git+https://github.com/RocketChat/react-native-keyboard-tracking-view.git",
"react-native-loading-spinner-overlay": "^0.5.2", "react-native-loading-spinner-overlay": "^0.5.2",
"react-native-meteor": "^1.2.0", "react-native-meteor": "^1.2.0",
"react-native-modal": "^4.1.1", "react-native-modal": "^5.1.1",
"react-native-optimized-flatlist": "^1.0.4", "react-native-optimized-flatlist": "^1.0.4",
"react-native-push-notification": "^3.0.1", "react-native-push-notification": "^3.0.1",
"react-native-responsive-ui": "^1.1.1", "react-native-responsive-ui": "^1.1.1",
@ -62,11 +63,11 @@
"react-native-svg-image": "^2.0.1", "react-native-svg-image": "^2.0.1",
"react-native-vector-icons": "^4.4.2", "react-native-vector-icons": "^4.4.2",
"react-native-video": "^2.0.0", "react-native-video": "^2.0.0",
"react-native-video-controls": "^2.0.0", "react-native-video-controls": "^2.1.0",
"react-native-zeroconf": "^0.8.3", "react-native-zeroconf": "^0.8.3",
"react-navigation": "^1.0.0-beta.19", "react-navigation": "^1.3.0",
"react-redux": "^5.0.6", "react-redux": "^5.0.6",
"realm": "^2.0.11", "realm": "^2.2.12",
"redux": "^3.7.2", "redux": "^3.7.2",
"redux-enhancer-react-native-appstate": "^0.3.0", "redux-enhancer-react-native-appstate": "^0.3.0",
"redux-immutable-state-invariant": "^2.1.0", "redux-immutable-state-invariant": "^2.1.0",

1163
yarn.lock

File diff suppressed because it is too large Load Diff