[FIX] Handle deleted messages (#466)
* [FIX] Handle deleted messages * Fix rest error * Fix some connection issues
This commit is contained in:
parent
d6c6ac4ae8
commit
d5a4ead888
|
@ -59,7 +59,7 @@ jobs:
|
|||
command: |
|
||||
brew update
|
||||
brew tap wix/brew
|
||||
brew install applesimutils
|
||||
brew install wix/brew/applesimutils
|
||||
|
||||
- run:
|
||||
name: Install NPM modules
|
||||
|
|
|
@ -185,11 +185,14 @@ export default class Socket extends EventEmitter {
|
|||
if (ignore) {
|
||||
return;
|
||||
}
|
||||
const cancel = this.ddp.once('disconnected', reject);
|
||||
const cancel = this.once('disconnected', () => {
|
||||
this.removeListener('disconnected', cancel);
|
||||
reject();
|
||||
});
|
||||
this.ddp.once(id, (data) => {
|
||||
// console.log(data);
|
||||
this.lastping = new Date();
|
||||
this.ddp.removeListener('disconnected', cancel);
|
||||
this.removeListener('disconnected', cancel);
|
||||
return (data.error ? reject(data.error) : resolve({ id, ...data }));
|
||||
});
|
||||
});
|
||||
|
@ -273,7 +276,7 @@ export default class Socket extends EventEmitter {
|
|||
if (this._timer || this.forceDisconnect) {
|
||||
return;
|
||||
}
|
||||
this._close();
|
||||
// this._close();
|
||||
this._logged = false;
|
||||
|
||||
this._timer = setTimeout(async() => {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { post } from './helpers/rest';
|
||||
import database from '../realm';
|
||||
import log from '../../utils/log';
|
||||
import store from '../createStore';
|
||||
|
||||
// TODO: api fix
|
||||
const ddpTypes = {
|
||||
|
@ -12,7 +13,8 @@ const restTypes = {
|
|||
|
||||
async function canOpenRoomREST({ type, rid }) {
|
||||
try {
|
||||
const { token, id } = this.ddp._login;
|
||||
const { user } = store.getState().login;
|
||||
const { token, id } = user;
|
||||
const server = this.ddp.url.replace(/^ws/, 'http');
|
||||
await post({ token, id, server }, `${ restTypes[type] }.open`, { roomId: rid });
|
||||
return true;
|
||||
|
@ -50,7 +52,7 @@ export default async function canOpenRoom({ rid, path }) {
|
|||
|
||||
try {
|
||||
// eslint-disable-next-line
|
||||
const data = await (this.ddp && this.ddp.status && false ? canOpenRoomDDP.call(this, { rid, type, name }) : canOpenRoomREST.call(this, { type, rid }));
|
||||
const data = await (this.ddp && this.ddp.status ? canOpenRoomDDP.call(this, { rid, type, name }) : canOpenRoomREST.call(this, { type, rid }));
|
||||
return data;
|
||||
} catch (e) {
|
||||
log('canOpenRoom', e);
|
||||
|
|
|
@ -15,6 +15,11 @@ const getLastMessage = () => {
|
|||
|
||||
export default async function() {
|
||||
try {
|
||||
if (!this.ddp) {
|
||||
// TODO: should implement loop or get from rest?
|
||||
return;
|
||||
}
|
||||
|
||||
const lastMessage = getLastMessage();
|
||||
let emojis = await this.ddp.call('listEmojiCustom');
|
||||
emojis = emojis.filter(emoji => !lastMessage || emoji._updatedAt > lastMessage);
|
||||
|
|
|
@ -11,6 +11,11 @@ const getLastUpdate = () => {
|
|||
|
||||
export default async function() {
|
||||
try {
|
||||
if (!this.ddp) {
|
||||
// TODO: should implement loop or get from rest?
|
||||
return;
|
||||
}
|
||||
|
||||
const lastUpdate = getLastUpdate();
|
||||
const result = await (!lastUpdate ? this.ddp.call('permissions/get') : this.ddp.call('permissions/get', new Date(lastUpdate)));
|
||||
const permissions = (result.update || result).filter(permission => defaultPermissions.includes(permission._id));
|
||||
|
|
|
@ -5,6 +5,7 @@ import { get } from './helpers/rest';
|
|||
import mergeSubscriptionsRooms, { merge } from './helpers/mergeSubscriptionsRooms';
|
||||
import database from '../realm';
|
||||
import log from '../../utils/log';
|
||||
import store from '../createStore';
|
||||
|
||||
const lastMessage = () => {
|
||||
const message = database
|
||||
|
@ -14,9 +15,9 @@ const lastMessage = () => {
|
|||
};
|
||||
|
||||
const getRoomRest = async function() {
|
||||
const { ddp } = this;
|
||||
const updatedSince = lastMessage();
|
||||
const { token, id } = ddp._login;
|
||||
const { user } = store.getState().login;
|
||||
const { token, id } = user;
|
||||
const server = this.ddp.url.replace(/^ws/, 'http');
|
||||
const [subscriptions, rooms] = await Promise.all([get({ token, id, server }, 'subscriptions.get', { updatedSince }), get({ token, id, server }, 'rooms.get', { updatedSince })]);
|
||||
return mergeSubscriptionsRooms(subscriptions, rooms);
|
||||
|
@ -39,7 +40,7 @@ export default async function() {
|
|||
return new Promise(async(resolve, reject) => {
|
||||
try {
|
||||
// eslint-disable-next-line
|
||||
const { subscriptions, rooms } = await (this.ddp.status && false ? getRoomDpp.apply(this) : getRoomRest.apply(this));
|
||||
const { subscriptions, rooms } = await (this.ddp && this.ddp.status ? getRoomDpp.apply(this) : getRoomRest.apply(this));
|
||||
|
||||
const data = rooms.map(room => ({ room, sub: database.objects('subscriptions').filtered('rid == $0', room._id) }));
|
||||
|
||||
|
|
|
@ -20,6 +20,11 @@ function updateServer(param) {
|
|||
|
||||
export default async function() {
|
||||
try {
|
||||
if (!this.ddp) {
|
||||
// TODO: should implement loop or get from rest?
|
||||
return;
|
||||
}
|
||||
|
||||
const lastUpdate = getLastUpdate();
|
||||
const fetchNewSettings = lastUpdate < settingsUpdatedAt;
|
||||
const result = await ((!lastUpdate || fetchNewSettings) ? this.ddp.call('public-settings/get') : this.ddp.call('public-settings/get', new Date(lastUpdate)));
|
||||
|
|
|
@ -2,7 +2,7 @@ import toQuery from './toQuery';
|
|||
|
||||
|
||||
const handleSuccess = (msg) => {
|
||||
if (msg.success !== undefined && !msg.success) {
|
||||
if ((msg.success !== undefined && !msg.success) || (msg.status && msg.status === 'error')) {
|
||||
return Promise.reject(msg);
|
||||
}
|
||||
return msg;
|
||||
|
|
|
@ -4,6 +4,7 @@ import { get } from './helpers/rest';
|
|||
import buildMessage from './helpers/buildMessage';
|
||||
import database from '../realm';
|
||||
import log from '../../utils/log';
|
||||
import store from '../createStore';
|
||||
|
||||
// TODO: api fix
|
||||
const types = {
|
||||
|
@ -11,7 +12,8 @@ const types = {
|
|||
};
|
||||
|
||||
async function loadMessagesForRoomRest({ rid: roomId, latest, t }) {
|
||||
const { token, id } = this.ddp._login;
|
||||
const { user } = store.getState().login;
|
||||
const { token, id } = user;
|
||||
const server = this.ddp.url.replace(/^ws/, 'http');
|
||||
const data = await get({ token, id, server }, `${ types[t] }.history`, { roomId, latest });
|
||||
if (!data || data.status === 'error') {
|
||||
|
@ -36,11 +38,9 @@ async function loadMessagesForRoomDDP(...args) {
|
|||
|
||||
export default async function loadMessagesForRoom(...args) {
|
||||
const { database: db } = database;
|
||||
|
||||
return new Promise(async(resolve, reject) => {
|
||||
try {
|
||||
// eslint-disable-next-line
|
||||
const data = (await (this.ddp.status ? loadMessagesForRoomDDP.call(this, ...args) : loadMessagesForRoomRest.call(this, ...args))).map(buildMessage);
|
||||
const data = (await (this.ddp && this.ddp.status ? loadMessagesForRoomDDP.call(this, ...args) : loadMessagesForRoomRest.call(this, ...args))).map(buildMessage);
|
||||
|
||||
if (data && data.length) {
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
|
|
|
@ -4,56 +4,53 @@ import { get } from './helpers/rest';
|
|||
import buildMessage from './helpers/buildMessage';
|
||||
import database from '../realm';
|
||||
import log from '../../utils/log';
|
||||
import store from '../createStore';
|
||||
|
||||
async function loadMissedMessagesRest({ rid: roomId, lastOpen: lastUpdate }) {
|
||||
const { token, id } = this.ddp._login;
|
||||
const { user } = store.getState().login;
|
||||
const { token, id } = user;
|
||||
const server = this.ddp.url.replace(/^ws/, 'http');
|
||||
const { result } = await get({ token, id, server }, 'chat.syncMessages', { roomId, lastUpdate });
|
||||
// TODO: api fix
|
||||
if (!result) {
|
||||
return [];
|
||||
}
|
||||
return result.updated || result.messages;
|
||||
return result;
|
||||
}
|
||||
|
||||
async function loadMissedMessagesDDP(...args) {
|
||||
const [{ rid, lastOpen: lastUpdate }] = args;
|
||||
|
||||
try {
|
||||
const data = await this.ddp.call('messages/get', rid, { lastUpdate: new Date(lastUpdate) });
|
||||
return data.updated || data.messages;
|
||||
const result = await this.ddp.call('messages/get', rid, { lastUpdate: new Date(lastUpdate) });
|
||||
return result;
|
||||
} catch (e) {
|
||||
return loadMissedMessagesRest.call(this, ...args);
|
||||
}
|
||||
|
||||
// }
|
||||
// if (cb) {
|
||||
// cb({ end: data && data.messages.length < 20 });
|
||||
// }
|
||||
// return data.message;
|
||||
// }, (err) => {
|
||||
// if (err) {
|
||||
// if (cb) {
|
||||
// cb({ end: true });
|
||||
// }
|
||||
// return Promise.reject(err);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
export default async function(...args) {
|
||||
export default async function loadMissedMessages(...args) {
|
||||
const { database: db } = database;
|
||||
return new Promise(async(resolve, reject) => {
|
||||
try {
|
||||
// eslint-disable-next-line
|
||||
const data = (await (this.ddp.status ? loadMissedMessagesDDP.call(this, ...args) : loadMissedMessagesRest.call(this, ...args)));
|
||||
const data = (await (this.ddp && this.ddp.status ? loadMissedMessagesDDP.call(this, ...args) : loadMissedMessagesRest.call(this, ...args)));
|
||||
|
||||
if (data) {
|
||||
data.forEach(buildMessage);
|
||||
return InteractionManager.runAfterInteractions(() => {
|
||||
db.write(() => data.forEach(message => db.create('messages', message, true)));
|
||||
resolve(data);
|
||||
});
|
||||
if (data.updated && data.updated.length) {
|
||||
const { updated } = data;
|
||||
updated.forEach(buildMessage);
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
db.write(() => updated.forEach(message => db.create('messages', message, true)));
|
||||
resolve(updated);
|
||||
});
|
||||
}
|
||||
if (data.deleted && data.deleted.length) {
|
||||
const { deleted } = data;
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
db.write(() => {
|
||||
deleted.forEach((m) => {
|
||||
const message = database.objects('messages').filtered('_id = $0', m._id);
|
||||
database.delete(message);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
resolve([]);
|
||||
} catch (e) {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { post } from './helpers/rest';
|
||||
import database from '../realm';
|
||||
import log from '../../utils/log';
|
||||
import store from '../createStore';
|
||||
|
||||
const readMessagesREST = function readMessagesREST(rid) {
|
||||
const { token, id } = this.ddp._login;
|
||||
const { user } = store.getState().login;
|
||||
const { token, id } = user;
|
||||
const server = this.ddp.url.replace(/^ws/, 'http');
|
||||
return post({ token, id, server }, 'subscriptions.read', { rid });
|
||||
};
|
||||
|
@ -20,7 +22,7 @@ export default async function readMessages(rid) {
|
|||
const { database: db } = database;
|
||||
try {
|
||||
// eslint-disable-next-line
|
||||
const data = await (this.ddp.status && false ? readMessagesDDP.call(this, rid) : readMessagesREST.call(this, rid));
|
||||
const data = await (this.ddp && this.ddp.status ? readMessagesDDP.call(this, rid) : readMessagesREST.call(this, rid));
|
||||
const [subscription] = db.objects('subscriptions').filtered('rid = $0', rid);
|
||||
db.write(() => {
|
||||
subscription.open = true;
|
||||
|
|
|
@ -46,7 +46,7 @@ function sendMessageByDDP(message) {
|
|||
export async function _sendMessageCall(message) {
|
||||
try {
|
||||
// eslint-disable-next-line
|
||||
const data = await (this.ddp.status && false ? sendMessageByDDP.call(this, message) : sendMessageByRest.call(this, message));
|
||||
const data = await (this.ddp && this.ddp.status ? sendMessageByDDP.call(this, message) : sendMessageByRest.call(this, message));
|
||||
return data;
|
||||
} catch (e) {
|
||||
database.write(() => {
|
||||
|
|
|
@ -7,7 +7,8 @@ import log from '../../../utils/log';
|
|||
|
||||
const subscribe = (ddp, rid) => Promise.all([
|
||||
ddp.subscribe('stream-room-messages', rid, false),
|
||||
ddp.subscribe('stream-notify-room', `${ rid }/typing`, false)
|
||||
ddp.subscribe('stream-notify-room', `${ rid }/typing`, false),
|
||||
ddp.subscribe('stream-notify-room', `${ rid }/deleteMessage`, false)
|
||||
]);
|
||||
const unsubscribe = subscriptions => subscriptions.forEach(sub => sub.unsubscribe().catch((e) => {
|
||||
log('unsubscribeRoom', e);
|
||||
|
|
|
@ -171,8 +171,6 @@ const RocketChat = {
|
|||
|
||||
this.ddp.on('background', () => this.getRooms().catch(e => log('background getRooms', e)));
|
||||
|
||||
this.ddp.on('disconnected', () => console.log('disconnected'));
|
||||
|
||||
this.ddp.on('logged', protectedFunction((user) => {
|
||||
this.loginSuccess(user);
|
||||
this.getRooms().catch(e => log('logged getRooms', e));
|
||||
|
@ -184,7 +182,7 @@ const RocketChat = {
|
|||
|
||||
this.ddp.on('disconnected', protectedFunction(() => {
|
||||
reduxStore.dispatch(disconnect());
|
||||
console.warn(this.ddp);
|
||||
console.log('disconnected', this.ddp);
|
||||
}));
|
||||
|
||||
this.ddp.on('stream-room-messages', (ddpMessage) => {
|
||||
|
@ -195,10 +193,17 @@ const RocketChat = {
|
|||
|
||||
this.ddp.on('stream-notify-room', protectedFunction((ddpMessage) => {
|
||||
const [_rid, ev] = ddpMessage.fields.eventName.split('/');
|
||||
if (ev !== 'typing') {
|
||||
return;
|
||||
if (ev === 'typing') {
|
||||
reduxStore.dispatch(someoneTyping({ _rid, username: ddpMessage.fields.args[0], typing: ddpMessage.fields.args[1] }));
|
||||
} else if (ev === 'deleteMessage') {
|
||||
database.write(() => {
|
||||
if (ddpMessage && ddpMessage.fields && ddpMessage.fields.args.length > 0) {
|
||||
const { _id } = ddpMessage.fields.args[0];
|
||||
const message = database.objects('messages').filtered('_id = $0', _id);
|
||||
database.delete(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
return reduxStore.dispatch(someoneTyping({ _rid, username: ddpMessage.fields.args[0], typing: ddpMessage.fields.args[1] }));
|
||||
}));
|
||||
|
||||
this.ddp.on('rocketchat_starred_message', protectedFunction((ddpMessage) => {
|
||||
|
|
|
@ -21,14 +21,13 @@ const restore = function* restore() {
|
|||
|
||||
const currentServer = yield call([AsyncStorage, 'getItem'], 'currentServer');
|
||||
if (currentServer) {
|
||||
yield put(selectServerRequest(currentServer));
|
||||
|
||||
const user = yield call([AsyncStorage, 'getItem'], `${ RocketChat.TOKEN_KEY }-${ currentServer }`);
|
||||
if (user) {
|
||||
const userParsed = JSON.parse(user);
|
||||
if (userParsed.language) {
|
||||
I18n.locale = userParsed.language;
|
||||
}
|
||||
yield put(selectServerRequest(currentServer));
|
||||
yield put(setUser(userParsed));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,8 +46,7 @@ export default StyleSheet.create({
|
|||
flexDirection: 'column'
|
||||
},
|
||||
loading: {
|
||||
flex: 1,
|
||||
marginVertical: 15
|
||||
flex: 1
|
||||
},
|
||||
imageBackground: {
|
||||
width: '100%',
|
||||
|
|
|
@ -3,7 +3,8 @@ import {
|
|||
View, Text, Animated, Easing, TouchableWithoutFeedback, TouchableOpacity, FlatList, Image, AsyncStorage
|
||||
} from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { connect, Provider } from 'react-redux';
|
||||
import { Navigation } from 'react-native-navigation';
|
||||
|
||||
import { toggleServerDropdown as toggleServerDropdownAction } from '../../actions/rooms';
|
||||
import { selectServerRequest as selectServerRequestAction } from '../../actions/server';
|
||||
|
@ -13,10 +14,13 @@ import database from '../../lib/realm';
|
|||
import Touch from '../../utils/touch';
|
||||
import RocketChat from '../../lib/rocketchat';
|
||||
import I18n from '../../i18n';
|
||||
import store from '../../lib/createStore';
|
||||
|
||||
const ROW_HEIGHT = 68;
|
||||
const ANIMATION_DURATION = 200;
|
||||
|
||||
let NewServerView = null;
|
||||
|
||||
@connect(state => ({
|
||||
closeServerDropdown: state.rooms.closeServerDropdown,
|
||||
server: state.server.server
|
||||
|
@ -111,6 +115,10 @@ export default class ServerDropdown extends Component {
|
|||
const token = await AsyncStorage.getItem(`${ RocketChat.TOKEN_KEY }-${ server }`);
|
||||
if (!token) {
|
||||
appStart();
|
||||
if (NewServerView == null) {
|
||||
NewServerView = require('../NewServerView').default;
|
||||
Navigation.registerComponent('NewServerView', () => NewServerView, store, Provider);
|
||||
}
|
||||
setTimeout(() => {
|
||||
navigator.push({
|
||||
screen: 'NewServerView',
|
||||
|
|
|
@ -14,6 +14,7 @@ async function navigateToRoomActions(type) {
|
|||
} else {
|
||||
room = `private${ data.random }`;
|
||||
}
|
||||
await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(10000);
|
||||
await element(by.id('rooms-list-view-search')).replaceText(room);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${ room }`))).toExist().withTimeout(60000);
|
||||
await element(by.id(`rooms-list-view-item-${ room }`)).tap();
|
||||
|
|
|
@ -14,7 +14,7 @@ async function navigateToRoomInfo(type) {
|
|||
}
|
||||
await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(10000);
|
||||
await element(by.id('rooms-list-view-search')).replaceText(room);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${ room }`))).toBeVisible().withTimeout(60000);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${ room }`))).toExist().withTimeout(60000);
|
||||
await element(by.id(`rooms-list-view-item-${ room }`)).tap();
|
||||
await waitFor(element(by.id('room-view'))).toBeVisible().withTimeout(2000);
|
||||
await element(by.id('room-view-header-actions')).tap();
|
||||
|
|
Loading…
Reference in New Issue