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
This commit is contained in:
parent
dca2181b2c
commit
ad37586065
|
@ -77,10 +77,6 @@ export const METEOR = createRequestTypes('METEOR_CONNECT', [...defaultTypes, 'DI
|
||||||
export const LOGOUT = 'LOGOUT'; // logout is always success
|
export const LOGOUT = 'LOGOUT'; // logout is always success
|
||||||
export const ACTIVE_USERS = createRequestTypes('ACTIVE_USERS', ['SET']);
|
export const ACTIVE_USERS = createRequestTypes('ACTIVE_USERS', ['SET']);
|
||||||
export const ROLES = createRequestTypes('ROLES', ['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 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 DEEP_LINKING = createRequestTypes('DEEP_LINKING', ['OPEN']);
|
||||||
export const SORT_PREFERENCES = createRequestTypes('SORT_PREFERENCES', ['SET_ALL', 'SET']);
|
export const SORT_PREFERENCES = createRequestTypes('SORT_PREFERENCES', ['SET_ALL', 'SET']);
|
||||||
|
|
|
@ -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
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -39,7 +39,8 @@ const SYSTEM_MESSAGES = [
|
||||||
'room_changed_description',
|
'room_changed_description',
|
||||||
'room_changed_announcement',
|
'room_changed_announcement',
|
||||||
'room_changed_topic',
|
'room_changed_topic',
|
||||||
'room_changed_privacy'
|
'room_changed_privacy',
|
||||||
|
'message_snippeted'
|
||||||
];
|
];
|
||||||
|
|
||||||
const getInfoMessage = ({
|
const getInfoMessage = ({
|
||||||
|
@ -76,6 +77,8 @@ const getInfoMessage = ({
|
||||||
return I18n.t('Room_changed_topic', { topic: msg, userBy: username });
|
return I18n.t('Room_changed_topic', { topic: msg, userBy: username });
|
||||||
} else if (type === 'room_changed_privacy') {
|
} else if (type === 'room_changed_privacy') {
|
||||||
return I18n.t('Room_changed_privacy', { type: msg, userBy: username });
|
return I18n.t('Room_changed_privacy', { type: msg, userBy: username });
|
||||||
|
} else if (type === 'message_snippeted') {
|
||||||
|
return I18n.t('Created_snippet');
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
|
@ -107,7 +110,10 @@ export default class Message extends PureComponent {
|
||||||
header: PropTypes.bool,
|
header: PropTypes.bool,
|
||||||
avatar: PropTypes.string,
|
avatar: PropTypes.string,
|
||||||
alias: PropTypes.string,
|
alias: PropTypes.string,
|
||||||
ts: PropTypes.instanceOf(Date),
|
ts: PropTypes.oneOfType([
|
||||||
|
PropTypes.instanceOf(Date),
|
||||||
|
PropTypes.string
|
||||||
|
]),
|
||||||
edited: PropTypes.bool,
|
edited: PropTypes.bool,
|
||||||
attachments: PropTypes.oneOfType([
|
attachments: PropTypes.oneOfType([
|
||||||
PropTypes.array,
|
PropTypes.array,
|
||||||
|
|
|
@ -35,7 +35,10 @@ export default class User extends React.PureComponent {
|
||||||
timeFormat: PropTypes.string.isRequired,
|
timeFormat: PropTypes.string.isRequired,
|
||||||
username: PropTypes.string,
|
username: PropTypes.string,
|
||||||
alias: PropTypes.string,
|
alias: PropTypes.string,
|
||||||
ts: PropTypes.instanceOf(Date),
|
ts: PropTypes.oneOfType([
|
||||||
|
PropTypes.instanceOf(Date),
|
||||||
|
PropTypes.string
|
||||||
|
]),
|
||||||
temp: PropTypes.bool
|
temp: PropTypes.bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,7 @@ export default {
|
||||||
Copy_Permalink: 'Copy Permalink',
|
Copy_Permalink: 'Copy Permalink',
|
||||||
Create_account: 'Create an account',
|
Create_account: 'Create an account',
|
||||||
Create_Channel: 'Create Channel',
|
Create_Channel: 'Create Channel',
|
||||||
|
Created_snippet: 'Created a snippet',
|
||||||
Create_a_new_workspace: 'Create a new workspace',
|
Create_a_new_workspace: 'Create a new workspace',
|
||||||
Create: 'Create',
|
Create: 'Create',
|
||||||
Delete_Room_Warning: 'Deleting a room will delete all messages posted within the room. This cannot be undone.',
|
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_files: 'No files',
|
||||||
No_mentioned_messages: 'No mentioned messages',
|
No_mentioned_messages: 'No mentioned messages',
|
||||||
No_pinned_messages: 'No pinned messages',
|
No_pinned_messages: 'No pinned messages',
|
||||||
|
No_results_found: 'No results found',
|
||||||
No_snippeted_messages: 'No snippeted messages',
|
No_snippeted_messages: 'No snippeted messages',
|
||||||
No_starred_messages: 'No starred messages',
|
No_starred_messages: 'No starred messages',
|
||||||
No_announcement_provided: 'No announcement provided.',
|
No_announcement_provided: 'No announcement provided.',
|
||||||
|
|
|
@ -138,6 +138,7 @@ export default {
|
||||||
Copy_Permalink: 'Copiar Link-Permanente',
|
Copy_Permalink: 'Copiar Link-Permanente',
|
||||||
Create_account: 'Criar conta',
|
Create_account: 'Criar conta',
|
||||||
Create_Channel: 'Criar Canal',
|
Create_Channel: 'Criar Canal',
|
||||||
|
Created_snippet: 'Criou um snippet',
|
||||||
Create_a_new_workspace: 'Criar nova área de trabalho',
|
Create_a_new_workspace: 'Criar nova área de trabalho',
|
||||||
Create: 'Criar',
|
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.',
|
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_files: 'Não há arquivos',
|
||||||
No_mentioned_messages: 'Não há menções',
|
No_mentioned_messages: 'Não há menções',
|
||||||
No_pinned_messages: 'Não há mensagens fixadas',
|
No_pinned_messages: 'Não há mensagens fixadas',
|
||||||
|
No_results_found: 'Nenhum resultado encontrado',
|
||||||
No_snippeted_messages: 'Não há trechos de mensagens',
|
No_snippeted_messages: 'Não há trechos de mensagens',
|
||||||
No_starred_messages: 'Não há mensagens favoritas',
|
No_starred_messages: 'Não há mensagens favoritas',
|
||||||
No_announcement_provided: 'Sem anúncio.',
|
No_announcement_provided: 'Sem anúncio.',
|
||||||
|
|
|
@ -6,6 +6,19 @@ import database from '../realm';
|
||||||
import log from '../../utils/log';
|
import log from '../../utils/log';
|
||||||
|
|
||||||
async function load({ rid: roomId, latest, t }) {
|
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 };
|
let params = { roomId, count: 50 };
|
||||||
if (latest) {
|
if (latest) {
|
||||||
params = { ...params, latest: new Date(latest).toISOString() };
|
params = { ...params, latest: new Date(latest).toISOString() };
|
||||||
|
|
|
@ -14,11 +14,7 @@ import {
|
||||||
} from '../actions/login';
|
} from '../actions/login';
|
||||||
import { disconnect, connectSuccess, connectRequest } from '../actions/connect';
|
import { disconnect, connectSuccess, connectRequest } from '../actions/connect';
|
||||||
import { setActiveUser } from '../actions/activeUsers';
|
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 { snippetedMessagesReceived } from '../actions/snippetedMessages';
|
||||||
import { roomFilesReceived } from '../actions/roomFiles';
|
|
||||||
import { someoneTyping, roomMessageReceived } from '../actions/room';
|
import { someoneTyping, roomMessageReceived } from '../actions/room';
|
||||||
import { setRoles } from '../actions/roles';
|
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) => {
|
SDK.driver.on('rocketchat_snippeted_message', protectedFunction((error, ddpMessage) => {
|
||||||
if (ddpMessage.msg === 'added') {
|
if (ddpMessage.msg === 'added') {
|
||||||
this.snippetedMessages = this.snippetedMessages || [];
|
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) => {
|
SDK.driver.on('rocketchat_roles', protectedFunction((error, ddpMessage) => {
|
||||||
this.roles = this.roles || {};
|
this.roles = this.roles || {};
|
||||||
|
|
||||||
|
@ -678,7 +557,7 @@ const RocketChat = {
|
||||||
async getRoomMember(rid, currentUserId) {
|
async getRoomMember(rid, currentUserId) {
|
||||||
try {
|
try {
|
||||||
const membersResult = await RocketChat.getRoomMembers(rid, true);
|
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) {
|
} catch (error) {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
|
@ -692,8 +571,8 @@ const RocketChat = {
|
||||||
leaveRoom(roomId, t) {
|
leaveRoom(roomId, t) {
|
||||||
return SDK.api.post(`${ this.roomTypeToApiType(t) }.leave`, { roomId });
|
return SDK.api.post(`${ this.roomTypeToApiType(t) }.leave`, { roomId });
|
||||||
},
|
},
|
||||||
eraseRoom(rid) {
|
eraseRoom(roomId, t) {
|
||||||
return call('eraseRoom', rid);
|
return SDK.api.post(`${ this.roomTypeToApiType(t) }.delete`, { roomId });
|
||||||
},
|
},
|
||||||
toggleMuteUserInRoom(rid, username, mute) {
|
toggleMuteUserInRoom(rid, username, mute) {
|
||||||
if (mute) {
|
if (mute) {
|
||||||
|
@ -701,17 +580,17 @@ const RocketChat = {
|
||||||
}
|
}
|
||||||
return call('unmuteUserInRoom', { rid, username });
|
return call('unmuteUserInRoom', { rid, username });
|
||||||
},
|
},
|
||||||
toggleArchiveRoom(rid, archive) {
|
toggleArchiveRoom(roomId, t, archive) {
|
||||||
if (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) {
|
saveRoomSettings(rid, params) {
|
||||||
return call('saveRoomSettings', rid, params);
|
return call('saveRoomSettings', rid, params);
|
||||||
},
|
},
|
||||||
saveUserProfile(params, customFields) {
|
saveUserProfile(data) {
|
||||||
return call('saveUserProfile', params, customFields);
|
return SDK.api.post('users.updateOwnBasicInfo', { data });
|
||||||
},
|
},
|
||||||
saveUserPreferences(params) {
|
saveUserPreferences(params) {
|
||||||
return call('saveUserPreferences', params);
|
return call('saveUserPreferences', params);
|
||||||
|
@ -719,9 +598,6 @@ const RocketChat = {
|
||||||
saveNotificationSettings(roomId, notifications) {
|
saveNotificationSettings(roomId, notifications) {
|
||||||
return SDK.api.post('rooms.saveNotification', { roomId, notifications });
|
return SDK.api.post('rooms.saveNotification', { roomId, notifications });
|
||||||
},
|
},
|
||||||
messageSearch(text, rid, limit) {
|
|
||||||
return call('messageSearch', text, rid, limit);
|
|
||||||
},
|
|
||||||
addUsersToRoom(rid) {
|
addUsersToRoom(rid) {
|
||||||
let { users } = reduxStore.getState().selectedUsers;
|
let { users } = reduxStore.getState().selectedUsers;
|
||||||
users = users.map(u => u.name);
|
users = users.map(u => u.name);
|
||||||
|
@ -756,8 +632,8 @@ const RocketChat = {
|
||||||
getAvatarSuggestion() {
|
getAvatarSuggestion() {
|
||||||
return call('getAvatarSuggestion');
|
return call('getAvatarSuggestion');
|
||||||
},
|
},
|
||||||
resetAvatar() {
|
resetAvatar(userId) {
|
||||||
return call('resetAvatar');
|
return SDK.api.post('users.resetAvatar', { userId });
|
||||||
},
|
},
|
||||||
setAvatarFromService({ data, contentType = '', service = null }) {
|
setAvatarFromService({ data, contentType = '', service = null }) {
|
||||||
return call('setAvatarFromService', data, contentType, service);
|
return call('setAvatarFromService', data, contentType, service);
|
||||||
|
@ -804,6 +680,30 @@ const RocketChat = {
|
||||||
c: 'channels', d: 'im', p: 'groups'
|
c: 'channels', d: 'im', p: 'groups'
|
||||||
};
|
};
|
||||||
return types[t];
|
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
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,7 @@ import app from './app';
|
||||||
import customEmojis from './customEmojis';
|
import customEmojis from './customEmojis';
|
||||||
import activeUsers from './activeUsers';
|
import activeUsers from './activeUsers';
|
||||||
import roles from './roles';
|
import roles from './roles';
|
||||||
import starredMessages from './starredMessages';
|
|
||||||
import pinnedMessages from './pinnedMessages';
|
|
||||||
import mentionedMessages from './mentionedMessages';
|
|
||||||
import snippetedMessages from './snippetedMessages';
|
import snippetedMessages from './snippetedMessages';
|
||||||
import roomFiles from './roomFiles';
|
|
||||||
import sortPreferences from './sortPreferences';
|
import sortPreferences from './sortPreferences';
|
||||||
|
|
||||||
export default combineReducers({
|
export default combineReducers({
|
||||||
|
@ -33,10 +29,6 @@ export default combineReducers({
|
||||||
customEmojis,
|
customEmojis,
|
||||||
activeUsers,
|
activeUsers,
|
||||||
roles,
|
roles,
|
||||||
starredMessages,
|
|
||||||
pinnedMessages,
|
|
||||||
mentionedMessages,
|
|
||||||
snippetedMessages,
|
snippetedMessages,
|
||||||
roomFiles,
|
|
||||||
sortPreferences
|
sortPreferences
|
||||||
});
|
});
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,11 +6,7 @@ import selectServer from './selectServer';
|
||||||
import createChannel from './createChannel';
|
import createChannel from './createChannel';
|
||||||
import init from './init';
|
import init from './init';
|
||||||
import state from './state';
|
import state from './state';
|
||||||
import starredMessages from './starredMessages';
|
|
||||||
import pinnedMessages from './pinnedMessages';
|
|
||||||
import mentionedMessages from './mentionedMessages';
|
|
||||||
import snippetedMessages from './snippetedMessages';
|
import snippetedMessages from './snippetedMessages';
|
||||||
import roomFiles from './roomFiles';
|
|
||||||
import deepLinking from './deepLinking';
|
import deepLinking from './deepLinking';
|
||||||
|
|
||||||
const root = function* root() {
|
const root = function* root() {
|
||||||
|
@ -22,11 +18,7 @@ const root = function* root() {
|
||||||
messages(),
|
messages(),
|
||||||
selectServer(),
|
selectServer(),
|
||||||
state(),
|
state(),
|
||||||
starredMessages(),
|
|
||||||
pinnedMessages(),
|
|
||||||
mentionedMessages(),
|
|
||||||
snippetedMessages(),
|
snippetedMessages(),
|
||||||
roomFiles(),
|
|
||||||
deepLinking()
|
deepLinking()
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,7 +33,8 @@ const handleLoginRequest = function* handleLoginRequest({ credentials }) {
|
||||||
username: data.me.username,
|
username: data.me.username,
|
||||||
name: data.me.name,
|
name: data.me.name,
|
||||||
language: data.me.language,
|
language: data.me.language,
|
||||||
status: data.me.status
|
status: data.me.status,
|
||||||
|
customFields: data.me.customFields
|
||||||
};
|
};
|
||||||
return yield put(loginSuccess(user));
|
return yield put(loginSuccess(user));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
|
@ -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;
|
|
|
@ -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;
|
|
|
@ -13,8 +13,6 @@ import database from '../lib/realm';
|
||||||
import log from '../utils/log';
|
import log from '../utils/log';
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
|
|
||||||
const eraseRoom = rid => RocketChat.eraseRoom(rid);
|
|
||||||
|
|
||||||
let sub;
|
let sub;
|
||||||
let thread;
|
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 }) {
|
const handleLeaveRoom = function* handleLeaveRoom({ rid, t }) {
|
||||||
try {
|
try {
|
||||||
sub.stop();
|
sub.stop();
|
||||||
yield RocketChat.leaveRoom(rid, t);
|
const result = yield RocketChat.leaveRoom(rid, t);
|
||||||
yield goRoomsListAndDelete(rid);
|
if (result.success) {
|
||||||
|
yield Navigation.popToRoot('RoomsListView');
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.data && e.data.errorType === 'error-you-are-last-owner') {
|
if (e.data && e.data.errorType === 'error-you-are-last-owner') {
|
||||||
Alert.alert(I18n.t('Oops'), I18n.t(e.data.errorType));
|
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 {
|
try {
|
||||||
sub.stop();
|
sub.stop();
|
||||||
yield eraseRoom(rid);
|
const result = yield RocketChat.eraseRoom(rid, t);
|
||||||
yield goRoomsListAndDelete(rid, 'erase');
|
if (result.success) {
|
||||||
|
yield Navigation.popToRoot('RoomsListView');
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Alert.alert(I18n.t('Oops'), I18n.t('There_was_an_error_while_action', { action: I18n.t('erasing_room') }));
|
Alert.alert(I18n.t('Oops'), I18n.t('There_was_an_error_while_action', { action: I18n.t('erasing_room') }));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
|
@ -3,26 +3,25 @@ import PropTypes from 'prop-types';
|
||||||
import { FlatList, View, Text } from 'react-native';
|
import { FlatList, View, Text } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import SafeAreaView from 'react-native-safe-area-view';
|
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 LoggedView from '../View';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import Message from '../../containers/message';
|
import Message from '../../containers/message/Message';
|
||||||
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import { DEFAULT_HEADER } from '../../constants/headerOptions';
|
import { DEFAULT_HEADER } from '../../constants/headerOptions';
|
||||||
|
import RocketChat from '../../lib/rocketchat';
|
||||||
|
import database from '../../lib/realm';
|
||||||
|
|
||||||
@connect(state => ({
|
@connect(state => ({
|
||||||
messages: state.mentionedMessages.messages,
|
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '',
|
||||||
ready: state.mentionedMessages.ready,
|
customEmojis: state.customEmojis,
|
||||||
user: {
|
user: {
|
||||||
id: state.login.user && state.login.user.id,
|
id: state.login.user && state.login.user.id,
|
||||||
username: state.login.user && state.login.user.username,
|
username: state.login.user && state.login.user.username,
|
||||||
token: state.login.user && state.login.user.token
|
token: state.login.user && state.login.user.token
|
||||||
}
|
}
|
||||||
}), dispatch => ({
|
|
||||||
openMentionedMessages: (rid, limit) => dispatch(openMentionedMessagesAction(rid, limit)),
|
|
||||||
closeMentionedMessages: () => dispatch(closeMentionedMessagesAction())
|
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
/** @extends React.Component */
|
||||||
export default class MentionedMessagesView extends LoggedView {
|
export default class MentionedMessagesView extends LoggedView {
|
||||||
|
@ -41,53 +40,57 @@ export default class MentionedMessagesView extends LoggedView {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
rid: PropTypes.string,
|
rid: PropTypes.string,
|
||||||
messages: PropTypes.array,
|
|
||||||
ready: PropTypes.bool,
|
|
||||||
user: PropTypes.object,
|
user: PropTypes.object,
|
||||||
openMentionedMessages: PropTypes.func,
|
baseUrl: PropTypes.string,
|
||||||
closeMentionedMessages: PropTypes.func
|
customEmojis: PropTypes.object
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('MentionedMessagesView', props);
|
super('StarredMessagesView', props);
|
||||||
|
this.rooms = database.objects('subscriptions').filtered('rid = $0', props.rid);
|
||||||
this.state = {
|
this.state = {
|
||||||
loading: true,
|
loading: false,
|
||||||
loadingMore: false
|
room: this.rooms[0],
|
||||||
|
messages: []
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.limit = 20;
|
|
||||||
this.load();
|
this.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
const { ready } = this.props;
|
return !equal(this.state, nextState);
|
||||||
if (nextProps.ready && nextProps.ready !== ready) {
|
|
||||||
this.setState({ loading: false, loadingMore: false });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
load = async() => {
|
||||||
const { closeMentionedMessages } = this.props;
|
const {
|
||||||
closeMentionedMessages();
|
messages, total, loading, room
|
||||||
}
|
} = this.state;
|
||||||
|
const { user } = this.props;
|
||||||
load = () => {
|
if (messages.length === total || loading) {
|
||||||
const { openMentionedMessages, rid } = this.props;
|
|
||||||
openMentionedMessages(rid, this.limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
moreData = () => {
|
|
||||||
const { loadingMore } = this.state;
|
|
||||||
const { messages } = this.props;
|
|
||||||
if (messages.length < this.limit) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!loadingMore) {
|
|
||||||
this.setState({ loadingMore: true });
|
this.setState({ loading: true });
|
||||||
this.limit += 20;
|
|
||||||
this.load();
|
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 }) => {
|
renderItem = ({ item }) => {
|
||||||
const { user } = this.props;
|
const { user, customEmojis, baseUrl } = this.props;
|
||||||
return (
|
return (
|
||||||
<Message
|
<Message
|
||||||
item={item}
|
|
||||||
style={styles.message}
|
style={styles.message}
|
||||||
reactions={item.reactions}
|
customEmojis={customEmojis}
|
||||||
|
baseUrl={baseUrl}
|
||||||
user={user}
|
user={user}
|
||||||
customTimeFormat='MMMM Do YYYY, h:mm:ss a'
|
author={item.u}
|
||||||
|
ts={item.ts}
|
||||||
|
msg={item.msg}
|
||||||
|
attachments={item.attachments || []}
|
||||||
|
timeFormat='MMM Do YYYY, h:mm:ss a'
|
||||||
|
edited={!!item.editedAt}
|
||||||
|
header
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { loading, loadingMore } = this.state;
|
const { messages, loading } = this.state;
|
||||||
const { messages, ready } = this.props;
|
|
||||||
|
|
||||||
if (ready && messages.length === 0) {
|
if (!loading && messages.length === 0) {
|
||||||
return this.renderEmpty();
|
return this.renderEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,9 +133,8 @@ export default class MentionedMessagesView extends LoggedView {
|
||||||
renderItem={this.renderItem}
|
renderItem={this.renderItem}
|
||||||
style={styles.list}
|
style={styles.list}
|
||||||
keyExtractor={item => item._id}
|
keyExtractor={item => item._id}
|
||||||
onEndReached={this.moreData}
|
onEndReached={this.load}
|
||||||
ListHeaderComponent={loading ? <RCActivityIndicator /> : null}
|
ListFooterComponent={loading ? <RCActivityIndicator /> : null}
|
||||||
ListFooterComponent={loadingMore ? <RCActivityIndicator /> : null}
|
|
||||||
/>
|
/>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,32 +4,29 @@ import { FlatList, View, Text } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import ActionSheet from 'react-native-actionsheet';
|
import ActionSheet from 'react-native-actionsheet';
|
||||||
import SafeAreaView from 'react-native-safe-area-view';
|
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 LoggedView from '../View';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import Message from '../../containers/message';
|
import Message from '../../containers/message/Message';
|
||||||
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import { DEFAULT_HEADER } from '../../constants/headerOptions';
|
import { DEFAULT_HEADER } from '../../constants/headerOptions';
|
||||||
|
import RocketChat from '../../lib/rocketchat';
|
||||||
|
import database from '../../lib/realm';
|
||||||
|
|
||||||
const PIN_INDEX = 0;
|
const PIN_INDEX = 0;
|
||||||
const CANCEL_INDEX = 1;
|
const CANCEL_INDEX = 1;
|
||||||
const options = [I18n.t('Unpin'), I18n.t('Cancel')];
|
const options = [I18n.t('Unpin'), I18n.t('Cancel')];
|
||||||
|
|
||||||
@connect(state => ({
|
@connect(state => ({
|
||||||
messages: state.pinnedMessages.messages,
|
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '',
|
||||||
ready: state.pinnedMessages.ready,
|
customEmojis: state.customEmojis,
|
||||||
user: {
|
user: {
|
||||||
id: state.login.user && state.login.user.id,
|
id: state.login.user && state.login.user.id,
|
||||||
username: state.login.user && state.login.user.username,
|
username: state.login.user && state.login.user.username,
|
||||||
token: state.login.user && state.login.user.token
|
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 */
|
/** @extends React.Component */
|
||||||
export default class PinnedMessagesView extends LoggedView {
|
export default class PinnedMessagesView extends LoggedView {
|
||||||
|
@ -48,38 +45,27 @@ export default class PinnedMessagesView extends LoggedView {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
rid: PropTypes.string,
|
rid: PropTypes.string,
|
||||||
messages: PropTypes.array,
|
|
||||||
ready: PropTypes.bool,
|
|
||||||
user: PropTypes.object,
|
user: PropTypes.object,
|
||||||
openPinnedMessages: PropTypes.func,
|
baseUrl: PropTypes.string,
|
||||||
closePinnedMessages: PropTypes.func,
|
customEmojis: PropTypes.object
|
||||||
togglePinRequest: PropTypes.func
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('PinnedMessagesView', props);
|
super('PinnedMessagesView', props);
|
||||||
|
this.rooms = database.objects('subscriptions').filtered('rid = $0', props.rid);
|
||||||
this.state = {
|
this.state = {
|
||||||
message: {},
|
loading: false,
|
||||||
loading: true,
|
room: this.rooms[0],
|
||||||
loadingMore: false
|
messages: []
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.limit = 20;
|
|
||||||
this.load();
|
this.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
const { ready } = this.props;
|
return !equal(this.state, nextState);
|
||||||
if (nextProps.ready && nextProps.ready !== ready) {
|
|
||||||
this.setState({ loading: false, loadingMore: false });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
const { closePinnedMessages } = this.props;
|
|
||||||
closePinnedMessages();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onLongPress = (message) => {
|
onLongPress = (message) => {
|
||||||
|
@ -90,33 +76,51 @@ export default class PinnedMessagesView extends LoggedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleActionPress = (actionIndex) => {
|
handleActionPress = (actionIndex) => {
|
||||||
const { message } = this.state;
|
|
||||||
const { togglePinRequest } = this.props;
|
|
||||||
|
|
||||||
switch (actionIndex) {
|
switch (actionIndex) {
|
||||||
case PIN_INDEX:
|
case PIN_INDEX:
|
||||||
togglePinRequest(message);
|
this.unPin();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
load = () => {
|
unPin = async() => {
|
||||||
const { openPinnedMessages, rid } = this.props;
|
const { message } = this.state;
|
||||||
openPinnedMessages(rid, this.limit);
|
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 = () => {
|
load = async() => {
|
||||||
const { loadingMore } = this.state;
|
const {
|
||||||
const { messages } = this.props;
|
messages, total, loading, room
|
||||||
if (messages.length < this.limit) {
|
} = this.state;
|
||||||
|
if (messages.length === total || loading) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!loadingMore) {
|
|
||||||
this.setState({ loadingMore: true });
|
this.setState({ loading: true });
|
||||||
this.limit += 20;
|
|
||||||
this.load();
|
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 }) => {
|
renderItem = ({ item }) => {
|
||||||
const { user } = this.props;
|
const { user, customEmojis, baseUrl } = this.props;
|
||||||
return (
|
return (
|
||||||
<Message
|
<Message
|
||||||
item={item}
|
|
||||||
style={styles.message}
|
style={styles.message}
|
||||||
reactions={item.reactions}
|
customEmojis={customEmojis}
|
||||||
|
baseUrl={baseUrl}
|
||||||
user={user}
|
user={user}
|
||||||
customTimeFormat='MMMM Do YYYY, h:mm:ss a'
|
author={item.u}
|
||||||
onLongPress={this.onLongPress}
|
ts={item.ts}
|
||||||
|
msg={item.msg}
|
||||||
|
attachments={item.attachments || []}
|
||||||
|
timeFormat='MMM Do YYYY, h:mm:ss a'
|
||||||
|
header
|
||||||
|
edited={!!item.editedAt}
|
||||||
|
onLongPress={() => this.onLongPress(item)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { loading, loadingMore } = this.state;
|
const { messages, loading } = this.state;
|
||||||
const { messages, ready } = this.props;
|
|
||||||
|
|
||||||
if (ready && messages.length === 0) {
|
if (!loading && messages.length === 0) {
|
||||||
return this.renderEmpty();
|
return this.renderEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,9 +164,8 @@ export default class PinnedMessagesView extends LoggedView {
|
||||||
renderItem={this.renderItem}
|
renderItem={this.renderItem}
|
||||||
style={styles.list}
|
style={styles.list}
|
||||||
keyExtractor={item => item._id}
|
keyExtractor={item => item._id}
|
||||||
onEndReached={this.moreData}
|
onEndReached={this.load}
|
||||||
ListHeaderComponent={loading ? <RCActivityIndicator /> : null}
|
ListFooterComponent={loading ? <RCActivityIndicator /> : null}
|
||||||
ListFooterComponent={loadingMore ? <RCActivityIndicator /> : null}
|
|
||||||
/>
|
/>
|
||||||
<ActionSheet
|
<ActionSheet
|
||||||
ref={o => this.actionSheet = o}
|
ref={o => this.actionSheet = o}
|
||||||
|
|
|
@ -20,7 +20,6 @@ import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
||||||
import { showErrorAlert, showToast } from '../../utils/info';
|
import { showErrorAlert, showToast } from '../../utils/info';
|
||||||
import RocketChat from '../../lib/rocketchat';
|
import RocketChat from '../../lib/rocketchat';
|
||||||
import RCTextInput from '../../containers/TextInput';
|
import RCTextInput from '../../containers/TextInput';
|
||||||
import Loading from '../../containers/Loading';
|
|
||||||
import log from '../../utils/log';
|
import log from '../../utils/log';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import Button from '../../containers/Button';
|
import Button from '../../containers/Button';
|
||||||
|
@ -29,9 +28,11 @@ import Touch from '../../utils/touch';
|
||||||
import Drawer from '../../Drawer';
|
import Drawer from '../../Drawer';
|
||||||
import { DEFAULT_HEADER } from '../../constants/headerOptions';
|
import { DEFAULT_HEADER } from '../../constants/headerOptions';
|
||||||
import { appStart as appStartAction } from '../../actions';
|
import { appStart as appStartAction } from '../../actions';
|
||||||
|
import { setUser as setUserAction } from '../../actions/login';
|
||||||
|
|
||||||
@connect(state => ({
|
@connect(state => ({
|
||||||
user: {
|
user: {
|
||||||
|
id: state.login.user && state.login.user.id,
|
||||||
name: state.login.user && state.login.user.name,
|
name: state.login.user && state.login.user.name,
|
||||||
username: state.login.user && state.login.user.username,
|
username: state.login.user && state.login.user.username,
|
||||||
customFields: state.login.user && state.login.user.customFields,
|
customFields: state.login.user && state.login.user.customFields,
|
||||||
|
@ -40,7 +41,8 @@ import { appStart as appStartAction } from '../../actions';
|
||||||
Accounts_CustomFields: state.settings.Accounts_CustomFields,
|
Accounts_CustomFields: state.settings.Accounts_CustomFields,
|
||||||
baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
|
baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
|
||||||
}), dispatch => ({
|
}), dispatch => ({
|
||||||
appStart: () => dispatch(appStartAction())
|
appStart: () => dispatch(appStartAction()),
|
||||||
|
setUser: params => dispatch(setUserAction(params))
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
/** @extends React.Component */
|
||||||
export default class ProfileView extends LoggedView {
|
export default class ProfileView extends LoggedView {
|
||||||
|
@ -75,7 +77,8 @@ export default class ProfileView extends LoggedView {
|
||||||
componentId: PropTypes.string,
|
componentId: PropTypes.string,
|
||||||
user: PropTypes.object,
|
user: PropTypes.object,
|
||||||
Accounts_CustomFields: PropTypes.string,
|
Accounts_CustomFields: PropTypes.string,
|
||||||
appStart: PropTypes.func
|
appStart: PropTypes.func,
|
||||||
|
setUser: PropTypes.func
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -87,7 +90,7 @@ export default class ProfileView extends LoggedView {
|
||||||
username: null,
|
username: null,
|
||||||
email: null,
|
email: null,
|
||||||
newPassword: null,
|
newPassword: null,
|
||||||
typedPassword: null,
|
currentPassword: null,
|
||||||
avatarUrl: null,
|
avatarUrl: null,
|
||||||
avatar: {},
|
avatar: {},
|
||||||
avatarSuggestions: {},
|
avatarSuggestions: {},
|
||||||
|
@ -146,7 +149,7 @@ export default class ProfileView extends LoggedView {
|
||||||
username,
|
username,
|
||||||
email: emails ? emails[0].address : null,
|
email: emails ? emails[0].address : null,
|
||||||
newPassword: null,
|
newPassword: null,
|
||||||
typedPassword: null,
|
currentPassword: null,
|
||||||
avatarUrl: null,
|
avatarUrl: null,
|
||||||
avatar: {},
|
avatar: {},
|
||||||
customFields: customFields || {}
|
customFields: customFields || {}
|
||||||
|
@ -163,7 +166,7 @@ export default class ProfileView extends LoggedView {
|
||||||
const customFieldsKeys = Object.keys(customFields);
|
const customFieldsKeys = Object.keys(customFields);
|
||||||
if (customFieldsKeys.length) {
|
if (customFieldsKeys.length) {
|
||||||
customFieldsKeys.forEach((key) => {
|
customFieldsKeys.forEach((key) => {
|
||||||
if (user.customFields[key] !== customFields[key]) {
|
if (!user.customFields || user.customFields[key] !== customFields[key]) {
|
||||||
customFieldsChanged = true;
|
customFieldsChanged = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -183,13 +186,8 @@ export default class ProfileView extends LoggedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleError = (e, func, action) => {
|
handleError = (e, func, action) => {
|
||||||
if (e && e.error && e.error !== 500) {
|
if (e.data && e.data.errorType === 'error-too-many-requests') {
|
||||||
if (e.details && e.details.timeToReset) {
|
return showErrorAlert(e.data.error);
|
||||||
return showErrorAlert(I18n.t('error-too-many-requests', {
|
|
||||||
seconds: parseInt(e.details.timeToReset / 1000, 10)
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
return showErrorAlert(I18n.t(e.error, e.details));
|
|
||||||
}
|
}
|
||||||
showErrorAlert(I18n.t('There_was_an_error_while_action', { action: I18n.t(action) }));
|
showErrorAlert(I18n.t('There_was_an_error_while_action', { action: I18n.t(action) }));
|
||||||
log(func, e);
|
log(func, e);
|
||||||
|
@ -205,14 +203,14 @@ export default class ProfileView extends LoggedView {
|
||||||
this.setState({ saving: true, showPasswordAlert: false });
|
this.setState({ saving: true, showPasswordAlert: false });
|
||||||
|
|
||||||
const {
|
const {
|
||||||
name, username, email, newPassword, typedPassword, avatar, customFields
|
name, username, email, newPassword, currentPassword, avatar, customFields
|
||||||
} = this.state;
|
} = this.state;
|
||||||
const { user } = this.props;
|
const { user, setUser } = this.props;
|
||||||
const params = {};
|
const params = {};
|
||||||
|
|
||||||
// Name
|
// Name
|
||||||
if (user.name !== name) {
|
if (user.name !== name) {
|
||||||
params.realname = name;
|
params.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Username
|
// Username
|
||||||
|
@ -230,13 +228,13 @@ export default class ProfileView extends LoggedView {
|
||||||
params.newPassword = newPassword;
|
params.newPassword = newPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
// typedPassword
|
// currentPassword
|
||||||
if (typedPassword) {
|
if (currentPassword) {
|
||||||
params.typedPassword = SHA256(typedPassword);
|
params.currentPassword = SHA256(currentPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
const requirePassword = !!params.email || newPassword;
|
const requirePassword = !!params.email || newPassword;
|
||||||
if (requirePassword && !params.typedPassword) {
|
if (requirePassword && !params.currentPassword) {
|
||||||
return this.setState({ showPasswordAlert: true, saving: false });
|
return this.setState({ showPasswordAlert: true, saving: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,28 +243,32 @@ export default class ProfileView extends LoggedView {
|
||||||
try {
|
try {
|
||||||
await RocketChat.setAvatarFromService(avatar);
|
await RocketChat.setAvatarFromService(avatar);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.setState({ saving: false, typedPassword: null });
|
this.setState({ saving: false, currentPassword: null });
|
||||||
return setTimeout(() => this.handleError(e, 'setAvatarFromService', 'changing_avatar'), 300);
|
return this.handleError(e, 'setAvatarFromService', 'changing_avatar');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await RocketChat.saveUserProfile(params, customFields);
|
params.customFields = customFields;
|
||||||
this.setState({ saving: false });
|
|
||||||
setTimeout(() => {
|
const result = await RocketChat.saveUserProfile(params);
|
||||||
|
if (result.success) {
|
||||||
|
if (params.customFields) {
|
||||||
|
setUser({ customFields });
|
||||||
|
}
|
||||||
|
this.setState({ saving: false });
|
||||||
showToast(I18n.t('Profile_saved_successfully'));
|
showToast(I18n.t('Profile_saved_successfully'));
|
||||||
this.init();
|
this.init();
|
||||||
}, 300);
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.setState({ saving: false, typedPassword: null });
|
this.setState({ saving: false, currentPassword: null });
|
||||||
setTimeout(() => {
|
this.handleError(e, 'saveUserProfile', 'saving_profile');
|
||||||
this.handleError(e, 'saveUserProfile', 'saving_profile');
|
|
||||||
}, 300);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resetAvatar = async() => {
|
resetAvatar = async() => {
|
||||||
try {
|
try {
|
||||||
await RocketChat.resetAvatar();
|
const { user } = this.props;
|
||||||
|
await RocketChat.resetAvatar(user.id);
|
||||||
showToast(I18n.t('Avatar_changed_successfully'));
|
showToast(I18n.t('Avatar_changed_successfully'));
|
||||||
this.init();
|
this.init();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -353,53 +355,57 @@ export default class ProfileView extends LoggedView {
|
||||||
if (!Accounts_CustomFields) {
|
if (!Accounts_CustomFields) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const parsedCustomFields = JSON.parse(Accounts_CustomFields);
|
try {
|
||||||
return Object.keys(parsedCustomFields).map((key, index, array) => {
|
const parsedCustomFields = JSON.parse(Accounts_CustomFields);
|
||||||
if (parsedCustomFields[key].type === 'select') {
|
return Object.keys(parsedCustomFields).map((key, index, array) => {
|
||||||
const options = parsedCustomFields[key].options.map(option => ({ label: option, value: option }));
|
if (parsedCustomFields[key].type === 'select') {
|
||||||
|
const options = parsedCustomFields[key].options.map(option => ({ label: option, value: option }));
|
||||||
|
return (
|
||||||
|
<RNPickerSelect
|
||||||
|
key={key}
|
||||||
|
items={options}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
const newValue = {};
|
||||||
|
newValue[key] = value;
|
||||||
|
this.setState({ customFields: { ...customFields, ...newValue } });
|
||||||
|
}}
|
||||||
|
value={customFields[key]}
|
||||||
|
>
|
||||||
|
<RCTextInput
|
||||||
|
inputRef={(e) => { this[key] = e; }}
|
||||||
|
label={key}
|
||||||
|
placeholder={key}
|
||||||
|
value={customFields[key]}
|
||||||
|
testID='settings-view-language'
|
||||||
|
/>
|
||||||
|
</RNPickerSelect>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RNPickerSelect
|
<RCTextInput
|
||||||
|
inputRef={(e) => { this[key] = e; }}
|
||||||
key={key}
|
key={key}
|
||||||
items={options}
|
label={key}
|
||||||
onValueChange={(value) => {
|
placeholder={key}
|
||||||
|
value={customFields[key]}
|
||||||
|
onChangeText={(value) => {
|
||||||
const newValue = {};
|
const newValue = {};
|
||||||
newValue[key] = value;
|
newValue[key] = value;
|
||||||
this.setState({ customFields: { ...customFields, ...newValue } });
|
this.setState({ customFields: { ...customFields, ...newValue } });
|
||||||
}}
|
}}
|
||||||
value={customFields[key]}
|
onSubmitEditing={() => {
|
||||||
>
|
if (array.length - 1 > index) {
|
||||||
<RCTextInput
|
return this[array[index + 1]].focus();
|
||||||
inputRef={(e) => { this[key] = e; }}
|
}
|
||||||
label={key}
|
this.avatarUrl.focus();
|
||||||
placeholder={key}
|
}}
|
||||||
value={customFields[key]}
|
/>
|
||||||
testID='settings-view-language'
|
|
||||||
/>
|
|
||||||
</RNPickerSelect>
|
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
} catch (error) {
|
||||||
return (
|
return null;
|
||||||
<RCTextInput
|
}
|
||||||
inputRef={(e) => { 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();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -480,16 +486,14 @@ export default class ProfileView extends LoggedView {
|
||||||
testID='profile-view-avatar-url'
|
testID='profile-view-avatar-url'
|
||||||
/>
|
/>
|
||||||
{this.renderAvatarButtons()}
|
{this.renderAvatarButtons()}
|
||||||
<View style={sharedStyles.alignItemsFlexStart}>
|
<Button
|
||||||
<Button
|
title={I18n.t('Save_Changes')}
|
||||||
title={I18n.t('Save_Changes')}
|
type='primary'
|
||||||
type='primary'
|
onPress={this.submit}
|
||||||
onPress={this.submit}
|
disabled={!this.formIsChanged()}
|
||||||
disabled={!this.formIsChanged()}
|
testID='profile-view-submit'
|
||||||
testID='profile-view-submit'
|
loading={saving}
|
||||||
/>
|
/>
|
||||||
</View>
|
|
||||||
<Loading visible={saving} />
|
|
||||||
<Dialog.Container visible={showPasswordAlert}>
|
<Dialog.Container visible={showPasswordAlert}>
|
||||||
<Dialog.Title>
|
<Dialog.Title>
|
||||||
{I18n.t('Please_enter_your_password')}
|
{I18n.t('Please_enter_your_password')}
|
||||||
|
@ -498,7 +502,7 @@ export default class ProfileView extends LoggedView {
|
||||||
{I18n.t('For_your_security_you_must_enter_your_current_password_to_continue')}
|
{I18n.t('For_your_security_you_must_enter_your_current_password_to_continue')}
|
||||||
</Dialog.Description>
|
</Dialog.Description>
|
||||||
<Dialog.Input
|
<Dialog.Input
|
||||||
onChangeText={value => this.setState({ typedPassword: value })}
|
onChangeText={value => this.setState({ currentPassword: value })}
|
||||||
secureTextEntry
|
secureTextEntry
|
||||||
testID='profile-view-typed-password'
|
testID='profile-view-typed-password'
|
||||||
style={styles.dialogInput}
|
style={styles.dialogInput}
|
||||||
|
|
|
@ -68,7 +68,9 @@ export default class RoomActionsView extends LoggedView {
|
||||||
this.state = {
|
this.state = {
|
||||||
room: this.rooms[0] || {},
|
room: this.rooms[0] || {},
|
||||||
membersCount: 0,
|
membersCount: 0,
|
||||||
member: {}
|
member: {},
|
||||||
|
joined: false,
|
||||||
|
canViewMembers: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +88,9 @@ export default class RoomActionsView extends LoggedView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (room.t === 'd') {
|
||||||
|
this.updateRoomMember();
|
||||||
|
}
|
||||||
this.rooms.addListener(this.updateRoom);
|
this.rooms.addListener(this.updateRoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,6 +315,20 @@ export default class RoomActionsView extends LoggedView {
|
||||||
this.setState({ room: this.rooms[0] || {} });
|
this.setState({ room: this.rooms[0] || {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateRoomMember = async() => {
|
||||||
|
const { room } = this.state;
|
||||||
|
const { rid } = room;
|
||||||
|
const { userId } = this.props;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const member = await RocketChat.getRoomMember(rid, userId);
|
||||||
|
this.setState({ member });
|
||||||
|
} catch (e) {
|
||||||
|
log('RoomActions updateRoomMember', e);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
toggleBlockUser = () => {
|
toggleBlockUser = () => {
|
||||||
const { room } = this.state;
|
const { room } = this.state;
|
||||||
const { rid, blocker } = room;
|
const { rid, blocker } = room;
|
||||||
|
|
|
@ -3,26 +3,25 @@ import PropTypes from 'prop-types';
|
||||||
import { FlatList, View, Text } from 'react-native';
|
import { FlatList, View, Text } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import SafeAreaView from 'react-native-safe-area-view';
|
import SafeAreaView from 'react-native-safe-area-view';
|
||||||
|
import equal from 'deep-equal';
|
||||||
|
|
||||||
import { openRoomFiles as openRoomFilesAction, closeRoomFiles as closeRoomFilesAction } from '../../actions/roomFiles';
|
|
||||||
import LoggedView from '../View';
|
import LoggedView from '../View';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import Message from '../../containers/message';
|
import Message from '../../containers/message/Message';
|
||||||
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import { DEFAULT_HEADER } from '../../constants/headerOptions';
|
import { DEFAULT_HEADER } from '../../constants/headerOptions';
|
||||||
|
import database from '../../lib/realm';
|
||||||
|
import RocketChat from '../../lib/rocketchat';
|
||||||
|
|
||||||
@connect(state => ({
|
@connect(state => ({
|
||||||
messages: state.roomFiles.messages,
|
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '',
|
||||||
ready: state.roomFiles.ready,
|
customEmojis: state.customEmojis,
|
||||||
user: {
|
user: {
|
||||||
id: state.login.user && state.login.user.id,
|
id: state.login.user && state.login.user.id,
|
||||||
username: state.login.user && state.login.user.username,
|
username: state.login.user && state.login.user.username,
|
||||||
token: state.login.user && state.login.user.token
|
token: state.login.user && state.login.user.token
|
||||||
}
|
}
|
||||||
}), dispatch => ({
|
|
||||||
openRoomFiles: (rid, limit) => dispatch(openRoomFilesAction(rid, limit)),
|
|
||||||
closeRoomFiles: () => dispatch(closeRoomFilesAction())
|
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
/** @extends React.Component */
|
||||||
export default class RoomFilesView extends LoggedView {
|
export default class RoomFilesView extends LoggedView {
|
||||||
|
@ -41,53 +40,51 @@ export default class RoomFilesView extends LoggedView {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
rid: PropTypes.string,
|
rid: PropTypes.string,
|
||||||
messages: PropTypes.array,
|
|
||||||
ready: PropTypes.bool,
|
|
||||||
user: PropTypes.object,
|
user: PropTypes.object,
|
||||||
openRoomFiles: PropTypes.func,
|
baseUrl: PropTypes.string,
|
||||||
closeRoomFiles: PropTypes.func
|
customEmojis: PropTypes.object
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('RoomFilesView', props);
|
super('RoomFilesView', props);
|
||||||
|
this.rooms = database.objects('subscriptions').filtered('rid = $0', props.rid);
|
||||||
this.state = {
|
this.state = {
|
||||||
loading: true,
|
loading: false,
|
||||||
loadingMore: false
|
room: this.rooms[0],
|
||||||
|
messages: []
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.limit = 20;
|
|
||||||
this.load();
|
this.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
const { ready } = this.props;
|
return !equal(this.state, nextState);
|
||||||
if (nextProps.ready && nextProps.ready !== ready) {
|
|
||||||
this.setState({ loading: false, loadingMore: false });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
load = async() => {
|
||||||
const { closeRoomFiles } = this.props;
|
const {
|
||||||
closeRoomFiles();
|
messages, total, loading, room
|
||||||
}
|
} = this.state;
|
||||||
|
if (messages.length === total || loading) {
|
||||||
load = () => {
|
|
||||||
const { openRoomFiles, rid } = this.props;
|
|
||||||
openRoomFiles(rid, this.limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
moreData = () => {
|
|
||||||
const { loadingMore } = this.state;
|
|
||||||
const { messages } = this.props;
|
|
||||||
if (messages.length < this.limit) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!loadingMore) {
|
|
||||||
this.setState({ loadingMore: true });
|
this.setState({ loading: true });
|
||||||
this.limit += 20;
|
|
||||||
this.load();
|
try {
|
||||||
|
const result = await RocketChat.getFiles(room.rid, room.t, messages.length);
|
||||||
|
if (result.success) {
|
||||||
|
this.setState(prevState => ({
|
||||||
|
messages: [...prevState.messages, ...result.files],
|
||||||
|
total: result.total,
|
||||||
|
loading: false
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.setState({ loading: false });
|
||||||
|
console.log('RoomFilesView -> catch -> error', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,26 +95,49 @@ export default class RoomFilesView extends LoggedView {
|
||||||
)
|
)
|
||||||
|
|
||||||
renderItem = ({ item }) => {
|
renderItem = ({ item }) => {
|
||||||
const { user } = this.props;
|
const { user, baseUrl, customEmojis } = this.props;
|
||||||
|
|
||||||
|
let url = {};
|
||||||
|
if (/image/.test(item.type)) {
|
||||||
|
url = { image_url: item.url };
|
||||||
|
} else if (/audio/.test(item.type)) {
|
||||||
|
url = { audio_url: item.url };
|
||||||
|
} else if (/video/.test(item.type)) {
|
||||||
|
url = { video_url: item.url };
|
||||||
|
} else {
|
||||||
|
url = {
|
||||||
|
title_link: item.url,
|
||||||
|
type: 'file'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Message
|
<Message
|
||||||
item={item}
|
|
||||||
style={styles.message}
|
style={styles.message}
|
||||||
reactions={item.reactions}
|
customEmojis={customEmojis}
|
||||||
|
baseUrl={baseUrl}
|
||||||
user={user}
|
user={user}
|
||||||
customTimeFormat='MMMM Do YYYY, h:mm:ss a'
|
author={item.user}
|
||||||
|
ts={item.uploadedAt}
|
||||||
|
attachments={[{
|
||||||
|
title: item.name,
|
||||||
|
description: item.description,
|
||||||
|
...url
|
||||||
|
}]}
|
||||||
|
timeFormat='MMM Do YYYY, h:mm:ss a'
|
||||||
|
edited={!!item.editedAt}
|
||||||
|
header
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { messages, ready } = this.props;
|
const { messages, loading } = this.state;
|
||||||
if (ready && messages.length === 0) {
|
|
||||||
|
if (!loading && messages.length === 0) {
|
||||||
return this.renderEmpty();
|
return this.renderEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
const { loading, loadingMore } = this.state;
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={styles.list} testID='room-files-view' forceInset={{ bottom: 'never' }}>
|
<SafeAreaView style={styles.list} testID='room-files-view' forceInset={{ bottom: 'never' }}>
|
||||||
<FlatList
|
<FlatList
|
||||||
|
@ -125,9 +145,8 @@ export default class RoomFilesView extends LoggedView {
|
||||||
renderItem={this.renderItem}
|
renderItem={this.renderItem}
|
||||||
style={styles.list}
|
style={styles.list}
|
||||||
keyExtractor={item => item._id}
|
keyExtractor={item => item._id}
|
||||||
onEndReached={this.moreData}
|
onEndReached={this.load}
|
||||||
ListHeaderComponent={loading ? <RCActivityIndicator /> : null}
|
ListFooterComponent={loading ? <RCActivityIndicator /> : null}
|
||||||
ListFooterComponent={loadingMore ? <RCActivityIndicator /> : null}
|
|
||||||
/>
|
/>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
);
|
);
|
||||||
|
|
|
@ -39,7 +39,7 @@ const PERMISSIONS_ARRAY = [
|
||||||
];
|
];
|
||||||
|
|
||||||
@connect(null, dispatch => ({
|
@connect(null, dispatch => ({
|
||||||
eraseRoom: rid => dispatch(eraseRoomAction(rid))
|
eraseRoom: (rid, t) => dispatch(eraseRoomAction(rid, t))
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
/** @extends React.Component */
|
||||||
export default class RoomInfoEditView extends LoggedView {
|
export default class RoomInfoEditView extends LoggedView {
|
||||||
|
@ -231,7 +231,7 @@ export default class RoomInfoEditView extends LoggedView {
|
||||||
{
|
{
|
||||||
text: I18n.t('Yes_action_it', { action: I18n.t('delete') }),
|
text: I18n.t('Yes_action_it', { action: I18n.t('delete') }),
|
||||||
style: 'destructive',
|
style: 'destructive',
|
||||||
onPress: () => eraseRoom(room.rid)
|
onPress: () => eraseRoom(room.rid, room.t)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
{ cancelable: false }
|
{ cancelable: false }
|
||||||
|
@ -240,7 +240,7 @@ export default class RoomInfoEditView extends LoggedView {
|
||||||
|
|
||||||
toggleArchive = () => {
|
toggleArchive = () => {
|
||||||
const { room } = this.state;
|
const { room } = this.state;
|
||||||
const { rid, archived } = room;
|
const { rid, archived, t } = room;
|
||||||
|
|
||||||
const action = I18n.t(`${ archived ? 'un' : '' }archive`);
|
const action = I18n.t(`${ archived ? 'un' : '' }archive`);
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
|
@ -254,9 +254,9 @@ export default class RoomInfoEditView extends LoggedView {
|
||||||
{
|
{
|
||||||
text: I18n.t('Yes_action_it', { action }),
|
text: I18n.t('Yes_action_it', { action }),
|
||||||
style: 'destructive',
|
style: 'destructive',
|
||||||
onPress: () => {
|
onPress: async() => {
|
||||||
try {
|
try {
|
||||||
RocketChat.toggleArchiveRoom(rid, !archived);
|
await RocketChat.toggleArchiveRoom(rid, t, !archived);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log('toggleArchive', e);
|
log('toggleArchive', e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,8 +81,8 @@ export default class RoomMembersView extends LoggedView {
|
||||||
this.rooms.removeAllListeners();
|
this.rooms.removeAllListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
navigationButtonPressed = async({ buttonId }) => {
|
navigationButtonPressed = ({ buttonId }) => {
|
||||||
const { rid, allUsers } = this.state;
|
const { allUsers } = this.state;
|
||||||
const { componentId } = this.props;
|
const { componentId } = this.props;
|
||||||
|
|
||||||
if (buttonId === 'toggleOnline') {
|
if (buttonId === 'toggleOnline') {
|
||||||
|
@ -97,10 +97,7 @@ export default class RoomMembersView extends LoggedView {
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const allUsersFilter = !allUsers;
|
this.fetchMembers(!allUsers);
|
||||||
const membersResult = await RocketChat.getRoomMembers(rid, allUsersFilter);
|
|
||||||
const members = membersResult.records;
|
|
||||||
this.setState({ allUsers: allUsersFilter, members });
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log('RoomMembers.onNavigationButtonPressed', e);
|
log('RoomMembers.onNavigationButtonPressed', e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,6 +133,12 @@ export default class RoomView extends LoggedView {
|
||||||
return true;
|
return true;
|
||||||
} else if (room.f !== nextState.room.f) {
|
} else if (room.f !== nextState.room.f) {
|
||||||
return true;
|
return true;
|
||||||
|
} else if (room.blocked !== nextState.room.blocked) {
|
||||||
|
return true;
|
||||||
|
} else if (room.blocker !== nextState.room.blocker) {
|
||||||
|
return true;
|
||||||
|
} else if (room.archived !== nextState.room.archived) {
|
||||||
|
return true;
|
||||||
} else if (loaded !== nextState.loaded) {
|
} else if (loaded !== nextState.loaded) {
|
||||||
return true;
|
return true;
|
||||||
} else if (joined !== nextState.joined) {
|
} else if (joined !== nextState.joined) {
|
||||||
|
@ -156,17 +162,21 @@ export default class RoomView extends LoggedView {
|
||||||
const { componentId, appState } = this.props;
|
const { componentId, appState } = this.props;
|
||||||
|
|
||||||
if (prevState.room.f !== room.f) {
|
if (prevState.room.f !== room.f) {
|
||||||
|
const rightButtons = [{
|
||||||
|
id: 'star',
|
||||||
|
testID: 'room-view-header-star',
|
||||||
|
icon: room.f ? iconsMap.star : iconsMap.starOutline
|
||||||
|
}];
|
||||||
|
if (room.t !== 'l') {
|
||||||
|
rightButtons.unshift({
|
||||||
|
id: 'more',
|
||||||
|
testID: 'room-view-header-actions',
|
||||||
|
icon: iconsMap.more
|
||||||
|
});
|
||||||
|
}
|
||||||
Navigation.mergeOptions(componentId, {
|
Navigation.mergeOptions(componentId, {
|
||||||
topBar: {
|
topBar: {
|
||||||
rightButtons: [{
|
rightButtons
|
||||||
id: 'more',
|
|
||||||
testID: 'room-view-header-actions',
|
|
||||||
icon: iconsMap.more
|
|
||||||
}, {
|
|
||||||
id: 'star',
|
|
||||||
testID: 'room-view-header-star',
|
|
||||||
icon: room.f ? iconsMap.star : iconsMap.starOutline
|
|
||||||
}]
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (appState === 'foreground' && appState !== prevProps.appState) {
|
} else if (appState === 'foreground' && appState !== prevProps.appState) {
|
||||||
|
@ -375,14 +385,14 @@ export default class RoomView extends LoggedView {
|
||||||
}
|
}
|
||||||
if (room.archived || this.isReadOnly()) {
|
if (room.archived || this.isReadOnly()) {
|
||||||
return (
|
return (
|
||||||
<View style={styles.readOnly}>
|
<View style={styles.readOnly} key='room-view-read-only'>
|
||||||
<Text>{I18n.t('This_room_is_read_only')}</Text>
|
<Text>{I18n.t('This_room_is_read_only')}</Text>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (this.isBlocked()) {
|
if (this.isBlocked()) {
|
||||||
return (
|
return (
|
||||||
<View style={styles.blockedOrBlocker}>
|
<View style={styles.readOnly} key='room-view-block'>
|
||||||
<Text>{I18n.t('This_room_is_blocked')}</Text>
|
<Text>{I18n.t('This_room_is_blocked')}</Text>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
|
@ -32,10 +32,9 @@ export default StyleSheet.create({
|
||||||
color: '#ccc'
|
color: '#ccc'
|
||||||
},
|
},
|
||||||
readOnly: {
|
readOnly: {
|
||||||
padding: 10
|
justifyContent: 'flex-end',
|
||||||
},
|
alignItems: 'center',
|
||||||
blockedOrBlocker: {
|
marginVertical: 15
|
||||||
padding: 10
|
|
||||||
},
|
},
|
||||||
reactionPickerContainer: {
|
reactionPickerContainer: {
|
||||||
// width: width - 20,
|
// width: width - 20,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { View, FlatList } from 'react-native';
|
import { View, FlatList, Text } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import SafeAreaView from 'react-native-safe-area-view';
|
import SafeAreaView from 'react-native-safe-area-view';
|
||||||
|
|
||||||
|
@ -11,20 +11,20 @@ import styles from './styles';
|
||||||
import Markdown from '../../containers/message/Markdown';
|
import Markdown from '../../containers/message/Markdown';
|
||||||
import debounce from '../../utils/debounce';
|
import debounce from '../../utils/debounce';
|
||||||
import RocketChat from '../../lib/rocketchat';
|
import RocketChat from '../../lib/rocketchat';
|
||||||
import buildMessage from '../../lib/methods/helpers/buildMessage';
|
import Message from '../../containers/message/Message';
|
||||||
import Message from '../../containers/message';
|
|
||||||
import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
||||||
import log from '../../utils/log';
|
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import { DEFAULT_HEADER } from '../../constants/headerOptions';
|
import { DEFAULT_HEADER } from '../../constants/headerOptions';
|
||||||
|
import database from '../../lib/realm';
|
||||||
|
|
||||||
@connect(state => ({
|
@connect(state => ({
|
||||||
|
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '',
|
||||||
|
customEmojis: state.customEmojis,
|
||||||
user: {
|
user: {
|
||||||
id: state.login.user && state.login.user.id,
|
id: state.login.user && state.login.user.id,
|
||||||
username: state.login.user && state.login.user.username,
|
username: state.login.user && state.login.user.username,
|
||||||
token: state.login.user && state.login.user.token
|
token: state.login.user && state.login.user.token
|
||||||
},
|
}
|
||||||
baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
|
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
/** @extends React.Component */
|
||||||
export default class SearchMessagesView extends LoggedView {
|
export default class SearchMessagesView extends LoggedView {
|
||||||
|
@ -43,18 +43,19 @@ export default class SearchMessagesView extends LoggedView {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
rid: PropTypes.string,
|
rid: PropTypes.string,
|
||||||
componentId: PropTypes.string,
|
|
||||||
user: PropTypes.object,
|
user: PropTypes.object,
|
||||||
baseUrl: PropTypes.string
|
baseUrl: PropTypes.string,
|
||||||
|
customEmojis: PropTypes.object
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('SearchMessagesView', props);
|
super('SearchMessagesView', props);
|
||||||
this.limit = 0;
|
this.rooms = database.objects('subscriptions').filtered('rid = $0', props.rid);
|
||||||
this.state = {
|
this.state = {
|
||||||
|
loading: false,
|
||||||
|
room: this.rooms[0],
|
||||||
messages: [],
|
messages: [],
|
||||||
searching: false,
|
searchText: ''
|
||||||
loadingMore: false
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,100 +64,88 @@ export default class SearchMessagesView extends LoggedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.onChangeSearch.stop();
|
this.search.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeSearch = debounce((search) => {
|
// eslint-disable-next-line react/sort-comp
|
||||||
const { searching } = this.state;
|
search = debounce(async(searchText) => {
|
||||||
|
const { room } = this.state;
|
||||||
|
this.setState({ searchText, loading: true, messages: [] });
|
||||||
|
|
||||||
this.searchText = search;
|
try {
|
||||||
this.limit = 0;
|
const result = await RocketChat.searchMessages(room.rid, searchText);
|
||||||
if (!searching) {
|
if (result.success) {
|
||||||
this.setState({ searching: true });
|
this.setState({
|
||||||
|
messages: result.messages || [],
|
||||||
|
loading: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.setState({ loading: false });
|
||||||
|
console.log('SearchMessagesView -> search -> catch -> error', error);
|
||||||
}
|
}
|
||||||
this.search();
|
|
||||||
}, 1000)
|
}, 1000)
|
||||||
|
|
||||||
search = async() => {
|
renderEmpty = () => (
|
||||||
const { rid } = this.props;
|
<View style={styles.listEmptyContainer}>
|
||||||
|
<Text>{I18n.t('No_results_found')}</Text>
|
||||||
if (this._cancel) {
|
</View>
|
||||||
this._cancel('cancel');
|
)
|
||||||
}
|
|
||||||
const cancel = new Promise((r, reject) => this._cancel = reject);
|
|
||||||
let messages = [];
|
|
||||||
try {
|
|
||||||
const result = await Promise.race([RocketChat.messageSearch(this.searchText, rid, this.limit), cancel]);
|
|
||||||
messages = result.message.docs.map(message => buildMessage(message));
|
|
||||||
this.setState({ messages, searching: false, loadingMore: false });
|
|
||||||
} catch (e) {
|
|
||||||
this._cancel = null;
|
|
||||||
if (e !== 'cancel') {
|
|
||||||
return this.setState({ searching: false, loadingMore: false });
|
|
||||||
}
|
|
||||||
log('SearchMessagesView.search', e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
moreData = () => {
|
|
||||||
const { loadingMore, messages } = this.state;
|
|
||||||
if (messages.length < this.limit) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.searchText && !loadingMore) {
|
|
||||||
this.setState({ loadingMore: true });
|
|
||||||
this.limit += 20;
|
|
||||||
this.search();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderItem = ({ item }) => {
|
renderItem = ({ item }) => {
|
||||||
const { user } = this.props;
|
const { user, customEmojis, baseUrl } = this.props;
|
||||||
return (
|
return (
|
||||||
<Message
|
<Message
|
||||||
item={item}
|
|
||||||
style={styles.message}
|
style={styles.message}
|
||||||
reactions={item.reactions}
|
customEmojis={customEmojis}
|
||||||
|
baseUrl={baseUrl}
|
||||||
user={user}
|
user={user}
|
||||||
customTimeFormat='MMMM Do YYYY, h:mm:ss a'
|
author={item.u}
|
||||||
onReactionPress={async(emoji) => {
|
ts={item.ts}
|
||||||
try {
|
msg={item.msg}
|
||||||
await RocketChat.setReaction(emoji, item._id);
|
attachments={item.attachments || []}
|
||||||
this.search();
|
timeFormat='MMM Do YYYY, h:mm:ss a'
|
||||||
this.forceUpdate();
|
edited={!!item.editedAt}
|
||||||
} catch (e) {
|
header
|
||||||
log('SearchMessagesView.onReactionPress', e);
|
/>
|
||||||
}
|
);
|
||||||
}}
|
}
|
||||||
|
|
||||||
|
renderList = () => {
|
||||||
|
const { messages, loading, searchText } = this.state;
|
||||||
|
|
||||||
|
if (!loading && messages.length === 0 && searchText.length) {
|
||||||
|
return this.renderEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FlatList
|
||||||
|
data={messages}
|
||||||
|
renderItem={this.renderItem}
|
||||||
|
style={styles.list}
|
||||||
|
keyExtractor={item => item._id}
|
||||||
|
onEndReached={this.load}
|
||||||
|
ListFooterComponent={loading ? <RCActivityIndicator /> : null}
|
||||||
|
{...scrollPersistTaps}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { searching, loadingMore, messages } = this.state;
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={styles.container} testID='search-messages-view' forceInset={{ bottom: 'never' }}>
|
<SafeAreaView style={styles.container} testID='search-messages-view' forceInset={{ bottom: 'never' }}>
|
||||||
<View style={styles.searchContainer}>
|
<View style={styles.searchContainer}>
|
||||||
<RCTextInput
|
<RCTextInput
|
||||||
inputRef={(e) => { this.name = e; }}
|
inputRef={(e) => { this.name = e; }}
|
||||||
label={I18n.t('Search')}
|
label={I18n.t('Search')}
|
||||||
onChangeText={this.onChangeSearch}
|
onChangeText={this.search}
|
||||||
placeholder={I18n.t('Search_Messages')}
|
placeholder={I18n.t('Search_Messages')}
|
||||||
testID='search-message-view-input'
|
testID='search-message-view-input'
|
||||||
/>
|
/>
|
||||||
<Markdown msg={I18n.t('You_can_search_using_RegExp_eg')} username='' baseUrl='' customEmojis={{}} />
|
<Markdown msg={I18n.t('You_can_search_using_RegExp_eg')} username='' baseUrl='' customEmojis={{}} />
|
||||||
<View style={styles.divider} />
|
<View style={styles.divider} />
|
||||||
</View>
|
</View>
|
||||||
<FlatList
|
{this.renderList()}
|
||||||
data={messages}
|
|
||||||
renderItem={this.renderItem}
|
|
||||||
style={styles.list}
|
|
||||||
keyExtractor={item => item._id}
|
|
||||||
onEndReached={this.moreData}
|
|
||||||
ListHeaderComponent={searching ? <RCActivityIndicator /> : null}
|
|
||||||
ListFooterComponent={loadingMore ? <RCActivityIndicator /> : null}
|
|
||||||
{...scrollPersistTaps}
|
|
||||||
/>
|
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,9 @@ export default StyleSheet.create({
|
||||||
transform: [{ scaleY: 1 }]
|
transform: [{ scaleY: 1 }]
|
||||||
},
|
},
|
||||||
divider: {
|
divider: {
|
||||||
|
width: '100%',
|
||||||
height: StyleSheet.hairlineWidth,
|
height: StyleSheet.hairlineWidth,
|
||||||
borderColor: '#ddd',
|
backgroundColor: '#E7EBF2',
|
||||||
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
||||||
marginVertical: 20
|
marginVertical: 20
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -105,7 +105,7 @@ export default class SnippetedMessagesView extends LoggedView {
|
||||||
style={styles.message}
|
style={styles.message}
|
||||||
reactions={item.reactions}
|
reactions={item.reactions}
|
||||||
user={user}
|
user={user}
|
||||||
customTimeFormat='MMMM Do YYYY, h:mm:ss a'
|
customTimeFormat='MMM Do YYYY, h:mm:ss a'
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,32 +4,29 @@ import { FlatList, View, Text } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import ActionSheet from 'react-native-actionsheet';
|
import ActionSheet from 'react-native-actionsheet';
|
||||||
import SafeAreaView from 'react-native-safe-area-view';
|
import SafeAreaView from 'react-native-safe-area-view';
|
||||||
|
import equal from 'deep-equal';
|
||||||
|
|
||||||
import { openStarredMessages as openStarredMessagesAction, closeStarredMessages as closeStarredMessagesAction } from '../../actions/starredMessages';
|
|
||||||
import { toggleStarRequest as toggleStarRequestAction } from '../../actions/messages';
|
|
||||||
import LoggedView from '../View';
|
import LoggedView from '../View';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import Message from '../../containers/message';
|
import Message from '../../containers/message/Message';
|
||||||
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import { DEFAULT_HEADER } from '../../constants/headerOptions';
|
import { DEFAULT_HEADER } from '../../constants/headerOptions';
|
||||||
|
import RocketChat from '../../lib/rocketchat';
|
||||||
|
import database from '../../lib/realm';
|
||||||
|
|
||||||
const STAR_INDEX = 0;
|
const STAR_INDEX = 0;
|
||||||
const CANCEL_INDEX = 1;
|
const CANCEL_INDEX = 1;
|
||||||
const options = [I18n.t('Unstar'), I18n.t('Cancel')];
|
const options = [I18n.t('Unstar'), I18n.t('Cancel')];
|
||||||
|
|
||||||
@connect(state => ({
|
@connect(state => ({
|
||||||
messages: state.starredMessages.messages,
|
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '',
|
||||||
ready: state.starredMessages.ready,
|
customEmojis: state.customEmojis,
|
||||||
user: {
|
user: {
|
||||||
id: state.login.user && state.login.user.id,
|
id: state.login.user && state.login.user.id,
|
||||||
username: state.login.user && state.login.user.username,
|
username: state.login.user && state.login.user.username,
|
||||||
token: state.login.user && state.login.user.token
|
token: state.login.user && state.login.user.token
|
||||||
}
|
}
|
||||||
}), dispatch => ({
|
|
||||||
openStarredMessages: (rid, limit) => dispatch(openStarredMessagesAction(rid, limit)),
|
|
||||||
closeStarredMessages: () => dispatch(closeStarredMessagesAction()),
|
|
||||||
toggleStarRequest: message => dispatch(toggleStarRequestAction(message))
|
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
/** @extends React.Component */
|
||||||
export default class StarredMessagesView extends LoggedView {
|
export default class StarredMessagesView extends LoggedView {
|
||||||
|
@ -48,38 +45,27 @@ export default class StarredMessagesView extends LoggedView {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
rid: PropTypes.string,
|
rid: PropTypes.string,
|
||||||
messages: PropTypes.array,
|
|
||||||
ready: PropTypes.bool,
|
|
||||||
user: PropTypes.object,
|
user: PropTypes.object,
|
||||||
openStarredMessages: PropTypes.func,
|
baseUrl: PropTypes.string,
|
||||||
closeStarredMessages: PropTypes.func,
|
customEmojis: PropTypes.object
|
||||||
toggleStarRequest: PropTypes.func
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('StarredMessagesView', props);
|
super('StarredMessagesView', props);
|
||||||
|
this.rooms = database.objects('subscriptions').filtered('rid = $0', props.rid);
|
||||||
this.state = {
|
this.state = {
|
||||||
message: {},
|
loading: false,
|
||||||
loading: true,
|
room: this.rooms[0],
|
||||||
loadingMore: false
|
messages: []
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.limit = 20;
|
|
||||||
this.load();
|
this.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
const { ready } = this.props;
|
return !equal(this.state, nextState);
|
||||||
if (nextProps.ready && nextProps.ready !== ready) {
|
|
||||||
this.setState({ loading: false, loadingMore: false });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
const { closeStarredMessages } = this.props;
|
|
||||||
closeStarredMessages();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onLongPress = (message) => {
|
onLongPress = (message) => {
|
||||||
|
@ -90,33 +76,57 @@ export default class StarredMessagesView extends LoggedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleActionPress = (actionIndex) => {
|
handleActionPress = (actionIndex) => {
|
||||||
const { message } = this.state;
|
|
||||||
const { toggleStarRequest } = this.props;
|
|
||||||
|
|
||||||
switch (actionIndex) {
|
switch (actionIndex) {
|
||||||
case STAR_INDEX:
|
case STAR_INDEX:
|
||||||
toggleStarRequest(message);
|
this.unStar();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
load = () => {
|
unStar = async() => {
|
||||||
const { rid, openStarredMessages } = this.props;
|
const { message } = this.state;
|
||||||
openStarredMessages(rid, this.limit);
|
try {
|
||||||
|
const result = await RocketChat.toggleStarMessage(message);
|
||||||
|
if (result.success) {
|
||||||
|
this.setState(prevState => ({
|
||||||
|
messages: prevState.messages.filter(item => item._id !== message._id)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log('StarredMessagesView -> unStar -> catch -> error', error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
moreData = () => {
|
load = async() => {
|
||||||
const { loadingMore } = this.state;
|
const {
|
||||||
const { messages } = this.props;
|
messages, total, loading, room
|
||||||
if (messages.length < this.limit) {
|
} = this.state;
|
||||||
|
const { user } = this.props;
|
||||||
|
if (messages.length === total || loading) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!loadingMore) {
|
|
||||||
this.setState({ loadingMore: true });
|
this.setState({ loading: true });
|
||||||
this.limit += 20;
|
|
||||||
this.load();
|
try {
|
||||||
|
const result = await RocketChat.getMessages(
|
||||||
|
room.rid,
|
||||||
|
room.t,
|
||||||
|
{ 'starred._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('StarredMessagesView -> load -> catch -> error', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,24 +137,29 @@ export default class StarredMessagesView extends LoggedView {
|
||||||
)
|
)
|
||||||
|
|
||||||
renderItem = ({ item }) => {
|
renderItem = ({ item }) => {
|
||||||
const { user } = this.props;
|
const { user, customEmojis, baseUrl } = this.props;
|
||||||
return (
|
return (
|
||||||
<Message
|
<Message
|
||||||
item={item}
|
|
||||||
style={styles.message}
|
style={styles.message}
|
||||||
reactions={item.reactions}
|
customEmojis={customEmojis}
|
||||||
|
baseUrl={baseUrl}
|
||||||
user={user}
|
user={user}
|
||||||
customTimeFormat='MMMM Do YYYY, h:mm:ss a'
|
author={item.u}
|
||||||
onLongPress={this.onLongPress}
|
ts={item.ts}
|
||||||
|
msg={item.msg}
|
||||||
|
attachments={item.attachments || []}
|
||||||
|
timeFormat='MMM Do YYYY, h:mm:ss a'
|
||||||
|
edited={!!item.editedAt}
|
||||||
|
header
|
||||||
|
onLongPress={() => this.onLongPress(item)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { loading, loadingMore } = this.state;
|
const { messages, loading } = this.state;
|
||||||
const { messages, ready } = this.props;
|
|
||||||
|
|
||||||
if (ready && messages.length === 0) {
|
if (!loading && messages.length === 0) {
|
||||||
return this.renderEmpty();
|
return this.renderEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,9 +170,8 @@ export default class StarredMessagesView extends LoggedView {
|
||||||
renderItem={this.renderItem}
|
renderItem={this.renderItem}
|
||||||
style={styles.list}
|
style={styles.list}
|
||||||
keyExtractor={item => item._id}
|
keyExtractor={item => item._id}
|
||||||
onEndReached={this.moreData}
|
onEndReached={this.load}
|
||||||
ListHeaderComponent={loading ? <RCActivityIndicator /> : null}
|
ListFooterComponent={loading ? <RCActivityIndicator /> : null}
|
||||||
ListFooterComponent={loadingMore ? <RCActivityIndicator /> : null}
|
|
||||||
/>
|
/>
|
||||||
<ActionSheet
|
<ActionSheet
|
||||||
ref={o => this.actionSheet = o}
|
ref={o => this.actionSheet = o}
|
||||||
|
|
Loading…
Reference in New Issue