From 4a7c5e8412803fbd78cc59a99d6bf816a8adee79 Mon Sep 17 00:00:00 2001 From: diegolmello Date: Wed, 3 Jul 2019 16:50:03 -0300 Subject: [PATCH 1/6] Regression: on press style feedback --- app/presentation/RoomItem/styles.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/presentation/RoomItem/styles.js b/app/presentation/RoomItem/styles.js index fba962e7ea5..be12021efca 100644 --- a/app/presentation/RoomItem/styles.js +++ b/app/presentation/RoomItem/styles.js @@ -9,7 +9,6 @@ export const ROW_HEIGHT = 75 * PixelRatio.getFontScale(); export default StyleSheet.create({ container: { - backgroundColor: COLOR_WHITE, flexDirection: 'row', alignItems: 'center', paddingLeft: 14, From fbc5daee0c86f307fcbcb4699e007f7e11c0ba95 Mon Sep 17 00:00:00 2001 From: diegolmello Date: Wed, 3 Jul 2019 16:57:23 -0300 Subject: [PATCH 2/6] Action button styles --- app/presentation/RoomItem/index.js | 10 +++++----- app/presentation/RoomItem/styles.js | 8 +++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/app/presentation/RoomItem/index.js b/app/presentation/RoomItem/index.js index b93c9f1d5b0..f483f8e127e 100644 --- a/app/presentation/RoomItem/index.js +++ b/app/presentation/RoomItem/index.js @@ -246,12 +246,12 @@ export default class RoomItem extends React.Component { > {isRead ? ( - + {I18n.t('Unread')} ) : ( - + {I18n.t('Read')} )} @@ -293,12 +293,12 @@ export default class RoomItem extends React.Component { {favorite ? ( - + {I18n.t('Unfavorite')} ) : ( - + {I18n.t('Favorite')} )} @@ -314,7 +314,7 @@ export default class RoomItem extends React.Component { onPress={this.handleHideButtonPress} > - + {I18n.t('Hide')} diff --git a/app/presentation/RoomItem/styles.js b/app/presentation/RoomItem/styles.js index be12021efca..b3f7cb159b3 100644 --- a/app/presentation/RoomItem/styles.js +++ b/app/presentation/RoomItem/styles.js @@ -95,10 +95,12 @@ export default StyleSheet.create({ marginRight: 10 }, actionText: { - color: 'white', - fontSize: 14, + color: COLOR_WHITE, + fontSize: 15, backgroundColor: 'transparent', - justifyContent: 'center' + justifyContent: 'center', + marginTop: 4, + ...sharedStyles.textSemibold }, actionButtonLeft: { flex: 1, From db9ac33f375d84fe9902af8524a5741580274136 Mon Sep 17 00:00:00 2001 From: diegolmello Date: Wed, 3 Jul 2019 18:17:04 -0300 Subject: [PATCH 3/6] Fix animations --- app/presentation/RoomItem/index.js | 107 +++++++++++++--------------- app/presentation/RoomItem/styles.js | 3 - app/views/RoomsListView/index.js | 18 ++++- 3 files changed, 63 insertions(+), 65 deletions(-) diff --git a/app/presentation/RoomItem/index.js b/app/presentation/RoomItem/index.js index f483f8e127e..8c28b0af1bc 100644 --- a/app/presentation/RoomItem/index.js +++ b/app/presentation/RoomItem/index.js @@ -1,9 +1,7 @@ import React from 'react'; import moment from 'moment'; import PropTypes from 'prop-types'; -import { - View, Text, Dimensions, Animated -} from 'react-native'; +import { View, Text, Animated } from 'react-native'; import { connect } from 'react-redux'; import { RectButton, PanGestureHandler, State } from 'react-native-gesture-handler'; @@ -18,9 +16,8 @@ import { CustomIcon } from '../../lib/Icons'; export { ROW_HEIGHT }; const OPTION_WIDTH = 80; -const SMALL_SWIPE = 80; -const ACTION_OFFSET = 220; -const attrs = ['name', 'unread', 'userMentions', 'showLastMessage', 'alert', 'type']; +const SMALL_SWIPE = 40; +const attrs = ['name', 'unread', 'userMentions', 'showLastMessage', 'alert', 'type', 'width']; @connect(state => ({ userId: state.login.user && state.login.user.id, username: state.login.user && state.login.user.username, @@ -45,6 +42,7 @@ export default class RoomItem extends React.Component { token: PropTypes.string, avatarSize: PropTypes.number, testID: PropTypes.string, + width: PropTypes.number, height: PropTypes.number, favorite: PropTypes.bool, isRead: PropTypes.bool, @@ -72,8 +70,7 @@ export default class RoomItem extends React.Component { dragX, rowOffSet, rowState: 0, // 0: closed, 1: right opened, -1: left opened - leftWidth: undefined, - rightOffset: undefined + rowWidth: undefined }; this._onGestureEvent = Animated.event( [{ nativeEvent: { translationX: dragX } }] @@ -82,65 +79,52 @@ export default class RoomItem extends React.Component { this.rowTranslation.addListener(({ value }) => { this._value = value; }); } - shouldComponentUpdate(nextProps) { - const { lastMessage, _updatedAt, isRead } = this.props; - const oldlastMessage = lastMessage; - const newLastmessage = nextProps.lastMessage; + // shouldComponentUpdate(nextProps) { + // const { lastMessage, _updatedAt, isRead } = this.props; + // const oldlastMessage = lastMessage; + // const newLastmessage = nextProps.lastMessage; - if (oldlastMessage && newLastmessage && oldlastMessage.ts !== newLastmessage.ts) { - return true; - } - if (_updatedAt && nextProps._updatedAt && nextProps._updatedAt !== _updatedAt) { - return true; - } - if (isRead !== nextProps.isRead) { - return true; - } - // eslint-disable-next-line react/destructuring-assignment - return attrs.some(key => nextProps[key] !== this.props[key]); - } + // if (oldlastMessage && newLastmessage && oldlastMessage.ts !== newLastmessage.ts) { + // return true; + // } + // if (_updatedAt && nextProps._updatedAt && nextProps._updatedAt !== _updatedAt) { + // return true; + // } + // if (isRead !== nextProps.isRead) { + // return true; + // } + // // eslint-disable-next-line react/destructuring-assignment + // return attrs.some(key => nextProps[key] !== this.props[key]); + // } componentWillUnmount() { this.rowTranslation.removeAllListeners(); } - close = () => { - this.swipeableRow.close(); - }; - _onHandlerStateChange = ({ nativeEvent }) => { if (nativeEvent.oldState === State.ACTIVE) { this._handleRelease(nativeEvent); } }; - _currentOffset = () => { - const { leftWidth = 0, rowState } = this.state; - const { rightOffset } = this.state; - if (rowState === 1) { - return leftWidth; - } else if (rowState === -1) { - return rightOffset; - } - return 0; - }; - _handleRelease = (nativeEvent) => { const { translationX } = nativeEvent; - const { rowState } = this.state; + const { rowState, rowWidth } = this.state; + // const { width } = this.props; + const halfScreen = rowWidth / 2; let toValue = 0; if (rowState === 0) { // if no option is opened - if (translationX > 0 && translationX < ACTION_OFFSET) { + if (translationX > 0 && translationX < halfScreen) { toValue = OPTION_WIDTH; // open left option if he swipe right but not enough to trigger action this.setState({ rowState: -1 }); - } else if (translationX > ACTION_OFFSET) { + } else if (translationX >= halfScreen) { toValue = 0; this.toggleRead(); - } else if (translationX < 0 && translationX > -ACTION_OFFSET) { + } else if (translationX < 0 && translationX > -halfScreen) { toValue = -2 * OPTION_WIDTH; // open right option if he swipe left this.setState({ rowState: 1 }); - } else if (translationX < -ACTION_OFFSET) { - toValue = 0; + } else if (translationX <= -halfScreen) { + toValue = -rowWidth; this.hideChannel(); } else { toValue = 0; @@ -151,7 +135,7 @@ export default class RoomItem extends React.Component { if (this._value < SMALL_SWIPE) { toValue = 0; this.setState({ rowState: 0 }); - } else if (this._value > ACTION_OFFSET) { + } else if (this._value > halfScreen) { toValue = 0; this.setState({ rowState: 0 }); this.toggleRead(); @@ -164,7 +148,7 @@ export default class RoomItem extends React.Component { if (this._value > -2 * SMALL_SWIPE) { toValue = 0; this.setState({ rowState: 0 }); - } else if (this._value < -ACTION_OFFSET) { + } else if (this._value < -halfScreen) { toValue = 0; this.setState({ rowState: 0 }); this.hideChannel(); @@ -181,7 +165,7 @@ export default class RoomItem extends React.Component { dragX.setValue(0); Animated.spring(rowOffSet, { toValue, - bounciness: 5 + bounciness: 0 }).start(); } @@ -221,16 +205,20 @@ export default class RoomItem extends React.Component { } } + _onRowLayout = ({ nativeEvent }) => { + this.setState({ rowWidth: nativeEvent.layout.width }); + }; + renderLeftActions = () => { - const { isRead } = this.props; - const { width } = Dimensions.get('window'); + const { isRead, width } = this.props; + const halfWidth = width / 2; const trans = this.rowTranslation.interpolate({ inputRange: [0, OPTION_WIDTH], outputRange: [-width, -width + OPTION_WIDTH] }); const iconTrans = this.rowTranslation.interpolate({ - inputRange: [0, OPTION_WIDTH, ACTION_OFFSET - 20, ACTION_OFFSET, width], + inputRange: [0, OPTION_WIDTH, halfWidth - 1, halfWidth, width], outputRange: [0, 0, -(OPTION_WIDTH + 10), 0, 0] }); return ( @@ -262,23 +250,24 @@ export default class RoomItem extends React.Component { }; renderRightActions = () => { - const { favorite } = this.props; - const { width } = Dimensions.get('window'); + const { favorite, width } = this.props; + const halfWidth = width / 2; const trans = this.rowTranslation.interpolate({ inputRange: [-OPTION_WIDTH, 0], outputRange: [width - OPTION_WIDTH, width] }); const iconHideTrans = this.rowTranslation.interpolate({ - inputRange: [-(ACTION_OFFSET - 20), -2 * OPTION_WIDTH, 0], + inputRange: [-(halfWidth - 20), -2 * OPTION_WIDTH, 0], outputRange: [0, 0, -OPTION_WIDTH] }); const iconFavWidth = this.rowTranslation.interpolate({ - inputRange: [-(ACTION_OFFSET + 1), -ACTION_OFFSET, -(ACTION_OFFSET - 20), -2 * OPTION_WIDTH, 0], - outputRange: [0, 0, OPTION_WIDTH + 20, OPTION_WIDTH, OPTION_WIDTH] + inputRange: [-halfWidth, -2 * OPTION_WIDTH, 0], + outputRange: [0, OPTION_WIDTH, OPTION_WIDTH], + extrapolate: 'clamp' }); const iconHideWidth = this.rowTranslation.interpolate({ - inputRange: [-(ACTION_OFFSET + 1), -ACTION_OFFSET, -(ACTION_OFFSET - 20), -2 * OPTION_WIDTH, 0], - outputRange: [(ACTION_OFFSET + 1), ACTION_OFFSET, OPTION_WIDTH + 20, OPTION_WIDTH, OPTION_WIDTH] + inputRange: [-width, -halfWidth, -2 * OPTION_WIDTH, 0], + outputRange: [width, halfWidth, OPTION_WIDTH, OPTION_WIDTH] }); return ( - + {this.renderLeftActions()} {this.renderRightActions()} BackHandler.addEventListener('hardwareBackPress', this.handleBackPress)); @@ -148,6 +150,7 @@ export default class RoomsListView extends React.Component { initSearchingAndroid: this.initSearchingAndroid, cancelSearchingAndroid: this.cancelSearchingAndroid }); + Dimensions.addEventListener('change', this.onDimensionsChange); console.timeEnd(`${ this.constructor.name } mount`); } @@ -172,7 +175,7 @@ export default class RoomsListView extends React.Component { return true; } - const { loading, searching } = this.state; + const { loading, searching, width } = this.state; if (nextState.loading !== loading) { return true; } @@ -180,6 +183,10 @@ export default class RoomsListView extends React.Component { return true; } + if (nextState.width !== width) { + return true; + } + const { search } = this.state; if (!isEqual(nextState.search, search)) { return true; @@ -220,9 +227,12 @@ export default class RoomsListView extends React.Component { if (this.willBlurListener && this.willBlurListener.remove) { this.willBlurListener.remove(); } + Dimensions.removeEventListener('change', this.onDimensionsChange); console.countReset(`${ this.constructor.name }.render calls`); } + onDimensionsChange = () => ({ window: { width } }) => this.setState({ width }); + // eslint-disable-next-line react/sort-comp internalSetState = (...args) => { const { navigation } = this.props; @@ -435,6 +445,7 @@ export default class RoomsListView extends React.Component { } renderItem = ({ item }) => { + const { width } = this.state; const { userId, baseUrl, StoreLastMessage } = this.props; @@ -460,6 +471,7 @@ export default class RoomsListView extends React.Component { showLastMessage={StoreLastMessage} onPress={() => this._onPressItem(item)} testID={`rooms-list-view-item-${ item.name }`} + width={width} height={ROW_HEIGHT} toggleFav={this.toggleFav} toggleRead={this.toggleRead} From 1dcef68b1b6793ef7b3989f7c542ac2d83bb3bfd Mon Sep 17 00:00:00 2001 From: diegolmello Date: Thu, 4 Jul 2019 09:27:07 -0300 Subject: [PATCH 4/6] Styles changed --- app/presentation/RoomItem/index.js | 72 +++++++++++++++++++---------- app/presentation/RoomItem/styles.js | 3 ++ app/views/RoomsListView/index.js | 18 ++------ 3 files changed, 54 insertions(+), 39 deletions(-) diff --git a/app/presentation/RoomItem/index.js b/app/presentation/RoomItem/index.js index 8c28b0af1bc..e2622c26624 100644 --- a/app/presentation/RoomItem/index.js +++ b/app/presentation/RoomItem/index.js @@ -1,7 +1,9 @@ import React from 'react'; import moment from 'moment'; import PropTypes from 'prop-types'; -import { View, Text, Animated } from 'react-native'; +import { + View, Text, Animated, Dimensions +} from 'react-native'; import { connect } from 'react-redux'; import { RectButton, PanGestureHandler, State } from 'react-native-gesture-handler'; @@ -17,6 +19,7 @@ export { ROW_HEIGHT }; const OPTION_WIDTH = 80; const SMALL_SWIPE = 40; +const TEMP_WIDTH = Dimensions.get('window').width; const attrs = ['name', 'unread', 'userMentions', 'showLastMessage', 'alert', 'type', 'width']; @connect(state => ({ userId: state.login.user && state.login.user.id, @@ -42,7 +45,6 @@ export default class RoomItem extends React.Component { token: PropTypes.string, avatarSize: PropTypes.number, testID: PropTypes.string, - width: PropTypes.number, height: PropTypes.number, favorite: PropTypes.bool, isRead: PropTypes.bool, @@ -79,23 +81,28 @@ export default class RoomItem extends React.Component { this.rowTranslation.addListener(({ value }) => { this._value = value; }); } - // shouldComponentUpdate(nextProps) { - // const { lastMessage, _updatedAt, isRead } = this.props; - // const oldlastMessage = lastMessage; - // const newLastmessage = nextProps.lastMessage; - - // if (oldlastMessage && newLastmessage && oldlastMessage.ts !== newLastmessage.ts) { - // return true; - // } - // if (_updatedAt && nextProps._updatedAt && nextProps._updatedAt !== _updatedAt) { - // return true; - // } - // if (isRead !== nextProps.isRead) { - // return true; - // } - // // eslint-disable-next-line react/destructuring-assignment - // return attrs.some(key => nextProps[key] !== this.props[key]); - // } + shouldComponentUpdate(nextProps, nextState) { + const { rowWidth } = this.state; + const { lastMessage, _updatedAt, isRead } = this.props; + const oldlastMessage = lastMessage; + const newLastmessage = nextProps.lastMessage; + + if (rowWidth !== nextState.rowWidth) { + return true; + } + + if (oldlastMessage && newLastmessage && oldlastMessage.ts !== newLastmessage.ts) { + return true; + } + if (_updatedAt && nextProps._updatedAt && nextProps._updatedAt !== _updatedAt) { + return true; + } + if (isRead !== nextProps.isRead) { + return true; + } + // eslint-disable-next-line react/destructuring-assignment + return attrs.some(key => nextProps[key] !== this.props[key]); + } componentWillUnmount() { this.rowTranslation.removeAllListeners(); @@ -110,7 +117,6 @@ export default class RoomItem extends React.Component { _handleRelease = (nativeEvent) => { const { translationX } = nativeEvent; const { rowState, rowWidth } = this.state; - // const { width } = this.props; const halfScreen = rowWidth / 2; let toValue = 0; if (rowState === 0) { // if no option is opened @@ -175,6 +181,7 @@ export default class RoomItem extends React.Component { } close = () => { + this.setState({ rowState: 0 }); this._animateRow(0); } @@ -209,8 +216,22 @@ export default class RoomItem extends React.Component { this.setState({ rowWidth: nativeEvent.layout.width }); }; + onPress = () => { + const { rowState } = this.state; + if (rowState !== 0) { + this.close(); + return; + } + const { onPress } = this.props; + if (onPress) { + onPress(); + } + } + renderLeftActions = () => { - const { isRead, width } = this.props; + const { rowWidth } = this.state; + const { isRead } = this.props; + const width = rowWidth || TEMP_WIDTH; const halfWidth = width / 2; const trans = this.rowTranslation.interpolate({ inputRange: [0, OPTION_WIDTH], @@ -250,7 +271,9 @@ export default class RoomItem extends React.Component { }; renderRightActions = () => { - const { favorite, width } = this.props; + const { rowWidth } = this.state; + const { favorite } = this.props; + const width = rowWidth || TEMP_WIDTH; const halfWidth = width / 2; const trans = this.rowTranslation.interpolate({ inputRange: [-OPTION_WIDTH, 0], @@ -321,7 +344,7 @@ export default class RoomItem extends React.Component { render() { const { - unread, userMentions, name, _updatedAt, alert, testID, height, type, avatarSize, baseUrl, userId, username, token, onPress, id, prid, showLastMessage, lastMessage + unread, userMentions, name, _updatedAt, alert, testID, height, type, avatarSize, baseUrl, userId, username, token, id, prid, showLastMessage, lastMessage } = this.props; const date = this.formatDate(_updatedAt); @@ -358,10 +381,11 @@ export default class RoomItem extends React.Component { } > BackHandler.addEventListener('hardwareBackPress', this.handleBackPress)); @@ -150,7 +148,6 @@ export default class RoomsListView extends React.Component { initSearchingAndroid: this.initSearchingAndroid, cancelSearchingAndroid: this.cancelSearchingAndroid }); - Dimensions.addEventListener('change', this.onDimensionsChange); console.timeEnd(`${ this.constructor.name } mount`); } @@ -175,7 +172,7 @@ export default class RoomsListView extends React.Component { return true; } - const { loading, searching, width } = this.state; + const { loading, searching } = this.state; if (nextState.loading !== loading) { return true; } @@ -183,10 +180,6 @@ export default class RoomsListView extends React.Component { return true; } - if (nextState.width !== width) { - return true; - } - const { search } = this.state; if (!isEqual(nextState.search, search)) { return true; @@ -227,12 +220,9 @@ export default class RoomsListView extends React.Component { if (this.willBlurListener && this.willBlurListener.remove) { this.willBlurListener.remove(); } - Dimensions.removeEventListener('change', this.onDimensionsChange); console.countReset(`${ this.constructor.name }.render calls`); } - onDimensionsChange = () => ({ window: { width } }) => this.setState({ width }); - // eslint-disable-next-line react/sort-comp internalSetState = (...args) => { const { navigation } = this.props; @@ -445,7 +435,6 @@ export default class RoomsListView extends React.Component { } renderItem = ({ item }) => { - const { width } = this.state; const { userId, baseUrl, StoreLastMessage } = this.props; @@ -471,7 +460,6 @@ export default class RoomsListView extends React.Component { showLastMessage={StoreLastMessage} onPress={() => this._onPressItem(item)} testID={`rooms-list-view-item-${ item.name }`} - width={width} height={ROW_HEIGHT} toggleFav={this.toggleFav} toggleRead={this.toggleRead} From 6c7032df80be21cdf5a1a030c842875ddea071f4 Mon Sep 17 00:00:00 2001 From: diegolmello Date: Thu, 4 Jul 2019 09:43:50 -0300 Subject: [PATCH 5/6] Update subscription without having to wait for socket --- app/presentation/RoomItem/index.js | 2 +- app/presentation/RoomItem/styles.js | 3 +++ app/views/RoomsListView/index.js | 18 ++++++++++++++++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/app/presentation/RoomItem/index.js b/app/presentation/RoomItem/index.js index e2622c26624..9ac76e09cc0 100644 --- a/app/presentation/RoomItem/index.js +++ b/app/presentation/RoomItem/index.js @@ -370,7 +370,7 @@ export default class RoomItem extends React.Component { onGestureEvent={this._onGestureEvent} onHandlerStateChange={this._onHandlerStateChange} > - + {this.renderLeftActions()} {this.renderRightActions()} { try { - await RocketChat.toggleRead(isRead, rid); + const result = await RocketChat.toggleRead(isRead, rid); + if (result.success) { + database.write(() => { + const sub = database.objects('subscriptions').filtered('rid == $0', rid)[0]; + if (sub) { + sub.alert = isRead; + } + }); + } } catch (e) { log('error_toggle_read', e); } @@ -401,7 +409,13 @@ export default class RoomsListView extends React.Component { hideChannel = async(rid, type) => { try { - await RocketChat.hideRoom(rid, type); + const result = await RocketChat.hideRoom(rid, type); + if (result.success) { + database.write(() => { + const sub = database.objects('subscriptions').filtered('rid == $0', rid)[0]; + database.delete(sub); + }); + } } catch (e) { log('error_hide_channel', e); } From 0f3f217ef113ee4ffd31e316dfa2ef847eabe4c7 Mon Sep 17 00:00:00 2001 From: diegolmello Date: Thu, 4 Jul 2019 10:38:44 -0300 Subject: [PATCH 6/6] Calculate width on RoomsListView instead --- app/presentation/RoomItem/index.js | 39 +++++++++--------------------- app/views/RoomsListView/index.js | 18 +++++++++++--- storybook/stories/RoomItem.js | 4 ++- 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/app/presentation/RoomItem/index.js b/app/presentation/RoomItem/index.js index 9ac76e09cc0..b9e2639b91c 100644 --- a/app/presentation/RoomItem/index.js +++ b/app/presentation/RoomItem/index.js @@ -1,9 +1,7 @@ import React from 'react'; import moment from 'moment'; import PropTypes from 'prop-types'; -import { - View, Text, Animated, Dimensions -} from 'react-native'; +import { View, Text, Animated } from 'react-native'; import { connect } from 'react-redux'; import { RectButton, PanGestureHandler, State } from 'react-native-gesture-handler'; @@ -19,7 +17,6 @@ export { ROW_HEIGHT }; const OPTION_WIDTH = 80; const SMALL_SWIPE = 40; -const TEMP_WIDTH = Dimensions.get('window').width; const attrs = ['name', 'unread', 'userMentions', 'showLastMessage', 'alert', 'type', 'width']; @connect(state => ({ userId: state.login.user && state.login.user.id, @@ -45,6 +42,7 @@ export default class RoomItem extends React.Component { token: PropTypes.string, avatarSize: PropTypes.number, testID: PropTypes.string, + width: PropTypes.number, height: PropTypes.number, favorite: PropTypes.bool, isRead: PropTypes.bool, @@ -71,8 +69,7 @@ export default class RoomItem extends React.Component { this.state = { dragX, rowOffSet, - rowState: 0, // 0: closed, 1: right opened, -1: left opened - rowWidth: undefined + rowState: 0 // 0: closed, 1: right opened, -1: left opened }; this._onGestureEvent = Animated.event( [{ nativeEvent: { translationX: dragX } }] @@ -81,16 +78,11 @@ export default class RoomItem extends React.Component { this.rowTranslation.addListener(({ value }) => { this._value = value; }); } - shouldComponentUpdate(nextProps, nextState) { - const { rowWidth } = this.state; + shouldComponentUpdate(nextProps) { const { lastMessage, _updatedAt, isRead } = this.props; const oldlastMessage = lastMessage; const newLastmessage = nextProps.lastMessage; - if (rowWidth !== nextState.rowWidth) { - return true; - } - if (oldlastMessage && newLastmessage && oldlastMessage.ts !== newLastmessage.ts) { return true; } @@ -116,8 +108,9 @@ export default class RoomItem extends React.Component { _handleRelease = (nativeEvent) => { const { translationX } = nativeEvent; - const { rowState, rowWidth } = this.state; - const halfScreen = rowWidth / 2; + const { rowState } = this.state; + const { width } = this.props; + const halfScreen = width / 2; let toValue = 0; if (rowState === 0) { // if no option is opened if (translationX > 0 && translationX < halfScreen) { @@ -130,7 +123,7 @@ export default class RoomItem extends React.Component { toValue = -2 * OPTION_WIDTH; // open right option if he swipe left this.setState({ rowState: 1 }); } else if (translationX <= -halfScreen) { - toValue = -rowWidth; + toValue = -width; this.hideChannel(); } else { toValue = 0; @@ -212,10 +205,6 @@ export default class RoomItem extends React.Component { } } - _onRowLayout = ({ nativeEvent }) => { - this.setState({ rowWidth: nativeEvent.layout.width }); - }; - onPress = () => { const { rowState } = this.state; if (rowState !== 0) { @@ -229,9 +218,7 @@ export default class RoomItem extends React.Component { } renderLeftActions = () => { - const { rowWidth } = this.state; - const { isRead } = this.props; - const width = rowWidth || TEMP_WIDTH; + const { isRead, width } = this.props; const halfWidth = width / 2; const trans = this.rowTranslation.interpolate({ inputRange: [0, OPTION_WIDTH], @@ -271,9 +258,7 @@ export default class RoomItem extends React.Component { }; renderRightActions = () => { - const { rowWidth } = this.state; - const { favorite } = this.props; - const width = rowWidth || TEMP_WIDTH; + const { favorite, width } = this.props; const halfWidth = width / 2; const trans = this.rowTranslation.interpolate({ inputRange: [-OPTION_WIDTH, 0], @@ -370,7 +355,7 @@ export default class RoomItem extends React.Component { onGestureEvent={this._onGestureEvent} onHandlerStateChange={this._onHandlerStateChange} > - + {this.renderLeftActions()} {this.renderRightActions()} - + ); } diff --git a/app/views/RoomsListView/index.js b/app/views/RoomsListView/index.js index 18017c41049..fbb9c169ba4 100644 --- a/app/views/RoomsListView/index.js +++ b/app/views/RoomsListView/index.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { - View, FlatList, BackHandler, ActivityIndicator, Text, ScrollView, Keyboard, LayoutAnimation, InteractionManager + View, FlatList, BackHandler, ActivityIndicator, Text, ScrollView, Keyboard, LayoutAnimation, InteractionManager, Dimensions } from 'react-native'; import { connect } from 'react-redux'; import { isEqual } from 'lodash'; @@ -121,6 +121,7 @@ export default class RoomsListView extends React.Component { console.time(`${ this.constructor.name } init`); console.time(`${ this.constructor.name } mount`); + const { width } = Dimensions.get('window'); this.data = []; this.state = { searching: false, @@ -133,7 +134,8 @@ export default class RoomsListView extends React.Component { channels: [], privateGroup: [], direct: [], - livechat: [] + livechat: [], + width }; Orientation.unlockAllOrientations(); this.didFocusListener = props.navigation.addListener('didFocus', () => BackHandler.addEventListener('hardwareBackPress', this.handleBackPress)); @@ -148,6 +150,7 @@ export default class RoomsListView extends React.Component { initSearchingAndroid: this.initSearchingAndroid, cancelSearchingAndroid: this.cancelSearchingAndroid }); + Dimensions.addEventListener('change', this.onDimensionsChange); console.timeEnd(`${ this.constructor.name } mount`); } @@ -172,7 +175,7 @@ export default class RoomsListView extends React.Component { return true; } - const { loading, searching } = this.state; + const { loading, searching, width } = this.state; if (nextState.loading !== loading) { return true; } @@ -180,6 +183,10 @@ export default class RoomsListView extends React.Component { return true; } + if (nextState.width !== width) { + return true; + } + const { search } = this.state; if (!isEqual(nextState.search, search)) { return true; @@ -220,9 +227,12 @@ export default class RoomsListView extends React.Component { if (this.willBlurListener && this.willBlurListener.remove) { this.willBlurListener.remove(); } + Dimensions.removeEventListener('change', this.onDimensionsChange); console.countReset(`${ this.constructor.name }.render calls`); } + onDimensionsChange = ({ window: { width } }) => this.setState({ width }) + // eslint-disable-next-line react/sort-comp internalSetState = (...args) => { const { navigation } = this.props; @@ -449,6 +459,7 @@ export default class RoomsListView extends React.Component { } renderItem = ({ item }) => { + const { width } = this.state; const { userId, baseUrl, StoreLastMessage } = this.props; @@ -474,6 +485,7 @@ export default class RoomsListView extends React.Component { showLastMessage={StoreLastMessage} onPress={() => this._onPressItem(item)} testID={`rooms-list-view-item-${ item.name }`} + width={width} height={ROW_HEIGHT} toggleFav={this.toggleFav} toggleRead={this.toggleRead} diff --git a/storybook/stories/RoomItem.js b/storybook/stories/RoomItem.js index 48fddcb19b6..dd22e393eb3 100644 --- a/storybook/stories/RoomItem.js +++ b/storybook/stories/RoomItem.js @@ -1,5 +1,5 @@ import React from 'react'; -import { ScrollView } from 'react-native'; +import { ScrollView, Dimensions } from 'react-native'; // import moment from 'moment'; import RoomItemComponent from '../../app/presentation/RoomItem'; @@ -7,6 +7,7 @@ import StoriesSeparator from './StoriesSeparator'; const date = '2017-10-10T10:00:00Z'; const baseUrl = 'https://open.rocket.chat'; +const { width } = Dimensions.get('window'); const RoomItem = props => ( ( name='rocket.cat' _updatedAt={date} baseUrl={baseUrl} + width={width} {...props} /> );