Use Rocket.Chat JS SDK (#481)

* JS SDK

* API working

* Multiple servers
This commit is contained in:
Diego Mello 2018-10-15 17:22:42 -03:00 committed by GitHub
parent 8db5723da8
commit 5a3ba40a9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 335 additions and 612 deletions

View File

@ -128,7 +128,8 @@ module.exports = {
"consistent-return": 0,
"global-require": "off",
"react-native/no-unused-styles": 2,
"react/jsx-one-expression-per-line": 0
"react/jsx-one-expression-per-line": 0,
"func-names": 0
},
"globals": {
"__DEV__": true

View File

@ -97,7 +97,7 @@ export default {
Allow_Reactions: 'Permitir reagir',
Alphabetical: 'Alfabético',
and_more: 'e mais',
and: 'a',
and: 'e',
announcement: 'anúncio',
Announcement: 'Anúncio',
ARCHIVE: 'ARQUIVAR',

View File

@ -1,338 +0,0 @@
import EJSON from 'ejson';
import { AppState } from 'react-native';
import debounce from '../utils/debounce';
import log from '../utils/log';
// import { AppState, NativeModules } from 'react-native';
// const { WebSocketModule, BlobManager } = NativeModules;
// class WS extends WebSocket {
// _close(code?: number, reason?: string): void {
// if (Platform.OS === 'android') {
// WebSocketModule.close(code, reason, this._socketId);
// } else {
// WebSocketModule.close(this._socketId);
// }
//
// if (BlobManager.isAvailable && this._binaryType === 'blob') {
// BlobManager.removeWebSocketHandler(this._socketId);
// }
// }
// }
class EventEmitter {
constructor() {
this.events = {};
}
on(event, listener) {
if (typeof this.events[event] !== 'object') {
this.events[event] = [];
}
this.events[event].push(listener);
return listener;
}
removeListener(event, listener) {
if (typeof this.events[event] === 'object') {
const idx = this.events[event].indexOf(listener);
if (idx > -1) {
this.events[event].splice(idx, 1);
}
if (this.events[event].length === 0) {
delete this.events[event];
}
}
}
emit(event, ...args) {
if (typeof this.events[event] === 'object') {
this.events[event].forEach((listener) => {
try {
listener.apply(this, args);
} catch (e) {
log('EventEmitter.emit', e);
}
});
}
}
once(event, listener) {
return this.on(event, function g(...args) {
this.removeListener(event, g);
listener.apply(this, args);
});
}
}
export default class Socket extends EventEmitter {
constructor(url, login) {
super();
this.state = 'active';
this.lastping = new Date();
this._login = login;
this.url = url;// .replace(/^http/, 'ws');
this.id = 0;
this.subscriptions = {};
this.ddp = new EventEmitter();
this._logged = false;
this.forceDisconnect = false;
this.connected = false;
const waitTimeout = () => setTimeout(() => {
// this.connection.ping();
this.send({ msg: 'ping' }).catch(e => log('ping', e));
this.timeout = setTimeout(() => this.reconnect(), 1000);
}, 40000);
const handlePing = () => {
this.lastping = new Date();
this.send({ msg: 'pong' }, true).catch(e => log('pong', e));
if (this.timeout) {
clearTimeout(this.timeout);
}
this.timeout = waitTimeout();
};
const handlePong = () => {
this.lastping = new Date();
if (this.timeout) {
clearTimeout(this.timeout);
}
this.timeout = waitTimeout();
};
AppState.addEventListener('change', async(nextAppState) => {
if (this.state && this.state.match(/inactive/) && nextAppState === 'active') {
try {
await this.send({ msg: 'ping' }, true);
// this.connection.ping();
} catch (e) {
this.reconnect();
}
}
if (this.state && this.state.match(/background/) && nextAppState === 'active') {
this.emit('background');
}
this.state = nextAppState;
});
this.on('pong', handlePong);
this.on('ping', handlePing);
this.on('result', data => this.ddp.emit(data.id, { id: data.id, result: data.result, error: data.error }));
this.on('ready', data => this.ddp.emit(data.subs[0], data));
// this.on('error', () => this.reconnect());
this.on('disconnected', debounce(() => this.reconnect(), 300));
this.on('logged', () => {
this._logged = true;
Object.keys(this.subscriptions || {}).forEach((key) => {
const { name, params } = this.subscriptions[key];
this.subscriptions[key].unsubscribe().catch(e => log('this.on(logged) unsub', e));
this.subscribe(name, ...params).catch(e => log('this.on(logged) sub', e));
});
});
this.on('open', async() => {
this._logged = false;
this.send({ msg: 'connect', version: '1', support: ['1', 'pre2', 'pre1'] }).catch(e => log('this.on(open)', e));
});
this._connect().catch(e => log('ddp.constructor._connect', e));
}
check() {
if (!this.lastping) {
return false;
}
if ((Math.abs(this.lastping.getTime() - new Date().getTime()) / 1000) > 50) {
return false;
}
return true;
}
async login(params) {
try {
this.emit('login', params);
const result = await this.call('login', params);
// this._login = { resume: result.token, ...result };
this._login = { resume: result.token, ...result, ...params };
this._logged = true;
// this.emit('logged', result);
this.emit('logged', this._login);
return result;
} catch (err) {
const error = { ...err };
if (/user not found/i.test(error.reason)) {
error.error = 1;
error.reason = 'User or Password incorrect';
error.message = 'User or Password incorrect';
}
this.emit('loginError', error);
return Promise.reject(error);
}
}
async send(obj, ignore) {
console.log('send', obj);
return new Promise((resolve, reject) => {
if (!this.connected) {
return reject();
}
this.id += 1;
const id = obj.id || `ddp-react-native-${ this.id }`;
// console.log('send', { ...obj, id });
this.connection.send(EJSON.stringify({ ...obj, id }));
if (ignore) {
return;
}
const cancel = this.once('disconnected', () => {
this.removeListener('disconnected', cancel);
reject();
});
this.ddp.once(id, (data) => {
// console.log(data);
this.lastping = new Date();
this.removeListener('disconnected', cancel);
return (data.error ? reject(data.error) : resolve({ id, ...data }));
});
});
}
get status() {
return this.connection && this.connection.readyState === 1 && this.check() && !!this._logged;
}
_close() {
try {
// this.connection && this.connection.readyState > 1 && this.connection.close && this.connection.close(300, 'disconnect');
if (this.connection && this.connection.close) {
this.connection.close();
delete this.connection;
}
} catch (e) {
// console.log(e);
}
}
_connect() {
return new Promise((resolve) => {
this.lastping = new Date();
this._close();
clearInterval(this.reconnect_timeout);
this.reconnect_timeout = setInterval(() => {
if (!this.connection || this.connection.readyState > 1 || !this.check()) {
this.reconnect();
}
}, 5000);
this.connection = new WebSocket(`${ this.url }/websocket`, null);
this.connection.onopen = async() => {
this.connected = true;
this.forceDisconnect = false;
this.emit('open');
resolve();
this.ddp.emit('open');
console.log(`Connected to: ${ this.url }`);
if (this._login) {
return this.login(this._login).catch(e => console.warn(e));
}
};
this.connection.onclose = debounce((e) => {
this.emit('disconnected', e);
this.connected = false;
}, 300);
this.connection.onmessage = (e) => {
try {
// console.log('received', e.data, e.target.readyState);
const data = EJSON.parse(e.data);
this.emit(data.msg, data);
return data.collection && this.emit(data.collection, data);
} catch (err) {
log('EJSON parse', err);
}
};
});
}
logout() {
this._login = null;
return this.call('logout')
.catch(e => log('logout', e))
.finally(() => this.subscriptions = {});
}
disconnect() {
this._logged = false;
this._login = null;
this.subscriptions = {};
this.forceDisconnect = true;
this._close();
if (this.timeout) {
clearTimeout(this.timeout);
}
}
async reconnect() {
if (this._timer || this.forceDisconnect) {
return;
}
// this._close();
this._logged = false;
this._timer = setTimeout(async() => {
delete this._timer;
try {
await this._connect();
} catch (e) {
log('ddp.reconnect._connect', e);
}
}, 1000);
}
call(method, ...params) {
return this.send({
msg: 'method', method, params
}).then(data => data.result || data.subs).catch((err) => {
log('DDP call Error', err);
if (err && /you've been logged out by the server/i.test(err.reason)) {
return this.emit('forbidden');
}
return Promise.reject(err);
});
}
unsubscribe(id) {
if (!this.subscriptions[id]) {
return Promise.reject(id);
}
delete this.subscriptions[id];
return this.send({
msg: 'unsub',
id
}).then(data => data.result || data.subs).catch((err) => {
log('DDP unsubscribe Error', err);
return Promise.reject(err);
});
}
subscribe(name, ...params) {
console.log(name, params);
return this.send({
msg: 'sub', name, params
}).then(({ id }) => {
const args = {
id,
name,
params,
unsubscribe: () => this.unsubscribe(id)
};
this.subscriptions[id] = args;
// console.log(args);
return args;
}).catch((err) => {
log('DDP subscribe Error', err);
return Promise.reject(err);
});
}
}

View File

@ -1,7 +1,7 @@
import { post } from './helpers/rest';
import * as SDK from '@rocket.chat/sdk';
import database from '../realm';
import log from '../../utils/log';
import store from '../createStore';
// TODO: api fix
const ddpTypes = {
@ -13,10 +13,7 @@ const restTypes = {
async function canOpenRoomREST({ type, rid }) {
try {
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 });
await SDK.api.post(`${ restTypes[type] }.open`, { roomId: rid });
return true;
} catch (error) {
// TODO: workround for 'already open for the sender' error
@ -30,7 +27,7 @@ async function canOpenRoomREST({ type, rid }) {
async function canOpenRoomDDP(...args) {
try {
const [{ type, name }] = args;
await this.ddp.call('getRoomByTypeAndName', ddpTypes[type], name);
await SDK.driver.asyncCall('getRoomByTypeAndName', ddpTypes[type], name);
return true;
} catch (error) {
if (error.isClientSafe) {
@ -51,8 +48,7 @@ export default async function canOpenRoom({ rid, path }) {
const [type, name] = path.split('/');
try {
// eslint-disable-next-line
const data = await (this.ddp && this.ddp.status ? canOpenRoomDDP.call(this, { rid, type, name }) : canOpenRoomREST.call(this, { type, rid }));
const data = await (SDK.driver.ddp ? canOpenRoomDDP.call(this, { rid, type, name }) : canOpenRoomREST.call(this, { type, rid }));
return data;
} catch (e) {
log('canOpenRoom', e);

View File

@ -1,7 +1,7 @@
import { InteractionManager } from 'react-native';
import * as SDK from '@rocket.chat/sdk';
import reduxStore from '../createStore';
// import { get } from './helpers/rest';
import database from '../realm';
import * as actions from '../../actions';
@ -12,16 +12,11 @@ const getLastMessage = () => {
return setting && setting._updatedAt;
};
// TODO: fix api (get emojis by date/version....)
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');
let emojis = await SDK.driver.asyncCall('listEmojiCustom');
emojis = emojis.filter(emoji => !lastMessage || emoji._updatedAt > lastMessage);
emojis = this._prepareEmojis(emojis);
InteractionManager.runAfterInteractions(() => database.write(() => {

View File

@ -1,4 +1,5 @@
import { InteractionManager } from 'react-native';
import * as SDK from '@rocket.chat/sdk';
import database from '../realm';
import log from '../../utils/log';
@ -11,13 +12,10 @@ 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 result = await (!lastUpdate
? SDK.driver.asyncCall('permissions/get')
: SDK.driver.asyncCall('permissions/get', new Date(lastUpdate)));
const permissions = (result.update || result).filter(permission => defaultPermissions.includes(permission._id));
permissions
.map((permission) => {
@ -27,9 +25,13 @@ export default async function() {
});
InteractionManager.runAfterInteractions(
() => database.write(
() => permissions.forEach(permission => database.create('permissions', permission, true))
)
() => database.write(() => permissions.forEach((permission) => {
try {
database.create('permissions', permission, true);
} catch (e) {
log('getPermissions create', e);
}
}))
);
} catch (e) {
log('getPermissions', e);

View File

@ -1,33 +1,30 @@
import { InteractionManager } from 'react-native';
import * as SDK from '@rocket.chat/sdk';
// import { showToast } from '../../utils/info';
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
.objects('subscriptions')
.sorted('roomUpdatedAt', true)[0];
return message && new Date(message.roomUpdatedAt);
return message && new Date(message.roomUpdatedAt).toISOString();
};
const getRoomRest = async function() {
const updatedSince = lastMessage();
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 })]);
const [subscriptions, rooms] = await (updatedSince
? Promise.all([SDK.api.get('subscriptions.get', { updatedSince }), SDK.api.get('rooms.get', { updatedSince })])
: Promise.all([SDK.api.get('subscriptions.get'), SDK.api.get('rooms.get')])
);
return mergeSubscriptionsRooms(subscriptions, rooms);
};
const getRoomDpp = async function() {
try {
const { ddp } = this;
const updatedSince = lastMessage();
const [subscriptions, rooms] = await Promise.all([ddp.call('subscriptions/get', updatedSince), ddp.call('rooms/get', updatedSince)]);
const [subscriptions, rooms] = await Promise.all([SDK.driver.asyncCall('subscriptions/get', updatedSince), SDK.driver.asyncCall('rooms/get', updatedSince)]);
return mergeSubscriptionsRooms(subscriptions, rooms);
} catch (e) {
return getRoomRest.apply(this);
@ -39,8 +36,7 @@ export default async function() {
return new Promise(async(resolve, reject) => {
try {
// eslint-disable-next-line
const { subscriptions, rooms } = await (this.ddp && this.ddp.status ? getRoomDpp.apply(this) : getRoomRest.apply(this));
const { subscriptions, rooms } = await (SDK.driver.ddp ? getRoomDpp.apply(this) : getRoomRest.apply(this));
const data = rooms.map(room => ({ room, sub: database.objects('subscriptions').filtered('rid == $0', room._id) }));

View File

@ -1,7 +1,7 @@
import { InteractionManager } from 'react-native';
import * as SDK from '@rocket.chat/sdk';
import reduxStore from '../createStore';
// import { get } from './helpers/rest';
import database from '../realm';
import * as actions from '../../actions';
import log from '../../utils/log';
@ -14,20 +14,22 @@ const getLastUpdate = () => {
function updateServer(param) {
database.databases.serversDB.write(() => {
database.databases.serversDB.create('servers', { id: this.ddp.url, ...param }, true);
database.databases.serversDB.create('servers', { id: reduxStore.getState().server.server, ...param }, true);
});
}
export default async function() {
try {
if (!this.ddp) {
// TODO: should implement loop or get from rest?
return;
}
// if (!SDK.driver.dd) {
// // 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)));
const result = await ((!lastUpdate || fetchNewSettings)
? SDK.driver.asyncCall('public-settings/get')
: SDK.driver.asyncCall('public-settings/get', new Date(lastUpdate)));
const data = result.update || result || [];
const filteredSettings = this._prepareSettings(this._filterSettings(data));
@ -47,7 +49,8 @@ export default async function() {
const iconSetting = data.find(item => item._id === 'Assets_favicon_512');
if (iconSetting) {
const iconURL = `${ this.ddp.url }/${ iconSetting.value.url || iconSetting.value.defaultUrl }`;
const baseUrl = reduxStore.getState().server.server;
const iconURL = `${ baseUrl }/${ iconSetting.value.url || iconSetting.value.defaultUrl }`;
updateServer.call(this, { iconURL });
}
} catch (e) {

View File

@ -22,10 +22,13 @@ export default (msg) => {
msg = normalizeAttachments(msg);
msg.reactions = msg.reactions || [];
// TODO: api problems
if (Array.isArray(msg.reactions)) {
msg.reactions = msg.reactions.map((value, key) => ({ emoji: key, usernames: value.usernames.map(username => ({ value: username })) }));
} else {
msg.reactions = Object.keys(msg.reactions).map(key => ({ emoji: key, usernames: msg.reactions[key].usernames.map(username => ({ value: username })) }));
// if (Array.isArray(msg.reactions)) {
// msg.reactions = msg.reactions.map((value, key) => ({ emoji: key, usernames: value.usernames.map(username => ({ value: username })) }));
// } else {
// msg.reactions = Object.keys(msg.reactions).map(key => ({ emoji: key, usernames: msg.reactions[key].usernames.map(username => ({ value: username })) }));
// }
if (!Array.isArray(msg.reactions)) {
msg.reactions = Object.keys(msg.reactions).map(key => ({ _id: `${ msg._id }${ key }`, emoji: key, usernames: msg.reactions[key].usernames.map(username => ({ value: username })) }));
}
msg.urls = msg.urls ? parseUrls(msg.urls) : [];
msg._updatedAt = new Date();

View File

@ -1,8 +1,8 @@
import { Answers } from 'react-native-fabric';
export default fn => (params) => {
export default fn => (...params) => {
try {
fn(params);
fn(...params);
} catch (e) {
let error = e;
if (typeof error !== 'object') {

View File

@ -1,40 +0,0 @@
import toQuery from './toQuery';
const handleSuccess = (msg) => {
if ((msg.success !== undefined && !msg.success) || (msg.status && msg.status === 'error')) {
return Promise.reject(msg);
}
return msg;
};
export const get = function({
token, id, server
}, method, params = {}) {
return fetch(`${ server }/api/v1/${ method }/?${ toQuery(params) }`, {
method: 'get',
headers: {
// 'Accept-Encoding': 'gzip',
'Content-Type': 'application/json',
'X-Auth-Token': token,
'X-User-Id': id
}
}).then(response => response.json()).then(handleSuccess);
};
export const post = function({
token, id, server
}, method, params = {}) {
return fetch(`${ server }/api/v1/${ method }`, {
method: 'post',
body: JSON.stringify(params),
headers: {
// 'Accept-Encoding': 'gzip',
'Content-Type': 'application/json',
Accept: 'application/json',
'X-Auth-Token': token,
'X-User-Id': id
}
}).then(response => response.json()).then(handleSuccess);
};

View File

@ -1,3 +0,0 @@
export default function(obj) {
return Object.keys(obj).filter(p => obj[p] !== undefined && obj[p] !== null).map(p => `${ encodeURIComponent(p) }=${ encodeURIComponent(obj[p]) }`).join('&');
}

View File

@ -1,10 +1,9 @@
import { InteractionManager } from 'react-native';
import * as SDK from '@rocket.chat/sdk';
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 = {
@ -12,10 +11,10 @@ const types = {
};
async function loadMessagesForRoomRest({ rid: roomId, latest, t }) {
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 (latest) {
latest = new Date(latest).toISOString();
}
const data = await SDK.api.get(`${ types[t] }.history`, { roomId, latest });
if (!data || data.status === 'error') {
return [];
}
@ -25,13 +24,12 @@ async function loadMessagesForRoomRest({ rid: roomId, latest, t }) {
async function loadMessagesForRoomDDP(...args) {
const [{ rid: roomId, latest }] = args;
try {
const data = await this.ddp.call('loadHistory', roomId, latest, 50);
const data = await SDK.driver.asyncCall('loadHistory', roomId, latest, 50);
if (!data || !data.messages.length) {
return [];
}
return data.messages;
} catch (e) {
console.warn('loadMessagesForRoomDDP', e);
return loadMessagesForRoomRest.call(this, ...args);
}
}
@ -40,11 +38,15 @@ export default async function loadMessagesForRoom(...args) {
const { database: db } = database;
return new Promise(async(resolve, reject) => {
try {
const data = (await (this.ddp && this.ddp.status ? loadMessagesForRoomDDP.call(this, ...args) : loadMessagesForRoomRest.call(this, ...args))).map(buildMessage);
const data = (await (SDK.driver.ddp
? loadMessagesForRoomDDP.call(this, ...args)
: loadMessagesForRoomRest.call(this, ...args))).map(buildMessage);
if (data && data.length) {
InteractionManager.runAfterInteractions(() => {
db.write(() => data.forEach(message => db.create('messages', message, true)));
db.write(() => data.forEach((message) => {
db.create('messages', message, true);
}));
return resolve(data);
});
} else {

View File

@ -1,16 +1,16 @@
import { InteractionManager } from 'react-native';
import * as SDK from '@rocket.chat/sdk';
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 { 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 });
async function loadMissedMessagesRest({ rid: roomId, lastOpen }) {
let lastUpdate;
if (lastOpen) {
lastUpdate = new Date(lastOpen).toISOString();
}
const { result } = await SDK.api.get('chat.syncMessages', { roomId, lastUpdate });
return result;
}
@ -18,7 +18,7 @@ async function loadMissedMessagesDDP(...args) {
const [{ rid, lastOpen: lastUpdate }] = args;
try {
const result = await this.ddp.call('messages/get', rid, { lastUpdate: new Date(lastUpdate) });
const result = await SDK.driver.asyncCall('messages/get', rid, { lastUpdate: new Date(lastUpdate) });
return result;
} catch (e) {
return loadMissedMessagesRest.call(this, ...args);
@ -29,7 +29,7 @@ export default async function loadMissedMessages(...args) {
const { database: db } = database;
return new Promise(async(resolve, reject) => {
try {
const data = (await (this.ddp && this.ddp.status ? loadMissedMessagesDDP.call(this, ...args) : loadMissedMessagesRest.call(this, ...args)));
const data = (await (SDK.driver.ddp ? loadMissedMessagesDDP.call(this, ...args) : loadMissedMessagesRest.call(this, ...args)));
if (data) {
if (data.updated && data.updated.length) {

View File

@ -1,28 +1,25 @@
import { post } from './helpers/rest';
import * as SDK from '@rocket.chat/sdk';
import database from '../realm';
import log from '../../utils/log';
import store from '../createStore';
const readMessagesREST = function readMessagesREST(rid) {
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 });
const readMessagesREST = function readMessagesREST(rid) {
return SDK.api.post('subscriptions.read', { rid });
};
const readMessagesDDP = function readMessagesDDP(rid) {
try {
return this.ddp.call('readMessages', rid);
return SDK.driver.asyncCall('readMessages', rid);
} catch (e) {
return readMessagesREST.call(this, rid);
}
};
export default async function readMessages(rid) {
const ls = new Date();
const { database: db } = database;
try {
// eslint-disable-next-line
const data = await (this.ddp && this.ddp.status ? readMessagesDDP.call(this, rid) : readMessagesREST.call(this, rid));
const data = await (SDK.driver.ddp ? readMessagesDDP.call(this, rid) : readMessagesREST.call(this, rid));
const [subscription] = db.objects('subscriptions').filtered('rid = $0', rid);
db.write(() => {
subscription.open = true;
@ -30,8 +27,8 @@ export default async function readMessages(rid) {
subscription.unread = 0;
subscription.userMentions = 0;
subscription.groupMentions = 0;
subscription.ls = new Date();
subscription.lastOpen = new Date();
subscription.ls = ls;
subscription.lastOpen = ls;
});
return data;
} catch (e) {

View File

@ -1,4 +1,5 @@
import RNFetchBlob from 'rn-fetch-blob';
import * as SDK from '@rocket.chat/sdk';
import reduxStore from '../createStore';
import database from '../realm';
@ -6,15 +7,15 @@ import database from '../realm';
const promises = {};
function _ufsCreate(fileInfo) {
return this.ddp.call('ufsCreate', fileInfo);
return SDK.driver.asyncCall('ufsCreate', fileInfo);
}
function _ufsComplete(fileId, store, token) {
return this.ddp.call('ufsComplete', fileId, store, token);
return SDK.driver.asyncCall('ufsComplete', fileId, store, token);
}
function _sendFileMessage(rid, data, msg = {}) {
return this.ddp.call('sendFileMessage', rid, null, data, msg);
return SDK.driver.asyncCall('sendFileMessage', rid, null, data, msg);
}
export function isUploadActive(path) {

View File

@ -1,8 +1,8 @@
import Random from 'react-native-meteor/lib/Random';
import * as SDK from '@rocket.chat/sdk';
import messagesStatus from '../../constants/messagesStatus';
import buildMessage from './helpers/buildMessage';
import { post } from './helpers/rest';
import database from '../realm';
import reduxStore from '../createStore';
import log from '../../utils/log';
@ -32,21 +32,18 @@ export const getMessage = (rid, msg = {}) => {
};
function sendMessageByRest(message) {
const { token, id } = this.ddp._login;
const server = this.ddp.url.replace(/^ws/, 'http');
const { _id, rid, msg } = message;
return post({ token, id, server }, 'chat.sendMessage', { message: { _id, rid, msg } });
return SDK.api.post('chat.sendMessage', { message: { _id, rid, msg } });
}
function sendMessageByDDP(message) {
const { _id, rid, msg } = message;
return this.ddp.call('sendMessage', { _id, rid, msg });
return SDK.driver.asyncCall('sendMessage', { _id, rid, msg });
}
export async function _sendMessageCall(message) {
try {
// eslint-disable-next-line
const data = await (this.ddp && this.ddp.status ? sendMessageByDDP.call(this, message) : sendMessageByRest.call(this, message));
const data = await (SDK.driver.ddp ? sendMessageByDDP.call(this, message) : sendMessageByRest.call(this, message));
return data;
} catch (e) {
database.write(() => {

View File

@ -1,14 +1,11 @@
// import database from '../../realm';
// import reduxStore from '../../createStore';
// import normalizeMessage from '../helpers/normalizeMessage';
// import _buildMessage from '../helpers/buildMessage';
// import protectedFunction from '../helpers/protectedFunction';
import * as SDK from '@rocket.chat/sdk';
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 }/deleteMessage`, false)
const subscribe = rid => Promise.all([
SDK.driver.subscribe('stream-room-messages', rid, false),
SDK.driver.subscribe('stream-notify-room', `${ rid }/typing`, false),
SDK.driver.subscribe('stream-notify-room', `${ rid }/deleteMessage`, false)
]);
const unsubscribe = subscriptions => subscriptions.forEach(sub => sub.unsubscribe().catch((e) => {
log('unsubscribeRoom', e);
@ -16,23 +13,13 @@ const unsubscribe = subscriptions => subscriptions.forEach(sub => sub.unsubscrib
let timer = null;
let promises;
let logged;
let disconnected;
const stop = (ddp) => {
const stop = () => {
if (promises) {
promises.then(unsubscribe);
promises = false;
}
if (ddp) {
ddp.removeListener('logged', logged);
ddp.removeListener('disconnected', disconnected);
}
logged = false;
disconnected = false;
clearTimeout(timer);
};
@ -47,7 +34,7 @@ export default async function subscribeRoom({ rid, t }) {
}
timer = setTimeout(async() => {
try {
await this.loadMissedMessages({ rid, t, lastOpen: timer });
await this.loadMissedMessages({ rid, t });
timer = false;
loop();
} catch (e) {
@ -56,29 +43,28 @@ export default async function subscribeRoom({ rid, t }) {
}, 5000);
};
if (!this.ddp || !this.ddp.status) {
if (!SDK.driver.ddp && SDK.driver.userId) {
loop();
} else {
logged = this.ddp.on('logged', () => {
SDK.driver.on('logged', () => {
clearTimeout(timer);
timer = false;
// promises = subscribe(this.ddp, rid);
});
disconnected = this.ddp.on('disconnected', () => {
if (this._login) {
SDK.driver.on('disconnected', () => {
if (SDK.driver.userId) {
loop();
}
});
try {
promises = subscribe(this.ddp, rid);
promises = subscribe(rid);
} catch (e) {
log('subscribeRoom', e);
}
}
return {
stop: () => stop(this.ddp)
stop: () => stop()
};
}

View File

@ -1,4 +1,6 @@
import Random from 'react-native-meteor/lib/Random';
import * as SDK from '@rocket.chat/sdk';
import database from '../../realm';
import { merge } from '../helpers/mergeSubscriptionsRooms';
import protectedFunction from '../helpers/protectedFunction';
@ -7,9 +9,9 @@ import log from '../../../utils/log';
export default async function subscribeRooms(id) {
const promises = Promise.all([
this.ddp.subscribe('stream-notify-user', `${ id }/subscriptions-changed`, false),
this.ddp.subscribe('stream-notify-user', `${ id }/rooms-changed`, false),
this.ddp.subscribe('stream-notify-user', `${ id }/message`, false)
SDK.driver.subscribe('stream-notify-user', `${ id }/subscriptions-changed`, false),
SDK.driver.subscribe('stream-notify-user', `${ id }/rooms-changed`, false),
SDK.driver.subscribe('stream-notify-user', `${ id }/message`, false)
]);
let timer = null;
@ -28,26 +30,29 @@ export default async function subscribeRooms(id) {
}, 5000);
};
if (!this.ddp && this._login) {
if (!SDK.driver.ddp && SDK.driver.userId) {
loop();
} else {
this.ddp.on('logged', () => {
SDK.driver.on('logged', () => {
clearTimeout(timer);
timer = false;
});
this.ddp.on('logout', () => {
SDK.driver.on('logout', () => {
clearTimeout(timer);
timer = true;
});
this.ddp.on('disconnected', () => {
SDK.driver.on('disconnected', () => {
if (this._login) {
loop();
}
});
this.ddp.on('stream-notify-user', protectedFunction((ddpMessage) => {
SDK.driver.on('stream-notify-user', protectedFunction((e, ddpMessage) => {
if (ddpMessage.msg === 'added') {
return;
}
const [type, data] = ddpMessage.fields.args;
const [, ev] = ddpMessage.fields.eventName.split('/');
if (/subscriptions/.test(ev)) {

View File

@ -177,8 +177,9 @@ const messagesReactionsUsernamesSchema = {
const messagesReactionsSchema = {
name: 'messagesReactions',
primaryKey: 'emoji',
primaryKey: '_id',
properties: {
_id: 'string',
emoji: 'string',
usernames: { type: 'list', objectType: 'messagesReactionsUsernames' }
}

View File

@ -1,7 +1,7 @@
import { AsyncStorage, Platform } from 'react-native';
import { hashPassword } from 'react-native-meteor/lib/utils';
import foreach from 'lodash/forEach';
import RNFetchBlob from 'rn-fetch-blob';
import * as SDK from '@rocket.chat/sdk';
import reduxStore from './createStore';
import defaultSettings from '../constants/settings';
@ -13,7 +13,7 @@ import log from '../utils/log';
import {
setUser, setLoginServices, removeLoginServices, loginRequest, loginSuccess, loginFailure, logout
} from '../actions/login';
import { disconnect, connectSuccess, connectFailure } from '../actions/connect';
import { disconnect, connectSuccess } from '../actions/connect';
import { setActiveUser } from '../actions/activeUsers';
import { starredMessagesReceived, starredMessageUnstarred } from '../actions/starredMessages';
import { pinnedMessagesReceived, pinnedMessageUnpinned } from '../actions/pinnedMessages';
@ -22,7 +22,6 @@ import { snippetedMessagesReceived } from '../actions/snippetedMessages';
import { roomFilesReceived } from '../actions/roomFiles';
import { someoneTyping, roomMessageReceived } from '../actions/room';
import { setRoles } from '../actions/roles';
import Ddp from './ddp';
import subscribeRooms from './methods/subscriptions/rooms';
import subscribeRoom from './methods/subscriptions/room';
@ -47,7 +46,7 @@ import { getDeviceToken } from '../push';
const TOKEN_KEY = 'reactnativemeteor_usertoken';
const SORT_PREFS_KEY = 'RC_SORT_PREFS_KEY';
const call = (method, ...params) => RocketChat.ddp.call(method, ...params); // eslint-disable-line
const call = (method, ...params) => SDK.driver.asyncCall(method, ...params);
const returnAnArray = obj => obj || [];
const RocketChat = {
@ -135,63 +134,84 @@ const RocketChat = {
// TODO: one api call
// call /me only one time
if (!user.username) {
const me = await this.me({ token: user.token, userId: user.id });
const me = await SDK.api.get('me');
user = { ...user, ...me };
}
if (user.username) {
const userInfo = await this.userInfo({ token: user.token, userId: user.id });
const userInfo = await SDK.api.get('users.info', { userId: user.id });
user = { ...user, ...userInfo.user };
}
RocketChat.registerPushToken(user.id);
reduxStore.dispatch(setUser(user));
reduxStore.dispatch(loginSuccess(user));
this.ddp.subscribe('userData');
} catch (e) {
log('rocketchat.loginSuccess', e);
log('SDK.loginSuccess', e);
}
},
connect(url, login) {
return new Promise((resolve) => {
return new Promise(async() => {
if (this.ddp) {
this.ddp.disconnect();
delete this.ddp;
RocketChat.disconnect();
this.ddp = null;
}
this.ddp = new Ddp(url, login);
if (login) {
protectedFunction(() => RocketChat.getRooms());
SDK.api.setAuth({ authToken: login.token, userId: login.id });
}
this.ddp.on('login', protectedFunction(() => reduxStore.dispatch(loginRequest())));
SDK.api.setBaseUrl(url);
SDK.driver.connect({ host: url, useSsl: true }, (err, ddp) => {
if (err) {
return console.warn(err);
}
this.ddp = ddp;
if (login) {
SDK.driver.ddp.login({ resume: login.resume });
}
});
this.ddp.on('loginError', protectedFunction(err => reduxStore.dispatch(loginFailure(err))));
SDK.driver.on('connected', () => {
reduxStore.dispatch(connectSuccess());
SDK.driver.subscribe('meteor.loginServiceConfiguration');
SDK.driver.subscribe('activeUsers');
SDK.driver.subscribe('roles');
RocketChat.getSettings();
RocketChat.getPermissions();
RocketChat.getCustomEmoji();
});
this.ddp.on('forbidden', protectedFunction(() => reduxStore.dispatch(logout())));
SDK.driver.on('login', protectedFunction(() => reduxStore.dispatch(loginRequest())));
this.ddp.on('users', protectedFunction(ddpMessage => RocketChat._setUser(ddpMessage)));
SDK.driver.on('forbidden', protectedFunction(() => reduxStore.dispatch(logout())));
this.ddp.on('background', () => this.getRooms().catch(e => log('background getRooms', e)));
SDK.driver.on('users', protectedFunction((error, ddpMessage) => RocketChat._setUser(ddpMessage)));
this.ddp.on('logged', protectedFunction((user) => {
// SDK.driver.on('background', () => this.getRooms().catch(e => log('background getRooms', e)));
SDK.driver.on('logged', protectedFunction((error, user) => {
SDK.api.setAuth({ authToken: user.token, userId: user.id });
SDK.api.currentLogin = {
userId: user.id,
authToken: user.token
};
this.loginSuccess(user);
this.getRooms().catch(e => log('logged getRooms', e));
}));
this.ddp.once('logged', protectedFunction(({ id }) => {
this.subscribeRooms(id);
// this.ddp.subscribe('stream-notify-logged', 'updateAvatar', false);
this.subscribeRooms(user.id);
}));
this.ddp.on('disconnected', protectedFunction(() => {
SDK.driver.on('disconnected', protectedFunction(() => {
reduxStore.dispatch(disconnect());
console.log('disconnected', this.ddp);
}));
this.ddp.on('stream-room-messages', (ddpMessage) => {
SDK.driver.on('stream-room-messages', (error, ddpMessage) => {
// TODO: debounce
const message = _buildMessage(ddpMessage.fields.args[0]);
requestAnimationFrame(() => reduxStore.dispatch(roomMessageReceived(message)));
});
this.ddp.on('stream-notify-room', protectedFunction((ddpMessage) => {
SDK.driver.on('stream-notify-room', protectedFunction((error, ddpMessage) => {
const [_rid, ev] = ddpMessage.fields.eventName.split('/');
if (ev === 'typing') {
reduxStore.dispatch(someoneTyping({ _rid, username: ddpMessage.fields.args[0], typing: ddpMessage.fields.args[1] }));
@ -206,7 +226,7 @@ const RocketChat = {
}
}));
this.ddp.on('rocketchat_starred_message', protectedFunction((ddpMessage) => {
SDK.driver.on('rocketchat_starred_message', protectedFunction((error, ddpMessage) => {
if (ddpMessage.msg === 'added') {
this.starredMessages = this.starredMessages || [];
@ -232,7 +252,7 @@ const RocketChat = {
}
}));
this.ddp.on('rocketchat_pinned_message', protectedFunction((ddpMessage) => {
SDK.driver.on('rocketchat_pinned_message', protectedFunction((error, ddpMessage) => {
if (ddpMessage.msg === 'added') {
this.pinnedMessages = this.pinnedMessages || [];
@ -258,7 +278,7 @@ const RocketChat = {
}
}));
this.ddp.on('rocketchat_mentioned_message', protectedFunction((ddpMessage) => {
SDK.driver.on('rocketchat_mentioned_message', protectedFunction((error, ddpMessage) => {
if (ddpMessage.msg === 'added') {
this.mentionedMessages = this.mentionedMessages || [];
@ -279,7 +299,7 @@ const RocketChat = {
}
}));
this.ddp.on('rocketchat_snippeted_message', protectedFunction((ddpMessage) => {
SDK.driver.on('rocketchat_snippeted_message', protectedFunction((error, ddpMessage) => {
if (ddpMessage.msg === 'added') {
this.snippetedMessages = this.snippetedMessages || [];
@ -300,7 +320,7 @@ const RocketChat = {
}
}));
this.ddp.on('room_files', protectedFunction((ddpMessage) => {
SDK.driver.on('room_files', protectedFunction((error, ddpMessage) => {
if (ddpMessage.msg === 'added') {
this.roomFiles = this.roomFiles || [];
@ -344,7 +364,7 @@ const RocketChat = {
}
}));
this.ddp.on('meteor_accounts_loginServiceConfiguration', protectedFunction((ddpMessage) => {
SDK.driver.on('meteor_accounts_loginServiceConfiguration', (error, ddpMessage) => {
if (ddpMessage.msg === 'added') {
this.loginServices = this.loginServices || {};
if (this.loginServiceTimer) {
@ -364,9 +384,9 @@ const RocketChat = {
}
this.loginServiceTimer = setTimeout(() => reduxStore.dispatch(removeLoginServices()), 1000);
}
}));
});
this.ddp.on('rocketchat_roles', protectedFunction((ddpMessage) => {
SDK.driver.on('rocketchat_roles', protectedFunction((error, ddpMessage) => {
this.roles = this.roles || {};
if (this.roleTimer) {
@ -388,27 +408,25 @@ const RocketChat = {
this.roles[ddpMessage.id] = (ddpMessage.fields && ddpMessage.fields.description) || undefined;
}));
this.ddp.on('error', (err) => {
log('rocketchat.onerror', err);
reduxStore.dispatch(connectFailure());
});
// SDK.driver.on('error', (err) => {
// log('SDK.onerror', err);
// reduxStore.dispatch(connectFailure());
// });
// TODO: fix api (get emojis by date/version....)
// SDK.driver.on('open', protectedFunction(() => {
// RocketChat.getSettings();
// RocketChat.getPermissions();
// reduxStore.dispatch(connectSuccess());
// resolve();
// }));
this.ddp.on('open', protectedFunction(() => {
RocketChat.getSettings();
RocketChat.getPermissions();
reduxStore.dispatch(connectSuccess());
resolve();
}));
this.ddp.once('open', protectedFunction(() => {
this.ddp.subscribe('activeUsers');
this.ddp.subscribe('roles');
RocketChat.getCustomEmoji();
}));
// this.ddp.once('open', protectedFunction(() => {
// this.ddp.subscribe('activeUsers');
// this.ddp.subscribe('roles');
// RocketChat.getCustomEmoji();
// }));
}).catch((e) => {
log('rocketchat.connect catch', e);
log('SDK.connect catch', e);
});
},
@ -424,7 +442,7 @@ const RocketChat = {
return call('sendForgotPasswordEmail', email);
},
loginWithPassword({ username, password, code }, callback) {
async loginWithPassword({ username, password, code }) {
let params = {};
const state = reduxStore.getState();
@ -443,14 +461,12 @@ const RocketChat = {
};
} else {
params = {
password: hashPassword(password),
user: {
username
}
username, password
};
if (typeof username === 'string' && username.indexOf('@') !== -1) {
params.user = { email: username };
params.email = username;
delete params.username;
}
}
@ -463,25 +479,45 @@ const RocketChat = {
};
}
return this.login(params, callback);
try {
return await this.login(params);
} catch (error) {
throw error;
}
},
login(params) {
return this.ddp.login(params);
async login(params) {
try {
await SDK.driver.login(params);
} catch (e) {
reduxStore.dispatch(loginFailure(e));
throw e;
}
},
logout({ server }) {
if (this.ddp) {
try {
this.ddp.logout();
} catch (e) {
log('rocketchat.logout', e);
}
try {
RocketChat.disconnect();
SDK.driver.logout();
} catch (error) {
console.warn(error);
}
AsyncStorage.removeItem(TOKEN_KEY);
AsyncStorage.removeItem(`${ TOKEN_KEY }-${ server }`);
setTimeout(() => {
database.deleteAll();
}, 1000);
}, 300);
},
disconnect() {
try {
SDK.driver.unsubscribeAll();
} catch (error) {
console.warn(error);
}
SDK.api.setAuth({ authToken: null, userId: null });
SDK.api.currentLogin = {
userId: null,
authToken: null
};
},
registerPushToken(userId) {
@ -508,27 +544,6 @@ const RocketChat = {
sendMessage,
getRooms,
readMessages,
me({ server = reduxStore.getState().server.server, token, userId }) {
return fetch(`${ server }/api/v1/me`, {
method: 'get',
headers: {
'Content-Type': 'application/json',
'X-Auth-Token': token,
'X-User-Id': userId
}
}).then(response => response.json());
},
userInfo({ server = reduxStore.getState().server.server, token, userId }) {
return fetch(`${ server }/api/v1/users.info?userId=${ userId }`, {
method: 'get',
headers: {
'Content-Type': 'application/json',
'X-Auth-Token': token,
'X-User-Id': userId
}
}).then(response => response.json());
},
async resendMessage(messageId) {
const message = await database.objects('messages').filtered('_id = $0', messageId)[0];
database.write(() => {
@ -657,7 +672,7 @@ const RocketChat = {
try {
room = await RocketChat.getRoom(message.rid);
} catch (e) {
log('rocketchat.getPermalink', e);
log('SDK.getPermalink', e);
return null;
}
const { server } = reduxStore.getState().server;
@ -669,7 +684,10 @@ const RocketChat = {
return `${ server }/${ roomType }/${ room.name }?msg=${ message._id }`;
},
subscribe(...args) {
return this.ddp.subscribe(...args);
return SDK.driver.subscribe(...args);
},
unsubscribe(subscription) {
return SDK.driver.unsubscribe(subscription);
},
emitTyping(room, t = true) {
const { login } = reduxStore.getState();

View File

@ -34,7 +34,7 @@ const test = function* test() {
const user = yield call(getToken);
// const response =
// yield all([call(connect, server, user && user.token ? { resume: user.token, ...user.user } : undefined)]);// , put(loginRequest({ resume: user.token }))]);
yield call(connect, server, user && user.token ? { resume: user.token, ...user.user } : undefined);
yield call(connect, server, user && user.token ? { resume: user.token, ...user } : null);
// yield put(connectSuccess(response));
} catch (err) {
console.warn('test', err);

View File

@ -29,7 +29,11 @@ const restore = function* restore() {
}
yield put(selectServerRequest(currentServer));
yield put(setUser(userParsed));
} else {
yield put(actions.appStart('outside'));
}
} else {
yield put(actions.appStart('outside'));
}
const sortPreferences = yield RocketChat.getSortPreferences();

View File

@ -10,7 +10,7 @@ let newSub;
const openRoomFiles = function* openRoomFiles({ rid, limit }) {
try {
newSub = yield RocketChat.subscribe('roomFiles', rid, limit);
sub = yield RocketChat.subscribe('roomFiles', rid, limit);
yield put(readyRoomFiles());
if (sub) {
sub.unsubscribe().catch(err => console.warn(err));
@ -23,6 +23,8 @@ const openRoomFiles = function* openRoomFiles({ rid, limit }) {
const closeRoomFiles = function* closeRoomFiles() {
try {
// yield sub.unsubscribe(sub);
// sub = null;
if (sub) {
yield sub.unsubscribe();
}

View File

@ -68,10 +68,10 @@ export default class RoomInfoEditView extends LoggedView {
async componentDidMount() {
const { room } = this.state;
await this.updateRoom();
this.init();
this.rooms.addListener(this.updateRoom);
const { room } = this.state;
this.permissions = RocketChat.hasPermission(PERMISSIONS_ARRAY, room.rid);
}

View File

@ -5,6 +5,7 @@ import {
import PropTypes from 'prop-types';
import { connect, Provider } from 'react-redux';
import { Navigation } from 'react-native-navigation';
import * as SDK from '@rocket.chat/sdk';
import { toggleServerDropdown as toggleServerDropdownAction } from '../../actions/rooms';
import { selectServerRequest as selectServerRequestAction } from '../../actions/server';
@ -106,15 +107,19 @@ export default class ServerDropdown extends Component {
select = async(server) => {
const {
server: serverProp, selectServerRequest, appStart, navigator
server: currentServer, selectServerRequest, appStart, navigator
} = this.props;
this.close();
if (serverProp !== server) {
selectServerRequest(server);
if (currentServer !== server) {
const token = await AsyncStorage.getItem(`${ RocketChat.TOKEN_KEY }-${ server }`);
if (!token) {
appStart();
try {
SDK.driver.disconnect();
} catch (error) {
console.warn(error);
}
if (NewServerView == null) {
NewServerView = require('../NewServerView').default;
Navigation.registerComponent('NewServerView', () => NewServerView, store, Provider);
@ -131,6 +136,8 @@ export default class ServerDropdown extends Component {
}
});
}, 1000);
} else {
selectServerRequest(server);
}
}
}
@ -149,6 +156,7 @@ export default class ServerDropdown extends Component {
source={{ uri: item.iconURL }}
defaultSource={{ uri: 'logo' }}
style={styles.serverIcon}
onError={() => console.warn('error loading serverIcon')}
/>
)
: (

90
package-lock.json generated
View File

@ -1820,6 +1820,30 @@
"resolved": "https://registry.npmjs.org/@remobile/react-native-toast/-/react-native-toast-1.0.7.tgz",
"integrity": "sha512-iOD1PRnTSVr9sDWQdesIpfRrwJhHfeEQe5BpalQxC5OhM9thpiE6cu2NlW1KBWl0RJG4ZiJaF1xLlCo9YxU6dA=="
},
"@rocket.chat/sdk": {
"version": "git+https://github.com/RocketChat/Rocket.Chat.js.SDK.git#a2af4675174ce53076ba587693e5210c05ee767d",
"from": "git+https://github.com/RocketChat/Rocket.Chat.js.SDK.git#ddp",
"requires": {
"@types/lru-cache": "^4.1.0",
"@types/node": "^9.4.6",
"axios": "^0.18.0",
"ejson": "^2.1.2",
"isomorphic-ws": "^4.0.1",
"lru-cache": "^4.1.1",
"universal-websocket-client": "^1.0.2",
"ws": "^5.2.0"
},
"dependencies": {
"ws": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
"integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
"requires": {
"async-limiter": "~1.0.0"
}
}
}
},
"@storybook/addon-actions": {
"version": "3.4.11",
"resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-3.4.11.tgz",
@ -2210,11 +2234,21 @@
"react-treebeard": "2.1.0"
}
},
"@types/lru-cache": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-4.1.1.tgz",
"integrity": "sha512-8mNEUG6diOrI6pMqOHrHPDBB1JsrpedeMK9AWGzVCQ7StRRribiT9BRvUmF8aUws9iBbVlgVekOT5Sgzc1MTKw=="
},
"@types/markdown-it": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-0.0.4.tgz",
"integrity": "sha512-FWR7QB7EqBRq1s9BMk0ccOSOuRLfVEWYpHQYpFPaXtCoqN6dJx2ttdsdQbUxLLnAlKpYeVjveGGhQ3583TTa7g=="
},
"@types/node": {
"version": "9.6.34",
"resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.34.tgz",
"integrity": "sha512-PzJpSs2afoYqBA4yLBgaKUdZRk8+1yvkxcUBW6958h4vYOC+pc4k4C+QmQ6AO5Pt7uA4EIIboFog6YNCuITD0g=="
},
"@types/react": {
"version": "16.4.6",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.4.6.tgz",
@ -2934,6 +2968,15 @@
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
},
"axios": {
"version": "0.18.0",
"resolved": "http://registry.npmjs.org/axios/-/axios-0.18.0.tgz",
"integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=",
"requires": {
"follow-redirects": "^1.3.0",
"is-buffer": "^1.1.5"
}
},
"axobject-query": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.1.tgz",
@ -8354,6 +8397,24 @@
"readable-stream": "2.3.5"
}
},
"follow-redirects": {
"version": "1.5.8",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.8.tgz",
"integrity": "sha512-sy1mXPmv7kLAMKW/8XofG7o9T+6gAjzdZK4AJF6ryqQYUa/hnzgiypoeUecZ53x7XiqKNEpNqLtS97MshW2nxg==",
"requires": {
"debug": "=3.1.0"
},
"dependencies": {
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
"ms": "2.0.0"
}
}
}
},
"for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@ -10697,6 +10758,11 @@
"whatwg-fetch": "2.0.3"
}
},
"isomorphic-ws": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz",
"integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w=="
},
"isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
@ -13737,7 +13803,7 @@
},
"rimraf": {
"version": "2.4.5",
"resolved": "http://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz",
"integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=",
"dev": true,
"optional": true,
@ -13873,7 +13939,7 @@
},
"ncp": {
"version": "2.0.0",
"resolved": "http://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz",
"resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz",
"integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=",
"dev": true,
"optional": true
@ -20472,6 +20538,26 @@
"crypto-random-string": "1.0.0"
}
},
"universal-websocket-client": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/universal-websocket-client/-/universal-websocket-client-1.0.2.tgz",
"integrity": "sha512-Pi6BdJtEAISb77GTbOLBLIWdYGezXgnJejrVBYKXxzNTsLcjJS+mWIJ2BRZElSlOG/wc7+yfOe5y30bzTu3Qqg==",
"requires": {
"ws": "^3.3.3"
},
"dependencies": {
"ws": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
"integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
"requires": {
"async-limiter": "~1.0.0",
"safe-buffer": "~5.1.0",
"ultron": "~1.1.0"
}
}
}
},
"universalify": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",

View File

@ -23,6 +23,7 @@
},
"dependencies": {
"@remobile/react-native-toast": "^1.0.7",
"@rocket.chat/sdk": "git+https://github.com/RocketChat/Rocket.Chat.js.SDK.git#ddp",
"deep-equal": "^1.0.1",
"ejson": "^2.1.2",
"js-base64": "^2.4.9",