From 75e4b86a951c90209c7d858dee72e696f7b3db53 Mon Sep 17 00:00:00 2001
From: Diego Mello <diegolmello@gmail.com>
Date: Fri, 26 Apr 2019 18:15:25 -0300
Subject: [PATCH] Fetch roles from rest api (#853)

* Fetch roles from rest api

* Fix RoomInfoView role get

* Remove roles from redux
---
 app/actions/actionsTypes.js     |  1 -
 app/actions/roles.js            |  8 --------
 app/lib/methods/getRoles.js     | 31 ++++++++++++++++++++++++++++++
 app/lib/rocketchat.js           | 34 ++++-----------------------------
 app/reducers/index.js           |  2 --
 app/reducers/roles.js           | 15 ---------------
 app/sagas/selectServer.js       |  6 ------
 app/views/RoomInfoView/index.js | 17 +++++++++++------
 8 files changed, 46 insertions(+), 68 deletions(-)
 delete mode 100644 app/actions/roles.js
 create mode 100644 app/lib/methods/getRoles.js
 delete mode 100644 app/reducers/roles.js

diff --git a/app/actions/actionsTypes.js b/app/actions/actionsTypes.js
index cd0a7ad1f..776a58e98 100644
--- a/app/actions/actionsTypes.js
+++ b/app/actions/actionsTypes.js
@@ -65,7 +65,6 @@ export const SERVER = createRequestTypes('SERVER', [
 export const METEOR = createRequestTypes('METEOR_CONNECT', [...defaultTypes, 'DISCONNECT']);
 export const LOGOUT = 'LOGOUT'; // logout is always success
 export const ACTIVE_USERS = createRequestTypes('ACTIVE_USERS', ['SET']);
-export const ROLES = createRequestTypes('ROLES', ['SET']);
 export const SNIPPETED_MESSAGES = createRequestTypes('SNIPPETED_MESSAGES', ['OPEN', 'READY', 'CLOSE', 'MESSAGES_RECEIVED']);
 export const DEEP_LINKING = createRequestTypes('DEEP_LINKING', ['OPEN']);
 export const SORT_PREFERENCES = createRequestTypes('SORT_PREFERENCES', ['SET_ALL', 'SET']);
diff --git a/app/actions/roles.js b/app/actions/roles.js
deleted file mode 100644
index 074111985..000000000
--- a/app/actions/roles.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import * as types from './actionsTypes';
-
-export function setRoles(data) {
-	return {
-		type: types.ROLES.SET,
-		data
-	};
-}
diff --git a/app/lib/methods/getRoles.js b/app/lib/methods/getRoles.js
new file mode 100644
index 000000000..c5ba86c13
--- /dev/null
+++ b/app/lib/methods/getRoles.js
@@ -0,0 +1,31 @@
+import { InteractionManager } from 'react-native';
+
+import database from '../realm';
+import log from '../../utils/log';
+
+export default async function() {
+	try {
+		// RC 0.70.0
+		const result = await this.sdk.get('roles.list');
+
+		if (!result.success) {
+			return;
+		}
+
+		const { roles } = result;
+
+		if (roles && roles.length) {
+			InteractionManager.runAfterInteractions(() => {
+				database.write(() => roles.forEach((role) => {
+					try {
+						database.create('roles', role, true);
+					} catch (e) {
+						log('getRoles create', e);
+					}
+				}));
+			});
+		}
+	} catch (e) {
+		log('getRoles', e);
+	}
+}
diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js
index 27dbc8e9f..f45fb5996 100644
--- a/app/lib/rocketchat.js
+++ b/app/lib/rocketchat.js
@@ -1,5 +1,4 @@
 import { AsyncStorage, InteractionManager } from 'react-native';
-import foreach from 'lodash/forEach';
 import semver from 'semver';
 import { Rocketchat as RocketchatClient } from '@rocket.chat/sdk';
 
@@ -16,7 +15,6 @@ import {
 } from '../actions/login';
 import { disconnect, connectSuccess, connectRequest } from '../actions/connect';
 import { setActiveUser } from '../actions/activeUsers';
-import { setRoles } from '../actions/roles';
 
 import subscribeRooms from './methods/subscriptions/rooms';
 import subscribeRoom from './methods/subscriptions/room';
@@ -28,6 +26,7 @@ import getSettings from './methods/getSettings';
 import getRooms from './methods/getRooms';
 import getPermissions from './methods/getPermissions';
 import getCustomEmoji from './methods/getCustomEmojis';
+import getRoles from './methods/getRoles';
 import canOpenRoom from './methods/canOpenRoom';
 
 import loadMessagesForRoom from './methods/loadMessagesForRoom';
@@ -43,7 +42,7 @@ import { roomsRequest } from '../actions/rooms';
 const TOKEN_KEY = 'reactnativemeteor_usertoken';
 const SORT_PREFS_KEY = 'RC_SORT_PREFS_KEY';
 const returnAnArray = obj => obj || [];
-const MIN_ROCKETCHAT_VERSION = '0.66.0';
+const MIN_ROCKETCHAT_VERSION = '0.70.0';
 
 const RocketChat = {
 	TOKEN_KEY,
@@ -144,9 +143,9 @@ const RocketChat = {
 		}
 		this.roomsSub = await this.subscribeRooms();
 
-		this.sdk.subscribe('roles');
 		this.getPermissions();
 		this.getCustomEmoji();
+		this.getRoles();
 		this.registerPushToken().catch(e => console.log(e));
 
 		if (this.activeUsersSubTimeout) {
@@ -200,32 +199,6 @@ const RocketChat = {
 		});
 
 		this.sdk.onStreamData('users', protectedFunction(ddpMessage => RocketChat._setUser(ddpMessage)));
-
-		this.sdk.onStreamData('rocketchat_roles', protectedFunction((ddpMessage) => {
-			this.roles = this.roles || {};
-
-			if (this.roleTimer) {
-				clearTimeout(this.roleTimer);
-				this.roleTimer = null;
-			}
-			this.roleTimer = setTimeout(() => {
-				reduxStore.dispatch(setRoles(this.roles));
-
-				database.write(() => {
-					foreach(this.roles, (description, _id) => {
-						try {
-							database.create('roles', { _id, description }, true);
-						} catch (e) {
-							log('create roles', e);
-						}
-					});
-				});
-
-				this.roleTimer = null;
-				return this.roles = {};
-			}, 1000);
-			this.roles[ddpMessage.id] = (ddpMessage.fields && ddpMessage.fields.description) || undefined;
-		}));
 	},
 
 	register(credentials) {
@@ -467,6 +440,7 @@ const RocketChat = {
 	getSettings,
 	getPermissions,
 	getCustomEmoji,
+	getRoles,
 	parseSettings: settings => settings.reduce((ret, item) => {
 		ret[item._id] = item[defaultSettings[item._id].type];
 		return ret;
diff --git a/app/reducers/index.js b/app/reducers/index.js
index 6b5efb5f3..44b209428 100644
--- a/app/reducers/index.js
+++ b/app/reducers/index.js
@@ -10,7 +10,6 @@ import createChannel from './createChannel';
 import app from './app';
 import customEmojis from './customEmojis';
 import activeUsers from './activeUsers';
-import roles from './roles';
 import sortPreferences from './sortPreferences';
 
 export default combineReducers({
@@ -25,6 +24,5 @@ export default combineReducers({
 	rooms,
 	customEmojis,
 	activeUsers,
-	roles,
 	sortPreferences
 });
diff --git a/app/reducers/roles.js b/app/reducers/roles.js
deleted file mode 100644
index f0e964e6c..000000000
--- a/app/reducers/roles.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import * as types from '../actions/actionsTypes';
-
-const initialState = {};
-
-export default (state = initialState, action) => {
-	switch (action.type) {
-		case types.ROLES.SET:
-			return {
-				...state,
-				...action.data
-			};
-		default:
-			return state;
-	}
-};
diff --git a/app/sagas/selectServer.js b/app/sagas/selectServer.js
index 9e72462a2..7f19cad2b 100644
--- a/app/sagas/selectServer.js
+++ b/app/sagas/selectServer.js
@@ -5,7 +5,6 @@ import Navigation from '../lib/Navigation';
 import { SERVER } from '../actions/actionsTypes';
 import * as actions from '../actions';
 import { serverFailure, selectServerRequest, selectServerSuccess } from '../actions/server';
-import { setRoles } from '../actions/roles';
 import { setUser } from '../actions/login';
 import RocketChat from '../lib/rocketchat';
 import database from '../lib/realm';
@@ -54,11 +53,6 @@ const handleSelectServer = function* handleSelectServer({ server, version, fetch
 		yield put(actions.setAllSettings(RocketChat.parseSettings(settings.slice(0, settings.length))));
 		const emojis = database.objects('customEmojis');
 		yield put(actions.setCustomEmojis(RocketChat.parseEmojis(emojis.slice(0, emojis.length))));
-		const roles = database.objects('roles');
-		yield put(setRoles(roles.reduce((result, role) => {
-			result[role._id] = role.description;
-			return result;
-		}, {})));
 
 		yield put(selectServerSuccess(server, fetchVersion ? serverInfo && serverInfo.version : version));
 	} catch (e) {
diff --git a/app/views/RoomInfoView/index.js b/app/views/RoomInfoView/index.js
index 0ed9f148a..d0b8e0f02 100644
--- a/app/views/RoomInfoView/index.js
+++ b/app/views/RoomInfoView/index.js
@@ -39,8 +39,7 @@ const getRoomTitle = room => (room.t === 'd'
 		token: state.login.user && state.login.user.token
 	},
 	activeUsers: state.activeUsers, // TODO: remove it
-	Message_TimeFormat: state.settings.Message_TimeFormat,
-	allRoles: state.roles
+	Message_TimeFormat: state.settings.Message_TimeFormat
 }))
 /** @extends React.Component */
 export default class RoomInfoView extends LoggedView {
@@ -67,8 +66,7 @@ export default class RoomInfoView extends LoggedView {
 		}),
 		baseUrl: PropTypes.string,
 		activeUsers: PropTypes.object,
-		Message_TimeFormat: PropTypes.string,
-		allRoles: PropTypes.object
+		Message_TimeFormat: PropTypes.string
 	}
 
 	constructor(props) {
@@ -161,6 +159,14 @@ export default class RoomInfoView extends LoggedView {
 		}
 	}
 
+	getRoleDescription = (id) => {
+		const role = database.objectForPrimaryKey('roles', id);
+		if (role) {
+			return role.description;
+		}
+		return null;
+	}
+
 	isDirect = () => {
 		const { room: { t } } = this.state;
 		return t === 'd';
@@ -185,7 +191,6 @@ export default class RoomInfoView extends LoggedView {
 
 	renderRoles = () => {
 		const { roles } = this.state;
-		const { allRoles } = this.props;
 
 		return (
 			roles.length > 0
@@ -195,7 +200,7 @@ export default class RoomInfoView extends LoggedView {
 						<View style={styles.rolesContainer}>
 							{roles.map(role => (
 								<View style={styles.roleBadge} key={role}>
-									<Text style={styles.role}>{ allRoles[role] }</Text>
+									<Text style={styles.role}>{ this.getRoleDescription(role) }</Text>
 								</View>
 							))}
 						</View>
-- 
GitLab