From 8f90565e55174189ca60c462f2960daa5f41aa0b Mon Sep 17 00:00:00 2001
From: Diego Mello <diegolmello@gmail.com>
Date: Thu, 24 May 2018 17:17:00 -0300
Subject: [PATCH] RoomsListView re-render (#304)

<!-- INSTRUCTION: Keep the line below to notify all core developers about this new PR -->
@RocketChat/ReactNative

<!-- INSTRUCTION: Inform the issue number that this PR closes, or remove the line below -->

<!-- INSTRUCTION: Tell us more about your PR with screen shots if you can -->
- [x] Removed unnecessary re-renders on RoomsListView
---
 app/ReactotronConfig.js                      |  4 +--
 app/lib/methods/helpers/protectedFunction.js |  8 +++--
 app/presentation/RoomItem.js                 |  7 ++--
 app/utils/log.js                             |  3 ++
 app/views/RoomsListView/index.js             | 36 ++++++++++++++------
 5 files changed, 41 insertions(+), 17 deletions(-)

diff --git a/app/ReactotronConfig.js b/app/ReactotronConfig.js
index a6d4b34f3..3630fe5d7 100644
--- a/app/ReactotronConfig.js
+++ b/app/ReactotronConfig.js
@@ -12,6 +12,6 @@ if (__DEV__) {
         .connect();
     // Running on android device
     // $ adb reverse tcp:9090 tcp:9090
-    // Reactotron.clear();
-    // console.warn = Reactotron.log;
+    Reactotron.clear();
+    console.warn = Reactotron.log;
 }
diff --git a/app/lib/methods/helpers/protectedFunction.js b/app/lib/methods/helpers/protectedFunction.js
index 820a65022..f6808531d 100644
--- a/app/lib/methods/helpers/protectedFunction.js
+++ b/app/lib/methods/helpers/protectedFunction.js
@@ -4,9 +4,13 @@ export default fn => (params) => {
 	try {
 		fn(params);
 	} catch (e) {
-		Answers.logCustom('error', e);
+		let error = e;
+		if (typeof error !== 'object') {
+			error = { error };
+		}
+		Answers.logCustom('error', error);
 		if (__DEV__) {
-			alert(e);
+			alert(error);
 		}
 	}
 };
diff --git a/app/presentation/RoomItem.js b/app/presentation/RoomItem.js
index 01ddac4a7..719d6d7a1 100644
--- a/app/presentation/RoomItem.js
+++ b/app/presentation/RoomItem.js
@@ -149,7 +149,7 @@ const renderNumber = (unread, userMentions) => {
 	);
 };
 
-const attrs = ['name', 'unread', 'userMentions', 'alert', 'showLastMessage', 'type', '_updatedAt'];
+const attrs = ['name', 'unread', 'userMentions', 'alert', 'showLastMessage', 'type'];
 @connect(state => ({
 	user: state.login && state.login.user,
 	StoreLastMessage: state.settings.Store_Last_Message
@@ -183,7 +183,10 @@ export default class RoomItem extends React.Component {
 		const oldlastMessage = this.props.lastMessage;
 		const newLastmessage = nextProps.lastMessage;
 
-		if (oldlastMessage && newLastmessage && oldlastMessage.ts !== newLastmessage.ts) {
+		if (oldlastMessage && newLastmessage && oldlastMessage.ts.toGMTString() !== newLastmessage.ts.toGMTString()) {
+			return true;
+		}
+		if (this.props._updatedAt && nextProps._updatedAt && nextProps._updatedAt.toGMTString() !== this.props._updatedAt.toGMTString()) {
 			return true;
 		}
 		return attrs.some(key => nextProps[key] !== this.props[key]);
diff --git a/app/utils/log.js b/app/utils/log.js
index 7bde33a48..e1c98aef8 100644
--- a/app/utils/log.js
+++ b/app/utils/log.js
@@ -1,6 +1,9 @@
 import { Answers } from 'react-native-fabric';
 
 export default (event, error) => {
+	if (typeof error !== 'object') {
+		error = { error };
+	}
 	Answers.logCustom(event, error);
 	if (__DEV__) {
 		console.warn(event, error);
diff --git a/app/views/RoomsListView/index.js b/app/views/RoomsListView/index.js
index b6be26fb2..d1c8726fc 100644
--- a/app/views/RoomsListView/index.js
+++ b/app/views/RoomsListView/index.js
@@ -8,11 +8,10 @@ import { connect } from 'react-redux';
 import database from '../../lib/realm';
 import RocketChat from '../../lib/rocketchat';
 import RoomItem from '../../presentation/RoomItem';
-import { goRoom } from '../../containers/routes/NavigationService';
 import Header from '../../containers/Header';
 import RoomsListHeader from './Header';
 import styles from './styles';
-import throttle from '../../utils/throttle';
+import debounce from '../../utils/debounce';
 import LoggedView from '../View';
 import log from '../../utils/log';
 
@@ -39,7 +38,8 @@ export default class RoomsListView extends LoggedView {
 		super('RoomsListView', props);
 
 		this.state = {
-			search: []
+			search: [],
+			rooms: []
 		};
 		this._keyExtractor = this._keyExtractor.bind(this);
 		this.data = database.objects('subscriptions').filtered('archived != true && open == true').sorted('roomUpdatedAt', true);
@@ -68,10 +68,10 @@ export default class RoomsListView extends LoggedView {
 		this.search(text);
 	}
 
-	updateState = throttle(() => {
+	updateState = debounce(() => {
 		LayoutAnimation.easeInEaseOut();
-		this.forceUpdate();
-	}, 1500);
+		this.setState({ rooms: this.data.slice() });
+	})
 
 	async search(text) {
 		const searchText = text.trim();
@@ -118,20 +118,33 @@ export default class RoomsListView extends LoggedView {
 		}
 	}
 
+	goRoom = (rid, name) => {
+		this.props.navigation.navigate({
+			key: `Room-${ rid }`,
+			routeName: 'Room',
+			params: { room: { rid, name }, rid, name }
+		});
+	}
+
 	_onPressItem = async(item = {}) => {
 		if (!item.search) {
-			return goRoom({ rid: item.rid, name: item.name });
+			const { rid, name } = item;
+			return this.goRoom(rid, name);
 		}
 		if (item.t === 'd') {
 			// if user is using the search we need first to join/create room
 			try {
-				const sub = await RocketChat.createDirectMessage(item.username);
-				return goRoom(sub);
+				const { username } = item;
+				const sub = await RocketChat.createDirectMessage(username);
+				const { rid } = sub;
+				return this.goRoom(rid, username);
 			} catch (e) {
 				log('RoomsListView._onPressItem', e);
 			}
+		} else {
+			const { rid, name } = item;
+			return this.goRoom(rid, name);
 		}
-		return goRoom(item);
 	}
 
 	createChannel() {
@@ -184,7 +197,8 @@ export default class RoomsListView extends LoggedView {
 
 	renderList = () => (
 		<FlatList
-			data={this.state.search.length > 0 ? this.state.search : this.data}
+			data={this.state.search.length > 0 ? this.state.search : this.state.rooms}
+			extraData={this.state.search.length > 0 ? this.state.search : this.state.rooms}
 			keyExtractor={this._keyExtractor}
 			style={styles.list}
 			renderItem={this.renderItem}
-- 
GitLab