From ad375860650eef87ef512e010325e3a33a9c7f63 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Wed, 12 Dec 2018 13:15:10 -0200 Subject: [PATCH] Use Rest API pt 2 (#568) * Room files * Pinned messages * Starred messages * Mentioned messages * Search messages * Bug fixes * Profile * Livechat * Block/unblock user * Erase room * Archive room * Remove unused method * Bug fix --- app/actions/actionsTypes.js | 4 - app/actions/mentionedMessages.js | 29 ---- app/actions/pinnedMessages.js | 36 ----- app/actions/roomFiles.js | 28 ---- app/actions/starredMessages.js | 35 ----- app/containers/message/Message.js | 10 +- app/containers/message/User.js | 5 +- app/i18n/locales/en.js | 2 + app/i18n/locales/pt-BR.js | 2 + app/lib/methods/loadMessagesForRoom.js | 13 ++ app/lib/rocketchat.js | 168 +++++------------------ app/reducers/index.js | 8 -- app/reducers/mentionedMessages.js | 30 ---- app/reducers/pinnedMessages.js | 37 ----- app/reducers/roomFiles.js | 30 ---- app/reducers/starredMessages.js | 37 ----- app/sagas/index.js | 8 -- app/sagas/login.js | 3 +- app/sagas/mentionedMessages.js | 41 ------ app/sagas/pinnedMessages.js | 41 ------ app/sagas/roomFiles.js | 43 ------ app/sagas/rooms.js | 30 ++-- app/sagas/starredMessages.js | 41 ------ app/views/MentionedMessagesView/index.js | 103 +++++++------- app/views/PinnedMessagesView/index.js | 116 ++++++++-------- app/views/ProfileView/index.js | 168 ++++++++++++----------- app/views/RoomActionsView/index.js | 21 ++- app/views/RoomFilesView/index.js | 113 ++++++++------- app/views/RoomInfoEditView/index.js | 10 +- app/views/RoomMembersView/index.js | 9 +- app/views/RoomView/index.js | 32 +++-- app/views/RoomView/styles.js | 7 +- app/views/SearchMessagesView/index.js | 141 +++++++++---------- app/views/SearchMessagesView/styles.js | 4 +- app/views/SnippetedMessagesView/index.js | 2 +- app/views/StarredMessagesView/index.js | 122 ++++++++-------- 36 files changed, 531 insertions(+), 998 deletions(-) delete mode 100644 app/actions/mentionedMessages.js delete mode 100644 app/actions/pinnedMessages.js delete mode 100644 app/actions/roomFiles.js delete mode 100644 app/actions/starredMessages.js delete mode 100644 app/reducers/mentionedMessages.js delete mode 100644 app/reducers/pinnedMessages.js delete mode 100644 app/reducers/roomFiles.js delete mode 100644 app/reducers/starredMessages.js delete mode 100644 app/sagas/mentionedMessages.js delete mode 100644 app/sagas/pinnedMessages.js delete mode 100644 app/sagas/roomFiles.js delete mode 100644 app/sagas/starredMessages.js diff --git a/app/actions/actionsTypes.js b/app/actions/actionsTypes.js index 5238b533..89b84a24 100644 --- a/app/actions/actionsTypes.js +++ b/app/actions/actionsTypes.js @@ -77,10 +77,6 @@ export const METEOR = createRequestTypes('METEOR_CONNECT', [...defaultTypes, 'DI export const LOGOUT = 'LOGOUT'; // logout is always success export const ACTIVE_USERS = createRequestTypes('ACTIVE_USERS', ['SET']); export const ROLES = createRequestTypes('ROLES', ['SET']); -export const STARRED_MESSAGES = createRequestTypes('STARRED_MESSAGES', ['OPEN', 'READY', 'CLOSE', 'MESSAGES_RECEIVED', 'MESSAGE_UNSTARRED']); -export const PINNED_MESSAGES = createRequestTypes('PINNED_MESSAGES', ['OPEN', 'READY', 'CLOSE', 'MESSAGES_RECEIVED', 'MESSAGE_UNPINNED']); -export const MENTIONED_MESSAGES = createRequestTypes('MENTIONED_MESSAGES', ['OPEN', 'READY', 'CLOSE', 'MESSAGES_RECEIVED']); export const SNIPPETED_MESSAGES = createRequestTypes('SNIPPETED_MESSAGES', ['OPEN', 'READY', 'CLOSE', 'MESSAGES_RECEIVED']); -export const ROOM_FILES = createRequestTypes('ROOM_FILES', ['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/mentionedMessages.js b/app/actions/mentionedMessages.js deleted file mode 100644 index e4d9e3be..00000000 --- a/app/actions/mentionedMessages.js +++ /dev/null @@ -1,29 +0,0 @@ -import * as types from './actionsTypes'; - -export function openMentionedMessages(rid, limit) { - return { - type: types.MENTIONED_MESSAGES.OPEN, - rid, - limit - }; -} - -export function readyMentionedMessages() { - return { - type: types.MENTIONED_MESSAGES.READY - }; -} - - -export function closeMentionedMessages() { - return { - type: types.MENTIONED_MESSAGES.CLOSE - }; -} - -export function mentionedMessagesReceived(messages) { - return { - type: types.MENTIONED_MESSAGES.MESSAGES_RECEIVED, - messages - }; -} diff --git a/app/actions/pinnedMessages.js b/app/actions/pinnedMessages.js deleted file mode 100644 index 40601003..00000000 --- a/app/actions/pinnedMessages.js +++ /dev/null @@ -1,36 +0,0 @@ -import * as types from './actionsTypes'; - -export function openPinnedMessages(rid, limit) { - return { - type: types.PINNED_MESSAGES.OPEN, - rid, - limit - }; -} - -export function readyPinnedMessages() { - return { - type: types.PINNED_MESSAGES.READY - }; -} - - -export function closePinnedMessages() { - return { - type: types.PINNED_MESSAGES.CLOSE - }; -} - -export function pinnedMessagesReceived(messages) { - return { - type: types.PINNED_MESSAGES.MESSAGES_RECEIVED, - messages - }; -} - -export function pinnedMessageUnpinned(messageId) { - return { - type: types.PINNED_MESSAGES.MESSAGE_UNPINNED, - messageId - }; -} diff --git a/app/actions/roomFiles.js b/app/actions/roomFiles.js deleted file mode 100644 index 906912a5..00000000 --- a/app/actions/roomFiles.js +++ /dev/null @@ -1,28 +0,0 @@ -import * as types from './actionsTypes'; - -export function openRoomFiles(rid, limit) { - return { - type: types.ROOM_FILES.OPEN, - rid, - limit - }; -} - -export function readyRoomFiles() { - return { - type: types.ROOM_FILES.READY - }; -} - -export function closeRoomFiles() { - return { - type: types.ROOM_FILES.CLOSE - }; -} - -export function roomFilesReceived(messages) { - return { - type: types.ROOM_FILES.MESSAGES_RECEIVED, - messages - }; -} diff --git a/app/actions/starredMessages.js b/app/actions/starredMessages.js deleted file mode 100644 index a8f82faf..00000000 --- a/app/actions/starredMessages.js +++ /dev/null @@ -1,35 +0,0 @@ -import * as types from './actionsTypes'; - -export function openStarredMessages(rid, limit) { - return { - type: types.STARRED_MESSAGES.OPEN, - rid, - limit - }; -} - -export function readyStarredMessages() { - return { - type: types.STARRED_MESSAGES.READY - }; -} - -export function closeStarredMessages() { - return { - type: types.STARRED_MESSAGES.CLOSE - }; -} - -export function starredMessagesReceived(messages) { - return { - type: types.STARRED_MESSAGES.MESSAGES_RECEIVED, - messages - }; -} - -export function starredMessageUnstarred(messageId) { - return { - type: types.STARRED_MESSAGES.MESSAGE_UNSTARRED, - messageId - }; -} diff --git a/app/containers/message/Message.js b/app/containers/message/Message.js index b2f32dc0..6657ae77 100644 --- a/app/containers/message/Message.js +++ b/app/containers/message/Message.js @@ -39,7 +39,8 @@ const SYSTEM_MESSAGES = [ 'room_changed_description', 'room_changed_announcement', 'room_changed_topic', - 'room_changed_privacy' + 'room_changed_privacy', + 'message_snippeted' ]; const getInfoMessage = ({ @@ -76,6 +77,8 @@ const getInfoMessage = ({ return I18n.t('Room_changed_topic', { topic: msg, userBy: username }); } else if (type === 'room_changed_privacy') { return I18n.t('Room_changed_privacy', { type: msg, userBy: username }); + } else if (type === 'message_snippeted') { + return I18n.t('Created_snippet'); } return ''; }; @@ -107,7 +110,10 @@ export default class Message extends PureComponent { header: PropTypes.bool, avatar: PropTypes.string, alias: PropTypes.string, - ts: PropTypes.instanceOf(Date), + ts: PropTypes.oneOfType([ + PropTypes.instanceOf(Date), + PropTypes.string + ]), edited: PropTypes.bool, attachments: PropTypes.oneOfType([ PropTypes.array, diff --git a/app/containers/message/User.js b/app/containers/message/User.js index c3d4b3dd..6f2d5bf4 100644 --- a/app/containers/message/User.js +++ b/app/containers/message/User.js @@ -35,7 +35,10 @@ export default class User extends React.PureComponent { timeFormat: PropTypes.string.isRequired, username: PropTypes.string, alias: PropTypes.string, - ts: PropTypes.instanceOf(Date), + ts: PropTypes.oneOfType([ + PropTypes.instanceOf(Date), + PropTypes.string + ]), temp: PropTypes.bool } diff --git a/app/i18n/locales/en.js b/app/i18n/locales/en.js index 425cacae..8e3487be 100644 --- a/app/i18n/locales/en.js +++ b/app/i18n/locales/en.js @@ -131,6 +131,7 @@ export default { Copy_Permalink: 'Copy Permalink', Create_account: 'Create an account', Create_Channel: 'Create Channel', + Created_snippet: 'Created a snippet', Create_a_new_workspace: 'Create a new workspace', Create: 'Create', Delete_Room_Warning: 'Deleting a room will delete all messages posted within the room. This cannot be undone.', @@ -209,6 +210,7 @@ export default { No_files: 'No files', No_mentioned_messages: 'No mentioned messages', No_pinned_messages: 'No pinned messages', + No_results_found: 'No results found', No_snippeted_messages: 'No snippeted messages', No_starred_messages: 'No starred messages', No_announcement_provided: 'No announcement provided.', diff --git a/app/i18n/locales/pt-BR.js b/app/i18n/locales/pt-BR.js index 76d51ae2..f7e49cf8 100644 --- a/app/i18n/locales/pt-BR.js +++ b/app/i18n/locales/pt-BR.js @@ -138,6 +138,7 @@ export default { Copy_Permalink: 'Copiar Link-Permanente', Create_account: 'Criar conta', Create_Channel: 'Criar Canal', + Created_snippet: 'Criou um snippet', Create_a_new_workspace: 'Criar nova área de trabalho', Create: 'Criar', Delete_Room_Warning: 'A exclusão de uma sala irá apagar todas as mensagens postadas na sala. Isso não pode ser desfeito.', @@ -212,6 +213,7 @@ export default { No_files: 'Não há arquivos', No_mentioned_messages: 'Não há menções', No_pinned_messages: 'Não há mensagens fixadas', + No_results_found: 'Nenhum resultado encontrado', No_snippeted_messages: 'Não há trechos de mensagens', No_starred_messages: 'Não há mensagens favoritas', No_announcement_provided: 'Sem anúncio.', diff --git a/app/lib/methods/loadMessagesForRoom.js b/app/lib/methods/loadMessagesForRoom.js index f20b57c6..1258769c 100644 --- a/app/lib/methods/loadMessagesForRoom.js +++ b/app/lib/methods/loadMessagesForRoom.js @@ -6,6 +6,19 @@ import database from '../realm'; import log from '../../utils/log'; async function load({ rid: roomId, latest, t }) { + if (t === 'l') { + try { + const data = await SDK.driver.asyncCall('loadHistory', roomId, null, 50, latest); + if (!data || data.status === 'error') { + return []; + } + return data.messages; + } catch (error) { + console.log(error); + return []; + } + } + let params = { roomId, count: 50 }; if (latest) { params = { ...params, latest: new Date(latest).toISOString() }; diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index 85bfb584..7bfec9cc 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -14,11 +14,7 @@ import { } from '../actions/login'; import { disconnect, connectSuccess, connectRequest } from '../actions/connect'; import { setActiveUser } from '../actions/activeUsers'; -import { starredMessagesReceived, starredMessageUnstarred } from '../actions/starredMessages'; -import { pinnedMessagesReceived, pinnedMessageUnpinned } from '../actions/pinnedMessages'; -import { mentionedMessagesReceived } from '../actions/mentionedMessages'; import { snippetedMessagesReceived } from '../actions/snippetedMessages'; -import { roomFilesReceived } from '../actions/roomFiles'; import { someoneTyping, roomMessageReceived } from '../actions/room'; import { setRoles } from '../actions/roles'; @@ -199,79 +195,6 @@ const RocketChat = { } })); - SDK.driver.on('rocketchat_starred_message', protectedFunction((error, ddpMessage) => { - if (ddpMessage.msg === 'added') { - this.starredMessages = this.starredMessages || []; - - if (this.starredMessagesTimer) { - clearTimeout(this.starredMessagesTimer); - this.starredMessagesTimer = null; - } - - this.starredMessagesTimer = setTimeout(protectedFunction(() => { - reduxStore.dispatch(starredMessagesReceived(this.starredMessages)); - this.starredMessagesTimer = null; - return this.starredMessages = []; - }), 1000); - const message = ddpMessage.fields; - message._id = ddpMessage.id; - const starredMessage = _buildMessage(message); - this.starredMessages = [...this.starredMessages, starredMessage]; - } - if (ddpMessage.msg === 'removed') { - if (reduxStore.getState().starredMessages.isOpen) { - return reduxStore.dispatch(starredMessageUnstarred(ddpMessage.id)); - } - } - })); - - SDK.driver.on('rocketchat_pinned_message', protectedFunction((error, ddpMessage) => { - if (ddpMessage.msg === 'added') { - this.pinnedMessages = this.pinnedMessages || []; - - if (this.pinnedMessagesTimer) { - clearTimeout(this.pinnedMessagesTimer); - this.pinnedMessagesTimer = null; - } - - this.pinnedMessagesTimer = setTimeout(() => { - reduxStore.dispatch(pinnedMessagesReceived(this.pinnedMessages)); - this.pinnedMessagesTimer = null; - return this.pinnedMessages = []; - }, 1000); - const message = ddpMessage.fields; - message._id = ddpMessage.id; - const pinnedMessage = _buildMessage(message); - this.pinnedMessages = [...this.pinnedMessages, pinnedMessage]; - } - if (ddpMessage.msg === 'removed') { - if (reduxStore.getState().pinnedMessages.isOpen) { - return reduxStore.dispatch(pinnedMessageUnpinned(ddpMessage.id)); - } - } - })); - - SDK.driver.on('rocketchat_mentioned_message', protectedFunction((error, ddpMessage) => { - if (ddpMessage.msg === 'added') { - this.mentionedMessages = this.mentionedMessages || []; - - if (this.mentionedMessagesTimer) { - clearTimeout(this.mentionedMessagesTimer); - this.mentionedMessagesTimer = null; - } - - this.mentionedMessagesTimer = setTimeout(() => { - reduxStore.dispatch(mentionedMessagesReceived(this.mentionedMessages)); - this.mentionedMessagesTimer = null; - return this.mentionedMessages = []; - }, 1000); - const message = ddpMessage.fields; - message._id = ddpMessage.id; - const mentionedMessage = _buildMessage(message); - this.mentionedMessages = [...this.mentionedMessages, mentionedMessage]; - } - })); - SDK.driver.on('rocketchat_snippeted_message', protectedFunction((error, ddpMessage) => { if (ddpMessage.msg === 'added') { this.snippetedMessages = this.snippetedMessages || []; @@ -293,50 +216,6 @@ const RocketChat = { } })); - SDK.driver.on('room_files', protectedFunction((error, ddpMessage) => { - if (ddpMessage.msg === 'added') { - this.roomFiles = this.roomFiles || []; - - if (this.roomFilesTimer) { - clearTimeout(this.roomFilesTimer); - this.roomFilesTimer = null; - } - - this.roomFilesTimer = setTimeout(() => { - reduxStore.dispatch(roomFilesReceived(this.roomFiles)); - this.roomFilesTimer = null; - return this.roomFiles = []; - }, 1000); - const { fields } = ddpMessage; - const message = { - _id: ddpMessage.id, - ts: fields.uploadedAt, - msg: fields.description, - status: 0, - attachments: [{ - title: fields.name - }], - urls: [], - reactions: [], - u: { - username: fields.user.username - } - }; - const fileUrl = `/file-upload/${ ddpMessage.id }/${ fields.name }`; - if (/image/.test(fields.type)) { - message.attachments[0].image_type = fields.type; - message.attachments[0].image_url = fileUrl; - } else if (/audio/.test(fields.type)) { - message.attachments[0].audio_type = fields.type; - message.attachments[0].audio_url = fileUrl; - } else if (/video/.test(fields.type)) { - message.attachments[0].video_type = fields.type; - message.attachments[0].video_url = fileUrl; - } - this.roomFiles = [...this.roomFiles, message]; - } - })); - SDK.driver.on('rocketchat_roles', protectedFunction((error, ddpMessage) => { this.roles = this.roles || {}; @@ -678,7 +557,7 @@ const RocketChat = { async getRoomMember(rid, currentUserId) { try { const membersResult = await RocketChat.getRoomMembers(rid, true); - return Promise.resolve(membersResult.records.find(m => m.id !== currentUserId)); + return Promise.resolve(membersResult.records.find(m => m._id !== currentUserId)); } catch (error) { return Promise.reject(error); } @@ -692,8 +571,8 @@ const RocketChat = { leaveRoom(roomId, t) { return SDK.api.post(`${ this.roomTypeToApiType(t) }.leave`, { roomId }); }, - eraseRoom(rid) { - return call('eraseRoom', rid); + eraseRoom(roomId, t) { + return SDK.api.post(`${ this.roomTypeToApiType(t) }.delete`, { roomId }); }, toggleMuteUserInRoom(rid, username, mute) { if (mute) { @@ -701,17 +580,17 @@ const RocketChat = { } return call('unmuteUserInRoom', { rid, username }); }, - toggleArchiveRoom(rid, archive) { + toggleArchiveRoom(roomId, t, archive) { if (archive) { - return call('archiveRoom', rid); + return SDK.api.post(`${ this.roomTypeToApiType(t) }.archive`, { roomId }); } - return call('unarchiveRoom', rid); + return SDK.api.post(`${ this.roomTypeToApiType(t) }.unarchive`, { roomId }); }, saveRoomSettings(rid, params) { return call('saveRoomSettings', rid, params); }, - saveUserProfile(params, customFields) { - return call('saveUserProfile', params, customFields); + saveUserProfile(data) { + return SDK.api.post('users.updateOwnBasicInfo', { data }); }, saveUserPreferences(params) { return call('saveUserPreferences', params); @@ -719,9 +598,6 @@ const RocketChat = { saveNotificationSettings(roomId, notifications) { return SDK.api.post('rooms.saveNotification', { roomId, notifications }); }, - messageSearch(text, rid, limit) { - return call('messageSearch', text, rid, limit); - }, addUsersToRoom(rid) { let { users } = reduxStore.getState().selectedUsers; users = users.map(u => u.name); @@ -756,8 +632,8 @@ const RocketChat = { getAvatarSuggestion() { return call('getAvatarSuggestion'); }, - resetAvatar() { - return call('resetAvatar'); + resetAvatar(userId) { + return SDK.api.post('users.resetAvatar', { userId }); }, setAvatarFromService({ data, contentType = '', service = null }) { return call('setAvatarFromService', data, contentType, service); @@ -804,6 +680,30 @@ const RocketChat = { c: 'channels', d: 'im', p: 'groups' }; return types[t]; + }, + getFiles(roomId, type, offset) { + return SDK.api.get(`${ this.roomTypeToApiType(type) }.files`, { + roomId, + offset, + sort: { uploadedAt: -1 }, + fields: { + name: 1, description: 1, size: 1, type: 1, uploadedAt: 1, url: 1, userId: 1 + } + }); + }, + getMessages(roomId, type, query, offset) { + return SDK.api.get(`${ this.roomTypeToApiType(type) }.messages`, { + roomId, + query, + offset, + sort: { ts: -1 } + }); + }, + searchMessages(roomId, searchText) { + return SDK.api.get('chat.search', { + roomId, + searchText + }); } }; diff --git a/app/reducers/index.js b/app/reducers/index.js index 86b6bcaa..0eae9c99 100644 --- a/app/reducers/index.js +++ b/app/reducers/index.js @@ -12,11 +12,7 @@ import app from './app'; import customEmojis from './customEmojis'; import activeUsers from './activeUsers'; import roles from './roles'; -import starredMessages from './starredMessages'; -import pinnedMessages from './pinnedMessages'; -import mentionedMessages from './mentionedMessages'; import snippetedMessages from './snippetedMessages'; -import roomFiles from './roomFiles'; import sortPreferences from './sortPreferences'; export default combineReducers({ @@ -33,10 +29,6 @@ export default combineReducers({ customEmojis, activeUsers, roles, - starredMessages, - pinnedMessages, - mentionedMessages, snippetedMessages, - roomFiles, sortPreferences }); diff --git a/app/reducers/mentionedMessages.js b/app/reducers/mentionedMessages.js deleted file mode 100644 index f8c445dd..00000000 --- a/app/reducers/mentionedMessages.js +++ /dev/null @@ -1,30 +0,0 @@ -import { MENTIONED_MESSAGES } from '../actions/actionsTypes'; - -const initialState = { - messages: [], - ready: false -}; - -export default function server(state = initialState, action) { - switch (action.type) { - case MENTIONED_MESSAGES.OPEN: - return { - ...state, - ready: false - }; - case MENTIONED_MESSAGES.READY: - return { - ...state, - ready: true - }; - case MENTIONED_MESSAGES.MESSAGES_RECEIVED: - return { - ...state, - messages: [...state.messages, ...action.messages] - }; - case MENTIONED_MESSAGES.CLOSE: - return initialState; - default: - return state; - } -} diff --git a/app/reducers/pinnedMessages.js b/app/reducers/pinnedMessages.js deleted file mode 100644 index d912e5b7..00000000 --- a/app/reducers/pinnedMessages.js +++ /dev/null @@ -1,37 +0,0 @@ -import { PINNED_MESSAGES } from '../actions/actionsTypes'; - -const initialState = { - messages: [], - isOpen: false, - ready: false -}; - -export default function server(state = initialState, action) { - switch (action.type) { - case PINNED_MESSAGES.OPEN: - return { - ...state, - isOpen: true, - ready: false - }; - case PINNED_MESSAGES.READY: - return { - ...state, - ready: true - }; - case PINNED_MESSAGES.MESSAGES_RECEIVED: - return { - ...state, - messages: [...state.messages, ...action.messages] - }; - case PINNED_MESSAGES.MESSAGE_UNPINNED: - return { - ...state, - messages: state.messages.filter(message => message._id !== action.messageId) - }; - case PINNED_MESSAGES.CLOSE: - return initialState; - default: - return state; - } -} diff --git a/app/reducers/roomFiles.js b/app/reducers/roomFiles.js deleted file mode 100644 index 911f295a..00000000 --- a/app/reducers/roomFiles.js +++ /dev/null @@ -1,30 +0,0 @@ -import { ROOM_FILES } from '../actions/actionsTypes'; - -const initialState = { - messages: [], - ready: false -}; - -export default function server(state = initialState, action) { - switch (action.type) { - case ROOM_FILES.OPEN: - return { - ...state, - ready: false - }; - case ROOM_FILES.READY: - return { - ...state, - ready: true - }; - case ROOM_FILES.MESSAGES_RECEIVED: - return { - ...state, - messages: [...state.messages, ...action.messages] - }; - case ROOM_FILES.CLOSE: - return initialState; - default: - return state; - } -} diff --git a/app/reducers/starredMessages.js b/app/reducers/starredMessages.js deleted file mode 100644 index b96fbe87..00000000 --- a/app/reducers/starredMessages.js +++ /dev/null @@ -1,37 +0,0 @@ -import { STARRED_MESSAGES } from '../actions/actionsTypes'; - -const initialState = { - messages: [], - isOpen: false, - ready: false -}; - -export default function server(state = initialState, action) { - switch (action.type) { - case STARRED_MESSAGES.OPEN: - return { - ...state, - isOpen: true, - ready: false - }; - case STARRED_MESSAGES.READY: - return { - ...state, - ready: true - }; - case STARRED_MESSAGES.MESSAGES_RECEIVED: - return { - ...state, - messages: [...state.messages, ...action.messages] - }; - case STARRED_MESSAGES.MESSAGE_UNSTARRED: - return { - ...state, - messages: state.messages.filter(message => message._id !== action.messageId) - }; - case STARRED_MESSAGES.CLOSE: - return initialState; - default: - return state; - } -} diff --git a/app/sagas/index.js b/app/sagas/index.js index d0e0d675..b85e7229 100644 --- a/app/sagas/index.js +++ b/app/sagas/index.js @@ -6,11 +6,7 @@ import selectServer from './selectServer'; import createChannel from './createChannel'; import init from './init'; import state from './state'; -import starredMessages from './starredMessages'; -import pinnedMessages from './pinnedMessages'; -import mentionedMessages from './mentionedMessages'; import snippetedMessages from './snippetedMessages'; -import roomFiles from './roomFiles'; import deepLinking from './deepLinking'; const root = function* root() { @@ -22,11 +18,7 @@ const root = function* root() { messages(), selectServer(), state(), - starredMessages(), - pinnedMessages(), - mentionedMessages(), snippetedMessages(), - roomFiles(), deepLinking() ]); }; diff --git a/app/sagas/login.js b/app/sagas/login.js index 6dad0566..1937f06b 100644 --- a/app/sagas/login.js +++ b/app/sagas/login.js @@ -33,7 +33,8 @@ const handleLoginRequest = function* handleLoginRequest({ credentials }) { username: data.me.username, name: data.me.name, language: data.me.language, - status: data.me.status + status: data.me.status, + customFields: data.me.customFields }; return yield put(loginSuccess(user)); } diff --git a/app/sagas/mentionedMessages.js b/app/sagas/mentionedMessages.js deleted file mode 100644 index 6543a15c..00000000 --- a/app/sagas/mentionedMessages.js +++ /dev/null @@ -1,41 +0,0 @@ -import { put, takeLatest } from 'redux-saga/effects'; - -import * as types from '../actions/actionsTypes'; -import RocketChat from '../lib/rocketchat'; -import { readyMentionedMessages } from '../actions/mentionedMessages'; -import log from '../utils/log'; - -let sub; -let newSub; - -const openMentionedMessagesRoom = function* openMentionedMessagesRoom({ rid, limit }) { - try { - newSub = yield RocketChat.subscribe('mentionedMessages', rid, limit); - yield put(readyMentionedMessages()); - if (sub) { - sub.unsubscribe().catch(err => console.warn(err)); - } - sub = newSub; - } catch (e) { - log('openMentionedMessagesRoom', e); - } -}; - -const closeMentionedMessagesRoom = function* closeMentionedMessagesRoom() { - try { - if (sub) { - yield sub.unsubscribe(); - } - if (newSub) { - yield newSub.unsubscribe(); - } - } catch (e) { - log('closeMentionedMessagesRoom', e); - } -}; - -const root = function* root() { - yield takeLatest(types.MENTIONED_MESSAGES.OPEN, openMentionedMessagesRoom); - yield takeLatest(types.MENTIONED_MESSAGES.CLOSE, closeMentionedMessagesRoom); -}; -export default root; diff --git a/app/sagas/pinnedMessages.js b/app/sagas/pinnedMessages.js deleted file mode 100644 index b14007f8..00000000 --- a/app/sagas/pinnedMessages.js +++ /dev/null @@ -1,41 +0,0 @@ -import { put, takeLatest } from 'redux-saga/effects'; - -import * as types from '../actions/actionsTypes'; -import RocketChat from '../lib/rocketchat'; -import { readyPinnedMessages } from '../actions/pinnedMessages'; -import log from '../utils/log'; - -let sub; -let newSub; - -const openPinnedMessagesRoom = function* openPinnedMessagesRoom({ rid, limit }) { - try { - newSub = yield RocketChat.subscribe('pinnedMessages', rid, limit); - yield put(readyPinnedMessages()); - if (sub) { - sub.unsubscribe().catch(err => console.warn(err)); - } - sub = newSub; - } catch (e) { - log('openPinnedMessagesRoom', e); - } -}; - -const closePinnedMessagesRoom = function* closePinnedMessagesRoom() { - try { - if (sub) { - yield sub.unsubscribe(); - } - if (newSub) { - yield newSub.unsubscribe(); - } - } catch (e) { - log('closePinnedMessagesRoom', e); - } -}; - -const root = function* root() { - yield takeLatest(types.PINNED_MESSAGES.OPEN, openPinnedMessagesRoom); - yield takeLatest(types.PINNED_MESSAGES.CLOSE, closePinnedMessagesRoom); -}; -export default root; diff --git a/app/sagas/roomFiles.js b/app/sagas/roomFiles.js deleted file mode 100644 index 42a01988..00000000 --- a/app/sagas/roomFiles.js +++ /dev/null @@ -1,43 +0,0 @@ -import { put, takeLatest } from 'redux-saga/effects'; - -import * as types from '../actions/actionsTypes'; -import RocketChat from '../lib/rocketchat'; -import { readyRoomFiles } from '../actions/roomFiles'; -import log from '../utils/log'; - -let sub; -let newSub; - -const openRoomFiles = function* openRoomFiles({ rid, limit }) { - try { - sub = yield RocketChat.subscribe('roomFiles', rid, limit); - yield put(readyRoomFiles()); - if (sub) { - sub.unsubscribe().catch(err => console.warn(err)); - } - sub = newSub; - } catch (e) { - log('openRoomFiles', e); - } -}; - -const closeRoomFiles = function* closeRoomFiles() { - try { - // yield sub.unsubscribe(sub); - // sub = null; - if (sub) { - yield sub.unsubscribe(); - } - if (newSub) { - yield newSub.unsubscribe(); - } - } catch (e) { - log('closeRoomFiles', e); - } -}; - -const root = function* root() { - yield takeLatest(types.ROOM_FILES.OPEN, openRoomFiles); - yield takeLatest(types.ROOM_FILES.CLOSE, closeRoomFiles); -}; -export default root; diff --git a/app/sagas/rooms.js b/app/sagas/rooms.js index 6c1df3a8..defc7c56 100644 --- a/app/sagas/rooms.js +++ b/app/sagas/rooms.js @@ -13,8 +13,6 @@ import database from '../lib/realm'; import log from '../utils/log'; import I18n from '../i18n'; -const eraseRoom = rid => RocketChat.eraseRoom(rid); - let sub; let thread; @@ -120,25 +118,13 @@ const watchuserTyping = function* watchuserTyping({ status }) { } }; -const goRoomsListAndDelete = function* goRoomsListAndDelete(rid) { - yield Navigation.popToRoot('RoomsListView'); - try { - database.write(() => { - const messages = database.objects('messages').filtered('rid = $0', rid); - database.delete(messages); - const subscription = database.objects('subscriptions').filtered('rid = $0', rid); - database.delete(subscription); - }); - } catch (error) { - console.warn('goRoomsListAndDelete', error); - } -}; - const handleLeaveRoom = function* handleLeaveRoom({ rid, t }) { try { sub.stop(); - yield RocketChat.leaveRoom(rid, t); - yield goRoomsListAndDelete(rid); + const result = yield RocketChat.leaveRoom(rid, t); + if (result.success) { + yield Navigation.popToRoot('RoomsListView'); + } } catch (e) { if (e.data && e.data.errorType === 'error-you-are-last-owner') { Alert.alert(I18n.t('Oops'), I18n.t(e.data.errorType)); @@ -148,11 +134,13 @@ const handleLeaveRoom = function* handleLeaveRoom({ rid, t }) { } }; -const handleEraseRoom = function* handleEraseRoom({ rid }) { +const handleEraseRoom = function* handleEraseRoom({ rid, t }) { try { sub.stop(); - yield eraseRoom(rid); - yield goRoomsListAndDelete(rid, 'erase'); + const result = yield RocketChat.eraseRoom(rid, t); + if (result.success) { + yield Navigation.popToRoot('RoomsListView'); + } } catch (e) { Alert.alert(I18n.t('Oops'), I18n.t('There_was_an_error_while_action', { action: I18n.t('erasing_room') })); } diff --git a/app/sagas/starredMessages.js b/app/sagas/starredMessages.js deleted file mode 100644 index dcba2895..00000000 --- a/app/sagas/starredMessages.js +++ /dev/null @@ -1,41 +0,0 @@ -import { put, takeLatest } from 'redux-saga/effects'; - -import * as types from '../actions/actionsTypes'; -import RocketChat from '../lib/rocketchat'; -import { readyStarredMessages } from '../actions/starredMessages'; -import log from '../utils/log'; - -let sub; -let newSub; - -const openStarredMessagesRoom = function* openStarredMessagesRoom({ rid, limit }) { - try { - newSub = yield RocketChat.subscribe('starredMessages', rid, limit); - yield put(readyStarredMessages()); - if (sub) { - sub.unsubscribe().catch(err => console.warn(err)); - } - sub = newSub; - } catch (e) { - log('openStarredMessagesRoom', e); - } -}; - -const closeStarredMessagesRoom = function* closeStarredMessagesRoom() { - try { - if (sub) { - yield sub.unsubscribe(); - } - if (newSub) { - yield newSub.unsubscribe(); - } - } catch (e) { - log('closeStarredMessagesRoom', e); - } -}; - -const root = function* root() { - yield takeLatest(types.STARRED_MESSAGES.OPEN, openStarredMessagesRoom); - yield takeLatest(types.STARRED_MESSAGES.CLOSE, closeStarredMessagesRoom); -}; -export default root; diff --git a/app/views/MentionedMessagesView/index.js b/app/views/MentionedMessagesView/index.js index ef461b23..524b69b4 100644 --- a/app/views/MentionedMessagesView/index.js +++ b/app/views/MentionedMessagesView/index.js @@ -3,26 +3,25 @@ import PropTypes from 'prop-types'; import { FlatList, View, Text } from 'react-native'; import { connect } from 'react-redux'; import SafeAreaView from 'react-native-safe-area-view'; +import equal from 'deep-equal'; -import { openMentionedMessages as openMentionedMessagesAction, closeMentionedMessages as closeMentionedMessagesAction } from '../../actions/mentionedMessages'; import LoggedView from '../View'; import styles from './styles'; -import Message from '../../containers/message'; +import Message from '../../containers/message/Message'; import RCActivityIndicator from '../../containers/ActivityIndicator'; import I18n from '../../i18n'; import { DEFAULT_HEADER } from '../../constants/headerOptions'; +import RocketChat from '../../lib/rocketchat'; +import database from '../../lib/realm'; @connect(state => ({ - messages: state.mentionedMessages.messages, - ready: state.mentionedMessages.ready, + baseUrl: state.settings.Site_Url || state.server ? state.server.server : '', + customEmojis: state.customEmojis, user: { id: state.login.user && state.login.user.id, username: state.login.user && state.login.user.username, token: state.login.user && state.login.user.token } -}), dispatch => ({ - openMentionedMessages: (rid, limit) => dispatch(openMentionedMessagesAction(rid, limit)), - closeMentionedMessages: () => dispatch(closeMentionedMessagesAction()) })) /** @extends React.Component */ export default class MentionedMessagesView extends LoggedView { @@ -41,53 +40,57 @@ export default class MentionedMessagesView extends LoggedView { static propTypes = { rid: PropTypes.string, - messages: PropTypes.array, - ready: PropTypes.bool, user: PropTypes.object, - openMentionedMessages: PropTypes.func, - closeMentionedMessages: PropTypes.func + baseUrl: PropTypes.string, + customEmojis: PropTypes.object } constructor(props) { - super('MentionedMessagesView', props); + super('StarredMessagesView', props); + this.rooms = database.objects('subscriptions').filtered('rid = $0', props.rid); this.state = { - loading: true, - loadingMore: false + loading: false, + room: this.rooms[0], + messages: [] }; } componentDidMount() { - this.limit = 20; this.load(); } - componentWillReceiveProps(nextProps) { - const { ready } = this.props; - if (nextProps.ready && nextProps.ready !== ready) { - this.setState({ loading: false, loadingMore: false }); - } + shouldComponentUpdate(nextProps, nextState) { + return !equal(this.state, nextState); } - componentWillUnmount() { - const { closeMentionedMessages } = this.props; - closeMentionedMessages(); - } - - load = () => { - const { openMentionedMessages, rid } = this.props; - openMentionedMessages(rid, this.limit); - } - - moreData = () => { - const { loadingMore } = this.state; - const { messages } = this.props; - if (messages.length < this.limit) { + load = async() => { + const { + messages, total, loading, room + } = this.state; + const { user } = this.props; + if (messages.length === total || loading) { return; } - if (!loadingMore) { - this.setState({ loadingMore: true }); - this.limit += 20; - this.load(); + + this.setState({ loading: true }); + + try { + const result = await RocketChat.getMessages( + room.rid, + room.t, + { 'mentions._id': { $in: [user.id] } }, + messages.length + ); + if (result.success) { + this.setState(prevState => ({ + messages: [...prevState.messages, ...result.messages], + total: result.total, + loading: false + })); + } + } catch (error) { + this.setState({ loading: false }); + console.log('MentionedMessagesView -> load -> catch -> error', error); } } @@ -98,23 +101,28 @@ export default class MentionedMessagesView extends LoggedView { ) renderItem = ({ item }) => { - const { user } = this.props; + const { user, customEmojis, baseUrl } = this.props; return ( ); } render() { - const { loading, loadingMore } = this.state; - const { messages, ready } = this.props; + const { messages, loading } = this.state; - if (ready && messages.length === 0) { + if (!loading && messages.length === 0) { return this.renderEmpty(); } @@ -125,9 +133,8 @@ export default class MentionedMessagesView extends LoggedView { renderItem={this.renderItem} style={styles.list} keyExtractor={item => item._id} - onEndReached={this.moreData} - ListHeaderComponent={loading ? : null} - ListFooterComponent={loadingMore ? : null} + onEndReached={this.load} + ListFooterComponent={loading ? : null} /> ); diff --git a/app/views/PinnedMessagesView/index.js b/app/views/PinnedMessagesView/index.js index daba4ae3..544ce1ca 100644 --- a/app/views/PinnedMessagesView/index.js +++ b/app/views/PinnedMessagesView/index.js @@ -4,32 +4,29 @@ import { FlatList, View, Text } from 'react-native'; import { connect } from 'react-redux'; import ActionSheet from 'react-native-actionsheet'; import SafeAreaView from 'react-native-safe-area-view'; +import equal from 'deep-equal'; -import { openPinnedMessages as openPinnedMessagesAction, closePinnedMessages as closePinnedMessagesAction } from '../../actions/pinnedMessages'; -import { togglePinRequest as togglePinRequestAction } from '../../actions/messages'; import LoggedView from '../View'; import styles from './styles'; -import Message from '../../containers/message'; +import Message from '../../containers/message/Message'; import RCActivityIndicator from '../../containers/ActivityIndicator'; import I18n from '../../i18n'; import { DEFAULT_HEADER } from '../../constants/headerOptions'; +import RocketChat from '../../lib/rocketchat'; +import database from '../../lib/realm'; const PIN_INDEX = 0; const CANCEL_INDEX = 1; const options = [I18n.t('Unpin'), I18n.t('Cancel')]; @connect(state => ({ - messages: state.pinnedMessages.messages, - ready: state.pinnedMessages.ready, + baseUrl: state.settings.Site_Url || state.server ? state.server.server : '', + customEmojis: state.customEmojis, user: { id: state.login.user && state.login.user.id, username: state.login.user && state.login.user.username, token: state.login.user && state.login.user.token } -}), dispatch => ({ - openPinnedMessages: (rid, limit) => dispatch(openPinnedMessagesAction(rid, limit)), - closePinnedMessages: () => dispatch(closePinnedMessagesAction()), - togglePinRequest: message => dispatch(togglePinRequestAction(message)) })) /** @extends React.Component */ export default class PinnedMessagesView extends LoggedView { @@ -48,38 +45,27 @@ export default class PinnedMessagesView extends LoggedView { static propTypes = { rid: PropTypes.string, - messages: PropTypes.array, - ready: PropTypes.bool, user: PropTypes.object, - openPinnedMessages: PropTypes.func, - closePinnedMessages: PropTypes.func, - togglePinRequest: PropTypes.func + baseUrl: PropTypes.string, + customEmojis: PropTypes.object } constructor(props) { super('PinnedMessagesView', props); + this.rooms = database.objects('subscriptions').filtered('rid = $0', props.rid); this.state = { - message: {}, - loading: true, - loadingMore: false + loading: false, + room: this.rooms[0], + messages: [] }; } componentDidMount() { - this.limit = 20; this.load(); } - componentWillReceiveProps(nextProps) { - const { ready } = this.props; - if (nextProps.ready && nextProps.ready !== ready) { - this.setState({ loading: false, loadingMore: false }); - } - } - - componentWillUnmount() { - const { closePinnedMessages } = this.props; - closePinnedMessages(); + shouldComponentUpdate(nextProps, nextState) { + return !equal(this.state, nextState); } onLongPress = (message) => { @@ -90,33 +76,51 @@ export default class PinnedMessagesView extends LoggedView { } handleActionPress = (actionIndex) => { - const { message } = this.state; - const { togglePinRequest } = this.props; - switch (actionIndex) { case PIN_INDEX: - togglePinRequest(message); + this.unPin(); break; default: break; } } - load = () => { - const { openPinnedMessages, rid } = this.props; - openPinnedMessages(rid, this.limit); + unPin = async() => { + const { message } = this.state; + try { + const result = await RocketChat.togglePinMessage(message); + if (result.success) { + this.setState(prevState => ({ + messages: prevState.messages.filter(item => item._id !== message._id) + })); + } + } catch (error) { + console.log('PinnedMessagesView -> unPin -> catch -> error', error); + } } - moreData = () => { - const { loadingMore } = this.state; - const { messages } = this.props; - if (messages.length < this.limit) { + load = async() => { + const { + messages, total, loading, room + } = this.state; + if (messages.length === total || loading) { return; } - if (!loadingMore) { - this.setState({ loadingMore: true }); - this.limit += 20; - this.load(); + + this.setState({ loading: true }); + + try { + const result = await RocketChat.getMessages(room.rid, room.t, { pinned: true }, messages.length); + if (result.success) { + this.setState(prevState => ({ + messages: [...prevState.messages, ...result.messages], + total: result.total, + loading: false + })); + } + } catch (error) { + this.setState({ loading: false }); + console.log('PinnedMessagesView -> catch -> error', error); } } @@ -127,24 +131,29 @@ export default class PinnedMessagesView extends LoggedView { ) renderItem = ({ item }) => { - const { user } = this.props; + const { user, customEmojis, baseUrl } = this.props; return ( this.onLongPress(item)} /> ); } render() { - const { loading, loadingMore } = this.state; - const { messages, ready } = this.props; + const { messages, loading } = this.state; - if (ready && messages.length === 0) { + if (!loading && messages.length === 0) { return this.renderEmpty(); } @@ -155,9 +164,8 @@ export default class PinnedMessagesView extends LoggedView { renderItem={this.renderItem} style={styles.list} keyExtractor={item => item._id} - onEndReached={this.moreData} - ListHeaderComponent={loading ? : null} - ListFooterComponent={loadingMore ? : null} + onEndReached={this.load} + ListFooterComponent={loading ? : null} /> this.actionSheet = o} diff --git a/app/views/ProfileView/index.js b/app/views/ProfileView/index.js index c688327d..52772744 100644 --- a/app/views/ProfileView/index.js +++ b/app/views/ProfileView/index.js @@ -20,7 +20,6 @@ import scrollPersistTaps from '../../utils/scrollPersistTaps'; import { showErrorAlert, showToast } from '../../utils/info'; import RocketChat from '../../lib/rocketchat'; import RCTextInput from '../../containers/TextInput'; -import Loading from '../../containers/Loading'; import log from '../../utils/log'; import I18n from '../../i18n'; import Button from '../../containers/Button'; @@ -29,9 +28,11 @@ import Touch from '../../utils/touch'; import Drawer from '../../Drawer'; import { DEFAULT_HEADER } from '../../constants/headerOptions'; import { appStart as appStartAction } from '../../actions'; +import { setUser as setUserAction } from '../../actions/login'; @connect(state => ({ user: { + id: state.login.user && state.login.user.id, name: state.login.user && state.login.user.name, username: state.login.user && state.login.user.username, customFields: state.login.user && state.login.user.customFields, @@ -40,7 +41,8 @@ import { appStart as appStartAction } from '../../actions'; Accounts_CustomFields: state.settings.Accounts_CustomFields, baseUrl: state.settings.Site_Url || state.server ? state.server.server : '' }), dispatch => ({ - appStart: () => dispatch(appStartAction()) + appStart: () => dispatch(appStartAction()), + setUser: params => dispatch(setUserAction(params)) })) /** @extends React.Component */ export default class ProfileView extends LoggedView { @@ -75,7 +77,8 @@ export default class ProfileView extends LoggedView { componentId: PropTypes.string, user: PropTypes.object, Accounts_CustomFields: PropTypes.string, - appStart: PropTypes.func + appStart: PropTypes.func, + setUser: PropTypes.func } constructor(props) { @@ -87,7 +90,7 @@ export default class ProfileView extends LoggedView { username: null, email: null, newPassword: null, - typedPassword: null, + currentPassword: null, avatarUrl: null, avatar: {}, avatarSuggestions: {}, @@ -146,7 +149,7 @@ export default class ProfileView extends LoggedView { username, email: emails ? emails[0].address : null, newPassword: null, - typedPassword: null, + currentPassword: null, avatarUrl: null, avatar: {}, customFields: customFields || {} @@ -163,7 +166,7 @@ export default class ProfileView extends LoggedView { const customFieldsKeys = Object.keys(customFields); if (customFieldsKeys.length) { customFieldsKeys.forEach((key) => { - if (user.customFields[key] !== customFields[key]) { + if (!user.customFields || user.customFields[key] !== customFields[key]) { customFieldsChanged = true; } }); @@ -183,13 +186,8 @@ export default class ProfileView extends LoggedView { } handleError = (e, func, action) => { - if (e && e.error && e.error !== 500) { - if (e.details && e.details.timeToReset) { - return showErrorAlert(I18n.t('error-too-many-requests', { - seconds: parseInt(e.details.timeToReset / 1000, 10) - })); - } - return showErrorAlert(I18n.t(e.error, e.details)); + if (e.data && e.data.errorType === 'error-too-many-requests') { + return showErrorAlert(e.data.error); } showErrorAlert(I18n.t('There_was_an_error_while_action', { action: I18n.t(action) })); log(func, e); @@ -205,14 +203,14 @@ export default class ProfileView extends LoggedView { this.setState({ saving: true, showPasswordAlert: false }); const { - name, username, email, newPassword, typedPassword, avatar, customFields + name, username, email, newPassword, currentPassword, avatar, customFields } = this.state; - const { user } = this.props; + const { user, setUser } = this.props; const params = {}; // Name if (user.name !== name) { - params.realname = name; + params.name = name; } // Username @@ -230,13 +228,13 @@ export default class ProfileView extends LoggedView { params.newPassword = newPassword; } - // typedPassword - if (typedPassword) { - params.typedPassword = SHA256(typedPassword); + // currentPassword + if (currentPassword) { + params.currentPassword = SHA256(currentPassword); } const requirePassword = !!params.email || newPassword; - if (requirePassword && !params.typedPassword) { + if (requirePassword && !params.currentPassword) { return this.setState({ showPasswordAlert: true, saving: false }); } @@ -245,28 +243,32 @@ export default class ProfileView extends LoggedView { try { await RocketChat.setAvatarFromService(avatar); } catch (e) { - this.setState({ saving: false, typedPassword: null }); - return setTimeout(() => this.handleError(e, 'setAvatarFromService', 'changing_avatar'), 300); + this.setState({ saving: false, currentPassword: null }); + return this.handleError(e, 'setAvatarFromService', 'changing_avatar'); } } - await RocketChat.saveUserProfile(params, customFields); - this.setState({ saving: false }); - setTimeout(() => { + params.customFields = customFields; + + const result = await RocketChat.saveUserProfile(params); + if (result.success) { + if (params.customFields) { + setUser({ customFields }); + } + this.setState({ saving: false }); showToast(I18n.t('Profile_saved_successfully')); this.init(); - }, 300); + } } catch (e) { - this.setState({ saving: false, typedPassword: null }); - setTimeout(() => { - this.handleError(e, 'saveUserProfile', 'saving_profile'); - }, 300); + this.setState({ saving: false, currentPassword: null }); + this.handleError(e, 'saveUserProfile', 'saving_profile'); } } resetAvatar = async() => { try { - await RocketChat.resetAvatar(); + const { user } = this.props; + await RocketChat.resetAvatar(user.id); showToast(I18n.t('Avatar_changed_successfully')); this.init(); } catch (e) { @@ -353,53 +355,57 @@ export default class ProfileView extends LoggedView { if (!Accounts_CustomFields) { return null; } - const parsedCustomFields = JSON.parse(Accounts_CustomFields); - return Object.keys(parsedCustomFields).map((key, index, array) => { - if (parsedCustomFields[key].type === 'select') { - const options = parsedCustomFields[key].options.map(option => ({ label: option, value: option })); + try { + const parsedCustomFields = JSON.parse(Accounts_CustomFields); + return Object.keys(parsedCustomFields).map((key, index, array) => { + if (parsedCustomFields[key].type === 'select') { + const options = parsedCustomFields[key].options.map(option => ({ label: option, value: option })); + return ( + { + const newValue = {}; + newValue[key] = value; + this.setState({ customFields: { ...customFields, ...newValue } }); + }} + value={customFields[key]} + > + { this[key] = e; }} + label={key} + placeholder={key} + value={customFields[key]} + testID='settings-view-language' + /> + + ); + } + return ( - { this[key] = e; }} key={key} - items={options} - onValueChange={(value) => { + label={key} + placeholder={key} + value={customFields[key]} + onChangeText={(value) => { const newValue = {}; newValue[key] = value; this.setState({ customFields: { ...customFields, ...newValue } }); }} - value={customFields[key]} - > - { this[key] = e; }} - label={key} - placeholder={key} - value={customFields[key]} - testID='settings-view-language' - /> - + onSubmitEditing={() => { + if (array.length - 1 > index) { + return this[array[index + 1]].focus(); + } + this.avatarUrl.focus(); + }} + /> ); - } - - return ( - { this[key] = e; }} - key={key} - label={key} - placeholder={key} - value={customFields[key]} - onChangeText={(value) => { - const newValue = {}; - newValue[key] = value; - this.setState({ customFields: { ...customFields, ...newValue } }); - }} - onSubmitEditing={() => { - if (array.length - 1 > index) { - return this[array[index + 1]].focus(); - } - this.avatarUrl.focus(); - }} - /> - ); - }); + }); + } catch (error) { + return null; + } } render() { @@ -480,16 +486,14 @@ export default class ProfileView extends LoggedView { testID='profile-view-avatar-url' /> {this.renderAvatarButtons()} - -