Update JS SDK version (#602)

This commit is contained in:
Diego Mello 2019-02-07 13:48:10 -02:00 committed by GitHub
parent d26f14d155
commit 2585038112
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 13647 additions and 24579 deletions

View File

@ -14,26 +14,33 @@ jobs:
steps: steps:
- checkout - checkout
- restore_cache:
key: node-modules-{{ checksum ".circleci/config.yml" }}-{{ checksum "yarn.lock" }}
- run: - run:
name: Install NPM modules name: Install NPM modules
command: | command: |
npm install yarn
# npm install codecov
- run: - run:
name: Lint name: Lint
command: | command: |
npm run lint yarn lint
- run: - run:
name: Test name: Test
command: | command: |
npm run test yarn test
- run: - run:
name: Codecov name: Codecov
command: | command: |
npx codecov yarn codecov
- save_cache:
key: node-modules-{{ checksum ".circleci/config.yml" }}-{{ checksum "yarn.lock" }}
paths:
- ./node_modules
e2e-test: e2e-test:
macos: macos:
@ -64,9 +71,8 @@ jobs:
- run: - run:
name: Install NPM modules name: Install NPM modules
command: | command: |
rm -rf node_modules yarn global add detox-cli
npm install yarn
npm install -g detox-cli
- run: - run:
name: Build name: Build
@ -96,20 +102,13 @@ jobs:
steps: steps:
- checkout - checkout
# - run:
# name: Install Node 8
# command: |
# curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh | bash
# source ~/.nvm/nvm.sh
# nvm install 8
- restore_cache: - restore_cache:
key: node-modules-{{ checksum ".circleci/config.yml" }}-{{ checksum "package-lock.json" }} key: node-modules-{{ checksum ".circleci/config.yml" }}-{{ checksum "yarn.lock" }}
- run: - run:
name: Install NPM modules name: Install NPM modules
command: | command: |
npm install yarn
- restore_cache: - restore_cache:
key: android-{{ checksum ".circleci/config.yml" }}-{{ checksum "android/build.gradle" }}-{{ checksum "android/app/build.gradle" }} key: android-{{ checksum ".circleci/config.yml" }}-{{ checksum "android/build.gradle" }}-{{ checksum "android/app/build.gradle" }}
@ -162,7 +161,7 @@ jobs:
path: /tmp/build/outputs path: /tmp/build/outputs
- save_cache: - save_cache:
key: node-modules-{{ checksum ".circleci/config.yml" }}-{{ checksum "package.json" }} key: node-modules-{{ checksum ".circleci/config.yml" }}-{{ checksum "yarn.lock" }}
paths: paths:
- ./node_modules - ./node_modules
@ -200,8 +199,7 @@ jobs:
- run: - run:
name: Install NPM modules name: Install NPM modules
command: | command: |
rm -rf node_modules yarn
npm install
- run: - run:
name: Fix known build error name: Fix known build error

View File

@ -27,16 +27,16 @@ Follow the [React Native Getting Started Guide](https://facebook.github.io/react
```bash ```bash
$ git clone git@github.com:RocketChat/Rocket.Chat.ReactNative.git $ git clone git@github.com:RocketChat/Rocket.Chat.ReactNative.git
$ cd Rocket.Chat.ReactNative $ cd Rocket.Chat.ReactNative
$ npm install -g react-native-cli $ yarn global add react-native-cli
$ npm install $ yarn
``` ```
- Run application - Run application
```bash ```bash
$ npm run ios $ yarn ios
``` ```
```bash ```bash
$ npm run android $ yarn android
``` ```
### Running single server ### Running single server
@ -221,13 +221,13 @@ $ detox test
- General requirements - General requirements
- Install storybook - Install storybook
```bash ```bash
$ npm i -g @storybook/cli $ yarn global add @storybook/cli
``` ```
- Running storybook - Running storybook
- Run storybook application - Run storybook application
```bash ```bash
$ npm run storybook $ yarn storybook
``` ```
- Run application in other shell - Run application in other shell
```bash ```bash

View File

@ -1,4 +1,5 @@
export default { export default {
getModel: () => '', getModel: () => '',
getReadableVersion: () => '' getReadableVersion: () => '',
getBundleId: () => ''
}; };

View File

@ -58,7 +58,8 @@ export default class EmojiCategory extends React.Component {
testID={`reaction-picker-${ emoji.isCustom ? emoji.content : emoji }`} testID={`reaction-picker-${ emoji.isCustom ? emoji.content : emoji }`}
> >
{renderEmoji(emoji, size, baseUrl)} {renderEmoji(emoji, size, baseUrl)}
</TouchableOpacity>); </TouchableOpacity>
);
} }
render() { render() {

View File

@ -148,6 +148,7 @@ export default class extends React.PureComponent {
/> />
</BorderlessButton> </BorderlessButton>
</View> </View>
</SafeAreaView>); </SafeAreaView>
);
} }
} }

View File

@ -1,5 +1,3 @@
import * as SDK from '@rocket.chat/sdk';
import database from '../realm'; import database from '../realm';
const restTypes = { const restTypes = {
@ -9,7 +7,7 @@ const restTypes = {
async function open({ type, rid }) { async function open({ type, rid }) {
try { try {
// RC 0.61.0 // RC 0.61.0
await SDK.api.post(`${ restTypes[type] }.open`, { roomId: rid }); await this.sdk.post(`${ restTypes[type] }.open`, { roomId: rid });
return true; return true;
} catch (e) { } catch (e) {
if (e.data && /is already open/.test(e.data.error)) { if (e.data && /is already open/.test(e.data.error)) {

View File

@ -1,8 +1,6 @@
import { InteractionManager } from 'react-native'; import { InteractionManager } from 'react-native';
import * as SDK from '@rocket.chat/sdk';
import reduxStore from '../createStore'; import reduxStore from '../createStore';
import database from '../realm'; import database from '../realm';
import * as actions from '../../actions'; import * as actions from '../../actions';
import log from '../../utils/log'; import log from '../../utils/log';
@ -17,7 +15,7 @@ export default async function() {
try { try {
const lastMessage = getLastMessage(); const lastMessage = getLastMessage();
// RC 0.61.0 // RC 0.61.0
const result = await SDK.api.get('emoji-custom'); const result = await this.sdk.get('emoji-custom');
let { emojis } = result; let { emojis } = result;
emojis = emojis.filter(emoji => !lastMessage || emoji._updatedAt > lastMessage); emojis = emojis.filter(emoji => !lastMessage || emoji._updatedAt > lastMessage);
emojis = this._prepareEmojis(emojis); emojis = this._prepareEmojis(emojis);

View File

@ -1,5 +1,4 @@
import { InteractionManager } from 'react-native'; import { InteractionManager } from 'react-native';
import * as SDK from '@rocket.chat/sdk';
import database from '../realm'; import database from '../realm';
import log from '../../utils/log'; import log from '../../utils/log';
@ -8,7 +7,7 @@ import defaultPermissions from '../../constants/permissions';
export default async function() { export default async function() {
try { try {
// RC 0.66.0 // RC 0.66.0
const result = await SDK.api.get('permissions.list'); const result = await this.sdk.get('permissions.list');
if (!result.success) { if (!result.success) {
return; return;

View File

@ -1,7 +1,6 @@
import { InteractionManager } from 'react-native'; import { InteractionManager } from 'react-native';
import * as SDK from '@rocket.chat/sdk';
import mergeSubscriptionsRooms, { merge } from './helpers/mergeSubscriptionsRooms'; import mergeSubscriptionsRooms from './helpers/mergeSubscriptionsRooms';
import database from '../realm'; import database from '../realm';
import log from '../../utils/log'; import log from '../../utils/log';
@ -13,27 +12,22 @@ const lastMessage = () => {
}; };
export default function() { export default function() {
const { database: db } = database;
return new Promise(async(resolve, reject) => { return new Promise(async(resolve, reject) => {
try { try {
const updatedSince = lastMessage(); const updatedSince = lastMessage();
// subscriptions.get: Since RC 0.60.0 // subscriptions.get: Since RC 0.60.0
// rooms.get: Since RC 0.62.0 // rooms.get: Since RC 0.62.0
const [subscriptionsResult, roomsResult] = await (updatedSince const [subscriptionsResult, roomsResult] = await (updatedSince
? Promise.all([SDK.api.get('subscriptions.get', { updatedSince }), SDK.api.get('rooms.get', { updatedSince })]) ? Promise.all([this.sdk.get('subscriptions.get', { updatedSince }), this.sdk.get('rooms.get', { updatedSince })])
: Promise.all([SDK.api.get('subscriptions.get'), SDK.api.get('rooms.get')]) : Promise.all([this.sdk.get('subscriptions.get'), this.sdk.get('rooms.get')])
); );
const { subscriptions, rooms } = mergeSubscriptionsRooms(subscriptionsResult, roomsResult); const { subscriptions } = mergeSubscriptionsRooms(subscriptionsResult, roomsResult);
const data = rooms.map(room => ({ room, sub: database.objects('subscriptions').filtered('rid == $0', room._id) }));
InteractionManager.runAfterInteractions(() => { InteractionManager.runAfterInteractions(() => {
db.write(() => { database.write(() => {
subscriptions.forEach(subscription => db.create('subscriptions', subscription, true)); subscriptions.forEach(subscription => database.create('subscriptions', subscription, true));
data.forEach(({ sub, room }) => sub[0] && merge(sub[0], room));
}); });
resolve(data); resolve(subscriptions);
}); });
} catch (e) { } catch (e) {
log('getRooms', e); log('getRooms', e);

View File

@ -1,5 +1,4 @@
import { InteractionManager } from 'react-native'; import { InteractionManager } from 'react-native';
import * as SDK from '@rocket.chat/sdk';
import reduxStore from '../createStore'; import reduxStore from '../createStore';
import database from '../realm'; import database from '../realm';
@ -17,7 +16,7 @@ export default async function() {
try { try {
const settingsParams = JSON.stringify(Object.keys(settings)); const settingsParams = JSON.stringify(Object.keys(settings));
// RC 0.60.0 // RC 0.60.0
const result = await fetch(`${ SDK.api.url }settings.public?query={"_id":{"$in":${ settingsParams }}}`).then(response => response.json()); const result = await fetch(`${ this.sdk.client.host }/api/v1/settings.public?query={"_id":{"$in":${ settingsParams }}}`).then(response => response.json());
if (!result.success) { if (!result.success) {
return; return;

View File

@ -1,7 +1,12 @@
import EJSON from 'ejson';
import normalizeMessage from './normalizeMessage'; import normalizeMessage from './normalizeMessage';
// TODO: delete and update // TODO: delete and update
export const merge = (subscription, room) => { export const merge = (subscription, room) => {
subscription = EJSON.fromJSONValue(subscription);
room = EJSON.fromJSONValue(room);
if (!subscription) { if (!subscription) {
return; return;
} }
@ -28,6 +33,8 @@ export const merge = (subscription, room) => {
} }
if (subscription.roles && subscription.roles.length) { if (subscription.roles && subscription.roles.length) {
subscription.roles = subscription.roles.map(role => (role.value ? role : { value: role })); subscription.roles = subscription.roles.map(role => (role.value ? role : { value: role }));
} else {
subscription.roles = [];
} }
if (subscription.mobilePushNotifications === 'nothing') { if (subscription.mobilePushNotifications === 'nothing') {

View File

@ -1,5 +1,4 @@
import { InteractionManager } from 'react-native'; import { InteractionManager } from 'react-native';
import * as SDK from '@rocket.chat/sdk';
import buildMessage from './helpers/buildMessage'; import buildMessage from './helpers/buildMessage';
import database from '../realm'; import database from '../realm';
@ -9,7 +8,7 @@ async function load({ rid: roomId, latest, t }) {
if (t === 'l') { if (t === 'l') {
try { try {
// RC 0.51.0 // RC 0.51.0
const data = await SDK.driver.asyncCall('loadHistory', roomId, null, 50, latest); const data = await this.sdk.methodCall('loadHistory', roomId, null, 50, latest);
if (!data || data.status === 'error') { if (!data || data.status === 'error') {
return []; return [];
} }
@ -25,7 +24,7 @@ async function load({ rid: roomId, latest, t }) {
params = { ...params, latest: new Date(latest).toISOString() }; params = { ...params, latest: new Date(latest).toISOString() };
} }
// RC 0.48.0 // RC 0.48.0
const data = await SDK.api.get(`${ this.roomTypeToApiType(t) }.history`, params); const data = await this.sdk.get(`${ this.roomTypeToApiType(t) }.history`, params);
if (!data || data.status === 'error') { if (!data || data.status === 'error') {
return []; return [];
} }
@ -33,15 +32,14 @@ async function load({ rid: roomId, latest, t }) {
} }
export default function loadMessagesForRoom(...args) { export default function loadMessagesForRoom(...args) {
const { database: db } = database;
return new Promise(async(resolve, reject) => { return new Promise(async(resolve, reject) => {
try { try {
const data = await load.call(this, ...args); const data = await load.call(this, ...args);
if (data && data.length) { if (data && data.length) {
InteractionManager.runAfterInteractions(() => { InteractionManager.runAfterInteractions(() => {
db.write(() => data.forEach((message) => { database.write(() => data.forEach((message) => {
db.create('messages', buildMessage(message), true); database.create('messages', buildMessage(message), true);
})); }));
return resolve(data); return resolve(data);
}); });

View File

@ -1,24 +1,29 @@
import { InteractionManager } from 'react-native'; import { InteractionManager } from 'react-native';
import * as SDK from '@rocket.chat/sdk';
import buildMessage from './helpers/buildMessage'; import buildMessage from './helpers/buildMessage';
import database from '../realm'; import database from '../realm';
import log from '../../utils/log'; import log from '../../utils/log';
const getLastUpdate = (rid) => {
const sub = database
.objects('subscriptions')
.filtered('rid == $0', rid)[0];
return sub && new Date(sub.lastOpen).toISOString();
};
async function load({ rid: roomId, lastOpen }) { async function load({ rid: roomId, lastOpen }) {
let lastUpdate; let lastUpdate;
if (lastOpen) { if (lastOpen) {
lastUpdate = new Date(lastOpen).toISOString(); lastUpdate = new Date(lastOpen).toISOString();
} else { } else {
return []; lastUpdate = getLastUpdate(roomId);
} }
// RC 0.60.0 // RC 0.60.0
const { result } = await SDK.api.get('chat.syncMessages', { roomId, lastUpdate, count: 50 }); const { result } = await this.sdk.get('chat.syncMessages', { roomId, lastUpdate, count: 50 });
return result; return result;
} }
export default function loadMissedMessages(...args) { export default function loadMissedMessages(...args) {
const { database: db } = database;
return new Promise(async(resolve, reject) => { return new Promise(async(resolve, reject) => {
try { try {
const data = (await load.call(this, ...args)); const data = (await load.call(this, ...args));
@ -28,14 +33,14 @@ export default function loadMissedMessages(...args) {
const { updated } = data; const { updated } = data;
updated.forEach(buildMessage); updated.forEach(buildMessage);
InteractionManager.runAfterInteractions(() => { InteractionManager.runAfterInteractions(() => {
db.write(() => updated.forEach(message => db.create('messages', message, true))); database.write(() => updated.forEach(message => database.create('messages', message, true)));
resolve(updated); resolve(updated);
}); });
} }
if (data.deleted && data.deleted.length) { if (data.deleted && data.deleted.length) {
const { deleted } = data; const { deleted } = data;
InteractionManager.runAfterInteractions(() => { InteractionManager.runAfterInteractions(() => {
db.write(() => { database.write(() => {
deleted.forEach((m) => { deleted.forEach((m) => {
const message = database.objects('messages').filtered('_id = $0', m._id); const message = database.objects('messages').filtered('_id = $0', m._id);
database.delete(message); database.delete(message);

View File

@ -1,5 +1,3 @@
import * as SDK from '@rocket.chat/sdk';
import database from '../realm'; import database from '../realm';
import log from '../../utils/log'; import log from '../../utils/log';
@ -7,7 +5,7 @@ export default async function readMessages(rid) {
const ls = new Date(); const ls = new Date();
try { try {
// RC 0.61.0 // RC 0.61.0
const data = await SDK.api.post('subscriptions.read', { rid }); const data = await this.sdk.post('subscriptions.read', { rid });
const [subscription] = database.objects('subscriptions').filtered('rid = $0', rid); const [subscription] = database.objects('subscriptions').filtered('rid = $0', rid);
database.write(() => { database.write(() => {
subscription.open = true; subscription.open = true;

View File

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

View File

@ -1,5 +1,3 @@
import * as SDK from '@rocket.chat/sdk';
import messagesStatus from '../../constants/messagesStatus'; import messagesStatus from '../../constants/messagesStatus';
import buildMessage from './helpers/buildMessage'; import buildMessage from './helpers/buildMessage';
import database from '../realm'; import database from '../realm';
@ -34,25 +32,24 @@ export const getMessage = (rid, msg = {}) => {
export async function sendMessageCall(message) { export async function sendMessageCall(message) {
const { _id, rid, msg } = message; const { _id, rid, msg } = message;
// RC 0.60.0 // RC 0.60.0
const data = await SDK.api.post('chat.sendMessage', { message: { _id, rid, msg } }); const data = await this.sdk.post('chat.sendMessage', { message: { _id, rid, msg } });
return data; return data;
} }
export default async function(rid, msg) { export default async function(rid, msg) {
const { database: db } = database;
try { try {
const message = getMessage(rid, msg); const message = getMessage(rid, msg);
const room = db.objects('subscriptions').filtered('rid == $0', rid); const room = database.objects('subscriptions').filtered('rid == $0', rid);
// TODO: do we need this? // TODO: do we need this?
db.write(() => { database.write(() => {
room.lastMessage = message; room.lastMessage = message;
}); });
try { try {
const ret = await sendMessageCall.call(this, message); const ret = await sendMessageCall.call(this, message);
db.write(() => { database.write(() => {
db.create('messages', buildMessage({ ...message, ...ret }), true); database.create('messages', buildMessage({ ...message, ...ret }), true);
}); });
} catch (e) { } catch (e) {
database.write(() => { database.write(() => {

View File

@ -1,16 +1,9 @@
import * as SDK from '@rocket.chat/sdk';
import log from '../../../utils/log'; import log from '../../../utils/log';
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(() => console.log('unsubscribeRoom'))); const unsubscribe = subscriptions => subscriptions.forEach(sub => sub.unsubscribe().catch(() => console.log('unsubscribeRoom')));
let timer = null;
let promises; let promises;
let timer = null;
const stop = () => { const stop = () => {
if (promises) { if (promises) {
@ -21,46 +14,46 @@ const stop = () => {
clearTimeout(timer); clearTimeout(timer);
}; };
export default function subscribeRoom({ rid, t }) { export default function subscribeRoom({ rid }) {
if (promises) { if (promises) {
promises.then(unsubscribe); promises.then(unsubscribe);
promises = false; promises = false;
} }
const loop = (time = new Date()) => { const loop = () => {
if (timer) { if (timer) {
return; return;
} }
timer = setTimeout(async() => { timer = setTimeout(async() => {
try { try {
await this.loadMissedMessages({ rid, t }); clearTimeout(timer);
timer = false; timer = false;
loop(); if (this.sdk.userId) {
await this.loadMissedMessages({ rid });
loop();
}
} catch (e) { } catch (e) {
loop(time); loop();
} }
}, 5000); }, 5000);
}; };
// if (!this.connected()) { this.sdk.onStreamData('connected', () => {
// loop(); if (this.sdk.userId) {
// } else { this.loadMissedMessages({ rid });
SDK.driver.on('logged', () => { }
clearTimeout(timer); clearTimeout(timer);
timer = false; timer = false;
}); });
SDK.driver.on('disconnected', () => { this.sdk.onStreamData('close', () => {
if (SDK.driver.userId) { loop();
loop();
}
}); });
try { try {
promises = subscribe(rid); promises = this.sdk.subscribeRoom(rid);
} catch (e) { } catch (e) {
log('subscribeRoom', e); log('subscribeRoom', e);
} }
// }
return { return {
stop: () => stop() stop: () => stop()

View File

@ -1,5 +1,3 @@
import * as SDK from '@rocket.chat/sdk';
import database from '../../realm'; import database from '../../realm';
import { merge } from '../helpers/mergeSubscriptionsRooms'; import { merge } from '../helpers/mergeSubscriptionsRooms';
import protectedFunction from '../helpers/protectedFunction'; import protectedFunction from '../helpers/protectedFunction';
@ -7,46 +5,39 @@ import messagesStatus from '../../../constants/messagesStatus';
import log from '../../../utils/log'; import log from '../../../utils/log';
import random from '../../../utils/random'; import random from '../../../utils/random';
export default async function subscribeRooms(id) { export default async function subscribeRooms() {
const promises = Promise.all([
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; let timer = null;
const loop = (time = new Date()) => { const loop = () => {
if (timer) { if (timer) {
return; return;
} }
timer = setTimeout(async() => { timer = setTimeout(async() => {
try { try {
await this.getRooms(time); clearTimeout(timer);
timer = false; timer = false;
loop(); if (this.sdk.userId) {
await this.getRooms();
loop();
}
} catch (e) { } catch (e) {
loop(time); loop();
} }
}, 5000); }, 5000);
}; };
SDK.driver.on('logged', () => { this.sdk.onStreamData('connected', () => {
if (this.sdk.userId) {
this.getRooms();
}
clearTimeout(timer); clearTimeout(timer);
timer = false; timer = false;
}); });
SDK.driver.on('logout', () => { this.sdk.onStreamData('close', () => {
clearTimeout(timer); loop();
timer = true;
}); });
SDK.driver.on('disconnected', () => { this.sdk.onStreamData('stream-notify-user', protectedFunction((ddpMessage) => {
if (SDK.driver.userId) {
loop();
}
});
SDK.driver.on('stream-notify-user', protectedFunction((e, ddpMessage) => {
if (ddpMessage.msg === 'added') { if (ddpMessage.msg === 'added') {
return; return;
} }
@ -77,7 +68,8 @@ export default async function subscribeRooms(id) {
if (type === 'updated') { if (type === 'updated') {
const [sub] = database.objects('subscriptions').filtered('rid == $0', data._id); const [sub] = database.objects('subscriptions').filtered('rid == $0', data._id);
database.write(() => { database.write(() => {
merge(sub, data); const tmp = merge(sub, data);
database.create('subscriptions', tmp, true);
}); });
} else if (type === 'inserted') { } else if (type === 'inserted') {
database.write(() => { database.write(() => {
@ -107,7 +99,7 @@ export default async function subscribeRooms(id) {
})); }));
try { try {
await promises; await this.sdk.subscribeNotifyUser();
} catch (e) { } catch (e) {
log('subscribeRooms', e); log('subscribeRooms', e);
} }

View File

@ -1,14 +1,14 @@
import { AsyncStorage } from 'react-native'; import { AsyncStorage } from 'react-native';
import foreach from 'lodash/forEach'; import foreach from 'lodash/forEach';
import * as SDK from '@rocket.chat/sdk';
import semver from 'semver'; import semver from 'semver';
import { Rocketchat as RocketchatClient } from '@rocket.chat/sdk';
import reduxStore from './createStore'; import reduxStore from './createStore';
import defaultSettings from '../constants/settings'; import defaultSettings from '../constants/settings';
import messagesStatus from '../constants/messagesStatus'; import messagesStatus from '../constants/messagesStatus';
import database from './realm'; import database from './realm';
import log from '../utils/log'; import log from '../utils/log';
import { isIOS } from '../utils/deviceInfo'; import { isIOS, getBundleId } from '../utils/deviceInfo';
import { import {
setUser, setLoginServices, loginRequest, loginFailure, logout setUser, setLoginServices, loginRequest, loginFailure, logout
@ -42,7 +42,6 @@ import { getDeviceToken } from '../push';
const TOKEN_KEY = 'reactnativemeteor_usertoken'; const TOKEN_KEY = 'reactnativemeteor_usertoken';
const SORT_PREFS_KEY = 'RC_SORT_PREFS_KEY'; const SORT_PREFS_KEY = 'RC_SORT_PREFS_KEY';
const call = (method, ...params) => SDK.driver.asyncCall(method, ...params);
const returnAnArray = obj => obj || []; const returnAnArray = obj => obj || [];
const MIN_ROCKETCHAT_VERSION = '0.66.0'; const MIN_ROCKETCHAT_VERSION = '0.66.0';
@ -55,7 +54,7 @@ const RocketChat = {
name, users, type, readOnly, broadcast name, users, type, readOnly, broadcast
}) { }) {
// RC 0.51.0 // RC 0.51.0
return call(type ? 'createPrivateGroup' : 'createChannel', name, users, readOnly, {}, { broadcast }); return this.sdk.methodCall(type ? 'createPrivateGroup' : 'createChannel', name, users, readOnly, {}, { broadcast });
}, },
async createDirectMessageAndWait(username) { async createDirectMessageAndWait(username) {
const room = await RocketChat.createDirectMessage(username); const room = await RocketChat.createDirectMessage(username);
@ -134,67 +133,61 @@ const RocketChat = {
} }
}, },
loginSuccess({ user }) { loginSuccess({ user }) {
SDK.driver.login({ resume: user.token });
reduxStore.dispatch(setUser(user)); reduxStore.dispatch(setUser(user));
this.getRooms().catch(e => console.log(e)); this.getRooms().catch(e => console.log(e));
this.subscribeRooms();
this.sdk.subscribe('activeUsers');
this.sdk.subscribe('roles');
this.getPermissions(); this.getPermissions();
this.getCustomEmoji(); this.getCustomEmoji();
this.registerPushToken().then(result => console.log(result)).catch(e => alert(e)); this.registerPushToken().then(result => console.log(result)).catch(e => console.log(e));
}, },
connect({ server, user }) { connect({ server, user }) {
database.setActiveDB(server); database.setActiveDB(server);
reduxStore.dispatch(connectRequest());
if (this.ddp) { if (this.connectTimeout) {
RocketChat.disconnect(); clearTimeout(this.connectTimeout);
this.ddp = null;
}
SDK.api.setBaseUrl(server);
this.getSettings();
if (user && user.token) {
reduxStore.dispatch(loginRequest({ resume: user.token }));
} }
// Use useSsl: false only if server url starts with http:// // Use useSsl: false only if server url starts with http://
const useSsl = !/http:\/\//.test(server); const useSsl = !/http:\/\//.test(server);
reduxStore.dispatch(connectRequest()); this.sdk = new RocketchatClient({ host: server, protocol: 'ddp', useSsl });
SDK.driver.connect({ host: server, useSsl }, (err, ddp) => { this.getSettings();
if (err) {
return console.warn(err);
}
this.ddp = ddp;
if (user && user.token) {
SDK.driver.login({ resume: user.token });
}
});
SDK.driver.on('connected', () => { this.sdk.connect()
.then(() => {
if (user && user.token) {
reduxStore.dispatch(loginRequest({ resume: user.token }));
}
})
.catch((err) => {
console.log('connect error', err);
// when `connect` raises an error, we try again in 10 seconds
this.connectTimeout = setTimeout(() => {
this.connect({ server, user });
}, 10000);
});
this.sdk.onStreamData('connected', () => {
reduxStore.dispatch(connectSuccess()); reduxStore.dispatch(connectSuccess());
}); });
SDK.driver.on('disconnected', protectedFunction(() => { this.sdk.onStreamData('close', () => {
reduxStore.dispatch(disconnect()); reduxStore.dispatch(disconnect());
})); });
SDK.driver.on('logged', protectedFunction((error, u) => { this.sdk.onStreamData('users', protectedFunction(ddpMessage => RocketChat._setUser(ddpMessage)));
this.subscribeRooms(u.id);
SDK.driver.subscribe('activeUsers');
SDK.driver.subscribe('roles');
}));
SDK.driver.on('forbidden', protectedFunction(() => reduxStore.dispatch(logout()))); this.sdk.onStreamData('stream-room-messages', (ddpMessage) => {
SDK.driver.on('users', protectedFunction((error, ddpMessage) => RocketChat._setUser(ddpMessage)));
SDK.driver.on('stream-room-messages', (error, ddpMessage) => {
// TODO: debounce // TODO: debounce
const message = _buildMessage(ddpMessage.fields.args[0]); const message = _buildMessage(ddpMessage.fields.args[0]);
requestAnimationFrame(() => reduxStore.dispatch(roomMessageReceived(message))); requestAnimationFrame(() => reduxStore.dispatch(roomMessageReceived(message)));
}); });
SDK.driver.on('stream-notify-room', protectedFunction((error, ddpMessage) => { this.sdk.onStreamData('stream-notify-room', protectedFunction((ddpMessage) => {
const [_rid, ev] = ddpMessage.fields.eventName.split('/'); const [_rid, ev] = ddpMessage.fields.eventName.split('/');
if (ev === 'typing') { if (ev === 'typing') {
reduxStore.dispatch(someoneTyping({ _rid, username: ddpMessage.fields.args[0], typing: ddpMessage.fields.args[1] })); reduxStore.dispatch(someoneTyping({ _rid, username: ddpMessage.fields.args[0], typing: ddpMessage.fields.args[1] }));
@ -209,7 +202,7 @@ const RocketChat = {
} }
})); }));
SDK.driver.on('rocketchat_snippeted_message', protectedFunction((error, ddpMessage) => { this.sdk.onStreamData('rocketchat_snippeted_message', protectedFunction((ddpMessage) => {
if (ddpMessage.msg === 'added') { if (ddpMessage.msg === 'added') {
this.snippetedMessages = this.snippetedMessages || []; this.snippetedMessages = this.snippetedMessages || [];
@ -230,7 +223,7 @@ const RocketChat = {
} }
})); }));
SDK.driver.on('rocketchat_roles', protectedFunction((error, ddpMessage) => { this.sdk.onStreamData('rocketchat_roles', protectedFunction((ddpMessage) => {
this.roles = this.roles || {}; this.roles = this.roles || {};
if (this.roleTimer) { if (this.roleTimer) {
@ -255,17 +248,17 @@ const RocketChat = {
register(credentials) { register(credentials) {
// RC 0.50.0 // RC 0.50.0
return SDK.api.post('users.register', credentials, false); return this.sdk.post('users.register', credentials, false);
}, },
setUsername(username) { setUsername(username) {
// RC 0.51.0 // RC 0.51.0
return call('setUsername', username); return this.sdk.methodCall('setUsername', username);
}, },
forgotPassword(email) { forgotPassword(email) {
// RC 0.64.0 // RC 0.64.0
return SDK.api.post('users.forgotPassword', { email }, false); return this.sdk.post('users.forgotPassword', { email }, false);
}, },
async loginWithPassword({ user, password, code }) { async loginWithPassword({ user, password, code }) {
@ -302,7 +295,7 @@ const RocketChat = {
async loginOAuth(params) { async loginOAuth(params) {
try { try {
const result = await SDK.driver.login(params); const result = await this.login(params);
reduxStore.dispatch(loginRequest({ resume: result.token })); reduxStore.dispatch(loginRequest({ resume: result.token }));
} catch (error) { } catch (error) {
throw error; throw error;
@ -312,14 +305,29 @@ const RocketChat = {
async login(params) { async login(params) {
try { try {
// RC 0.64.0 // RC 0.64.0
return await SDK.api.login(params); await this.sdk.login(params);
const { result } = this.sdk.currentLogin;
const user = {
id: result.userId,
token: result.authToken,
username: result.me.username,
name: result.me.name,
language: result.me.language,
status: result.me.status,
customFields: result.me.customFields,
emails: result.me.emails
};
return user;
} catch (e) { } catch (e) {
reduxStore.dispatch(loginFailure(e)); if (e.data && e.data.message && /you've been logged out by the server/i.test(e.data.message)) {
reduxStore.dispatch(logout({ server: this.sdk.client.host }));
} else {
reduxStore.dispatch(loginFailure(e));
}
throw e; throw e;
} }
}, },
async logout({ server }) { async logout({ server }) {
// this.removePushToken().catch(error => console.log(error));
try { try {
await this.removePushToken(); await this.removePushToken();
} catch (error) { } catch (error) {
@ -327,12 +335,11 @@ const RocketChat = {
} }
try { try {
// RC 0.60.0 // RC 0.60.0
await SDK.api.logout(); await this.sdk.logout();
} catch (error) { } catch (error) {
console.log('logout -> api logout -> catch -> error', error); console.log('logout -> api logout -> catch -> error', error);
} }
SDK.driver.ddp.disconnect(); this.sdk = null;
this.ddp = null;
Promise.all([ Promise.all([
AsyncStorage.removeItem('currentServer'), AsyncStorage.removeItem('currentServer'),
@ -346,18 +353,6 @@ const RocketChat = {
console.log(error); console.log(error);
} }
}, },
disconnect() {
try {
SDK.driver.unsubscribeAll();
} catch (error) {
console.log(error);
}
RocketChat.setApiUser({ userId: null, authToken: null });
},
setApiUser({ userId, authToken }) {
SDK.api.setAuth({ userId, authToken });
SDK.api.currentLogin = null;
},
registerPushToken() { registerPushToken() {
return new Promise((resolve) => { return new Promise((resolve) => {
const token = getDeviceToken(); const token = getDeviceToken();
@ -366,10 +361,10 @@ const RocketChat = {
const data = { const data = {
value: token, value: token,
type, type,
appName: 'chat.rocket.reactnative' // TODO: try to get from config file appName: getBundleId
}; };
// RC 0.60.0 // RC 0.60.0
return SDK.api.post('push.token', data); return this.sdk.post('push.token', data);
} }
return resolve(); return resolve();
}); });
@ -378,7 +373,7 @@ const RocketChat = {
const token = getDeviceToken(); const token = getDeviceToken();
if (token) { if (token) {
// RC 0.60.0 // RC 0.60.0
return SDK.api.del('push.token', { token }); return this.sdk.del('push.token', { token });
} }
return Promise.resolve(); return Promise.resolve();
}, },
@ -458,17 +453,17 @@ const RocketChat = {
spotlight(search, usernames, type) { spotlight(search, usernames, type) {
// RC 0.51.0 // RC 0.51.0
return call('spotlight', search, usernames, type); return this.sdk.methodCall('spotlight', search, usernames, type);
}, },
createDirectMessage(username) { createDirectMessage(username) {
// RC 0.59.0 // RC 0.59.0
return SDK.api.post('im.create', { username }); return this.sdk.post('im.create', { username });
}, },
joinRoom(roomId) { joinRoom(roomId) {
// TODO: join code // TODO: join code
// RC 0.48.0 // RC 0.48.0
return SDK.api.post('channels.join', { roomId }); return this.sdk.post('channels.join', { roomId });
}, },
sendFileMessage, sendFileMessage,
cancelUpload, cancelUpload,
@ -502,28 +497,28 @@ const RocketChat = {
deleteMessage(message) { deleteMessage(message) {
const { _id, rid } = message; const { _id, rid } = message;
// RC 0.48.0 // RC 0.48.0
return SDK.api.post('chat.delete', { roomId: rid, msgId: _id }); return this.sdk.post('chat.delete', { roomId: rid, msgId: _id });
}, },
editMessage(message) { editMessage(message) {
const { _id, msg, rid } = message; const { _id, msg, rid } = message;
// RC 0.49.0 // RC 0.49.0
return SDK.api.post('chat.update', { roomId: rid, msgId: _id, text: msg }); return this.sdk.post('chat.update', { roomId: rid, msgId: _id, text: msg });
}, },
toggleStarMessage(message) { toggleStarMessage(message) {
if (message.starred) { if (message.starred) {
// RC 0.59.0 // RC 0.59.0
return SDK.api.post('chat.unStarMessage', { messageId: message._id }); return this.sdk.post('chat.unStarMessage', { messageId: message._id });
} }
// RC 0.59.0 // RC 0.59.0
return SDK.api.post('chat.starMessage', { messageId: message._id }); return this.sdk.post('chat.starMessage', { messageId: message._id });
}, },
togglePinMessage(message) { togglePinMessage(message) {
if (message.pinned) { if (message.pinned) {
// RC 0.59.0 // RC 0.59.0
return SDK.api.post('chat.unPinMessage', { messageId: message._id }); return this.sdk.post('chat.unPinMessage', { messageId: message._id });
} }
// RC 0.59.0 // RC 0.59.0
return SDK.api.post('chat.pinMessage', { messageId: message._id }); return this.sdk.post('chat.pinMessage', { messageId: message._id });
}, },
getRoom(rid) { getRoom(rid) {
const [result] = database.objects('subscriptions').filtered('rid = $0', rid); const [result] = database.objects('subscriptions').filtered('rid = $0', rid);
@ -537,7 +532,7 @@ const RocketChat = {
try { try {
room = await RocketChat.getRoom(message.rid); room = await RocketChat.getRoom(message.rid);
} catch (e) { } catch (e) {
log('SDK.getPermalink', e); log('Rocketchat.getPermalink', e);
return null; return null;
} }
const { server } = reduxStore.getState().server; const { server } = reduxStore.getState().server;
@ -549,43 +544,43 @@ const RocketChat = {
return `${ server }/${ roomType }/${ room.name }?msg=${ message._id }`; return `${ server }/${ roomType }/${ room.name }?msg=${ message._id }`;
}, },
subscribe(...args) { subscribe(...args) {
return SDK.driver.subscribe(...args); return this.sdk.subscribe(...args);
}, },
unsubscribe(subscription) { unsubscribe(subscription) {
return SDK.driver.unsubscribe(subscription); return this.sdk.unsubscribe(subscription);
}, },
emitTyping(room, t = true) { emitTyping(room, t = true) {
const { login } = reduxStore.getState(); const { login } = reduxStore.getState();
return call('stream-notify-room', `${ room }/typing`, login.user.username, t); return this.sdk.methodCall('stream-notify-room', `${ room }/typing`, login.user.username, t);
}, },
setUserPresenceAway() { setUserPresenceAway() {
return call('UserPresence:away'); return this.sdk.methodCall('UserPresence:away');
}, },
setUserPresenceOnline() { setUserPresenceOnline() {
return call('UserPresence:online'); return this.sdk.methodCall('UserPresence:online');
}, },
setUserPresenceDefaultStatus(status) { setUserPresenceDefaultStatus(status) {
return call('UserPresence:setDefaultStatus', status); return this.sdk.methodCall('UserPresence:setDefaultStatus', status);
}, },
setReaction(emoji, messageId) { setReaction(emoji, messageId) {
// RC 0.62.2 // RC 0.62.2
return SDK.api.post('chat.react', { emoji, messageId }); return this.sdk.post('chat.react', { emoji, messageId });
}, },
toggleFavorite(roomId, favorite) { toggleFavorite(roomId, favorite) {
// RC 0.64.0 // RC 0.64.0
return SDK.api.post('rooms.favorite', { roomId, favorite }); return this.sdk.post('rooms.favorite', { roomId, favorite });
}, },
getRoomMembers(rid, allUsers) { getRoomMembers(rid, allUsers) {
// RC 0.42.0 // RC 0.42.0
return call('getUsersOfRoom', rid, allUsers); return this.sdk.methodCall('getUsersOfRoom', rid, allUsers);
}, },
getUserRoles() { getUserRoles() {
// RC 0.27.0 // RC 0.27.0
return call('getUserRoles'); return this.sdk.methodCall('getUserRoles');
}, },
getRoomCounters(roomId, t) { getRoomCounters(roomId, t) {
// RC 0.65.0 // RC 0.65.0
return SDK.api.get(`${ this.roomTypeToApiType(t) }.counters`, { roomId }); return this.sdk.get(`${ this.roomTypeToApiType(t) }.counters`, { roomId });
}, },
async getRoomMember(rid, currentUserId) { async getRoomMember(rid, currentUserId) {
try { try {
@ -601,56 +596,56 @@ const RocketChat = {
toggleBlockUser(rid, blocked, block) { toggleBlockUser(rid, blocked, block) {
if (block) { if (block) {
// RC 0.49.0 // RC 0.49.0
return call('blockUser', { rid, blocked }); return this.sdk.methodCall('blockUser', { rid, blocked });
} }
// RC 0.49.0 // RC 0.49.0
return call('unblockUser', { rid, blocked }); return this.sdk.methodCall('unblockUser', { rid, blocked });
}, },
leaveRoom(roomId, t) { leaveRoom(roomId, t) {
// RC 0.48.0 // RC 0.48.0
return SDK.api.post(`${ this.roomTypeToApiType(t) }.leave`, { roomId }); return this.sdk.post(`${ this.roomTypeToApiType(t) }.leave`, { roomId });
}, },
eraseRoom(roomId, t) { eraseRoom(roomId, t) {
// RC 0.49.0 // RC 0.49.0
return SDK.api.post(`${ this.roomTypeToApiType(t) }.delete`, { roomId }); return this.sdk.post(`${ this.roomTypeToApiType(t) }.delete`, { roomId });
}, },
toggleMuteUserInRoom(rid, username, mute) { toggleMuteUserInRoom(rid, username, mute) {
if (mute) { if (mute) {
// RC 0.51.0 // RC 0.51.0
return call('muteUserInRoom', { rid, username }); return this.sdk.methodCall('muteUserInRoom', { rid, username });
} }
// RC 0.51.0 // RC 0.51.0
return call('unmuteUserInRoom', { rid, username }); return this.sdk.methodCall('unmuteUserInRoom', { rid, username });
}, },
toggleArchiveRoom(roomId, t, archive) { toggleArchiveRoom(roomId, t, archive) {
if (archive) { if (archive) {
// RC 0.48.0 // RC 0.48.0
return SDK.api.post(`${ this.roomTypeToApiType(t) }.archive`, { roomId }); return this.sdk.post(`${ this.roomTypeToApiType(t) }.archive`, { roomId });
} }
// RC 0.48.0 // RC 0.48.0
return SDK.api.post(`${ this.roomTypeToApiType(t) }.unarchive`, { roomId }); return this.sdk.post(`${ this.roomTypeToApiType(t) }.unarchive`, { roomId });
}, },
saveRoomSettings(rid, params) { saveRoomSettings(rid, params) {
// RC 0.55.0 // RC 0.55.0
return call('saveRoomSettings', rid, params); return this.sdk.methodCall('saveRoomSettings', rid, params);
}, },
saveUserProfile(data) { saveUserProfile(data) {
// RC 0.62.2 // RC 0.62.2
return SDK.api.post('users.updateOwnBasicInfo', { data }); return this.sdk.post('users.updateOwnBasicInfo', { data });
}, },
saveUserPreferences(params) { saveUserPreferences(params) {
// RC 0.51.0 // RC 0.51.0
return call('saveUserPreferences', params); return this.sdk.methodCall('saveUserPreferences', params);
}, },
saveNotificationSettings(roomId, notifications) { saveNotificationSettings(roomId, notifications) {
// RC 0.63.0 // RC 0.63.0
return SDK.api.post('rooms.saveNotification', { roomId, notifications }); return this.sdk.post('rooms.saveNotification', { roomId, notifications });
}, },
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);
// RC 0.51.0 // RC 0.51.0
return call('addUsersToRoom', { rid, users }); return this.sdk.methodCall('addUsersToRoom', { rid, users });
}, },
hasPermission(permissions, rid) { hasPermission(permissions, rid) {
let roles = []; let roles = [];
@ -685,15 +680,15 @@ const RocketChat = {
}, },
getAvatarSuggestion() { getAvatarSuggestion() {
// RC 0.51.0 // RC 0.51.0
return call('getAvatarSuggestion'); return this.sdk.methodCall('getAvatarSuggestion');
}, },
resetAvatar(userId) { resetAvatar(userId) {
// RC 0.55.0 // RC 0.55.0
return SDK.api.post('users.resetAvatar', { userId }); return this.sdk.post('users.resetAvatar', { userId });
}, },
setAvatarFromService({ data, contentType = '', service = null }) { setAvatarFromService({ data, contentType = '', service = null }) {
// RC 0.51.0 // RC 0.51.0
return call('setAvatarFromService', data, contentType, service); return this.sdk.methodCall('setAvatarFromService', data, contentType, service);
}, },
async getSortPreferences() { async getSortPreferences() {
const prefs = await AsyncStorage.getItem(SORT_PREFS_KEY); const prefs = await AsyncStorage.getItem(SORT_PREFS_KEY);
@ -731,7 +726,7 @@ const RocketChat = {
}, },
getUsernameSuggestion() { getUsernameSuggestion() {
// RC 0.65.0 // RC 0.65.0
return SDK.api.get('users.getUsernameSuggestion'); return this.sdk.get('users.getUsernameSuggestion');
}, },
roomTypeToApiType(t) { roomTypeToApiType(t) {
const types = { const types = {
@ -741,7 +736,7 @@ const RocketChat = {
}, },
getFiles(roomId, type, offset) { getFiles(roomId, type, offset) {
// RC 0.59.0 // RC 0.59.0
return SDK.api.get(`${ this.roomTypeToApiType(type) }.files`, { return this.sdk.get(`${ this.roomTypeToApiType(type) }.files`, {
roomId, roomId,
offset, offset,
sort: { uploadedAt: -1 }, sort: { uploadedAt: -1 },
@ -752,7 +747,7 @@ const RocketChat = {
}, },
getMessages(roomId, type, query, offset) { getMessages(roomId, type, query, offset) {
// RC 0.59.0 // RC 0.59.0
return SDK.api.get(`${ this.roomTypeToApiType(type) }.messages`, { return this.sdk.get(`${ this.roomTypeToApiType(type) }.messages`, {
roomId, roomId,
query, query,
offset, offset,
@ -761,7 +756,7 @@ const RocketChat = {
}, },
searchMessages(roomId, searchText) { searchMessages(roomId, searchText) {
// RC 0.60.0 // RC 0.60.0
return SDK.api.get('chat.search', { return this.sdk.get('chat.search', {
roomId, roomId,
searchText searchText
}); });

View File

@ -25,19 +25,7 @@ const handleLoginRequest = function* handleLoginRequest({ credentials }) {
} else { } else {
result = yield call(loginWithPasswordCall, credentials); result = yield call(loginWithPasswordCall, credentials);
} }
if (result.status === 'success') { return yield put(loginSuccess(result));
const { data } = result;
const user = {
id: data.userId,
token: data.authToken,
username: data.me.username,
name: data.me.name,
language: data.me.language,
status: data.me.status,
customFields: data.me.customFields
};
return yield put(loginSuccess(user));
}
} catch (error) { } catch (error) {
yield put(loginFailure(error)); yield put(loginFailure(error));
} }

View File

@ -3,6 +3,7 @@ import {
put, call, takeLatest, take, select, race, fork, cancel, takeEvery put, call, takeLatest, take, select, race, fork, cancel, takeEvery
} from 'redux-saga/effects'; } from 'redux-saga/effects';
import { delay } from 'redux-saga'; import { delay } from 'redux-saga';
import EJSON from 'ejson';
import Navigation from '../lib/Navigation'; import Navigation from '../lib/Navigation';
import * as types from '../actions/actionsTypes'; import * as types from '../actions/actionsTypes';
@ -45,7 +46,7 @@ const handleMessageReceived = function* handleMessageReceived({ message }) {
if (message.rid === room.rid) { if (message.rid === room.rid) {
database.write(() => { database.write(() => {
database.create('messages', message, true); database.create('messages', EJSON.fromJSONValue(message), true);
}); });
if (room._id) { if (room._id) {

View File

@ -7,10 +7,12 @@ export const isNotch = NOTCH_DEVICES.includes(DeviceInfo.getModel());
export const isIOS = Platform.OS === 'ios'; export const isIOS = Platform.OS === 'ios';
export const isAndroid = !isIOS; export const isAndroid = !isIOS;
export const getReadableVersion = DeviceInfo.getReadableVersion(); export const getReadableVersion = DeviceInfo.getReadableVersion();
export const getBundleId = DeviceInfo.getBundleId();
export default { export default {
isNotch, isNotch,
isIOS, isIOS,
isAndroid, isAndroid,
getReadableVersion getReadableVersion,
getBundleId
}; };

View File

@ -48,7 +48,7 @@ const styles = StyleSheet.create({
@connect(state => ({ @connect(state => ({
isFetching: state.login.isFetching, isFetching: state.login.isFetching,
failure: state.login.failure, failure: state.login.failure,
error: state.login.error, error: state.login.error && state.login.error.data,
Site_Name: state.settings.Site_Name, Site_Name: state.settings.Site_Name,
Accounts_EmailOrUsernamePlaceholder: state.settings.Accounts_EmailOrUsernamePlaceholder, Accounts_EmailOrUsernamePlaceholder: state.settings.Accounts_EmailOrUsernamePlaceholder,
Accounts_PasswordPlaceholder: state.settings.Accounts_PasswordPlaceholder Accounts_PasswordPlaceholder: state.settings.Accounts_PasswordPlaceholder
@ -200,7 +200,7 @@ export default class LoginView extends LoggedView {
return user.trim() && password.trim(); return user.trim() && password.trim();
} }
submit = async() => { submit = () => {
if (!this.valid()) { if (!this.valid()) {
return; return;
} }
@ -208,23 +208,8 @@ export default class LoginView extends LoggedView {
const { user, password, code } = this.state; const { user, password, code } = this.state;
const { loginRequest } = this.props; const { loginRequest } = this.props;
Keyboard.dismiss(); Keyboard.dismiss();
loginRequest({ user, password, code });
try { Answers.logLogin('Email', true);
await loginRequest({ user, password, code });
Answers.logLogin('Email', true);
} catch (e) {
if (e && e.error === 'totp-required') {
LayoutAnimation.easeInEaseOut();
this.setState({ showTOTP: true });
setTimeout(() => {
if (this.codeInput && this.codeInput.focus) {
this.codeInput.focus();
}
}, 300);
return;
}
Alert.alert(I18n.t('Oops'), I18n.t('Login_error'));
}
} }
register = () => { register = () => {

View File

@ -42,7 +42,8 @@ export default class RegisterView extends LoggedView {
static propTypes = { static propTypes = {
componentId: PropTypes.string, componentId: PropTypes.string,
loginRequest: PropTypes.func loginRequest: PropTypes.func,
Site_Name: PropTypes.string
} }
constructor(props) { constructor(props) {

View File

@ -6,6 +6,7 @@ import {
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { RectButton } from 'react-native-gesture-handler'; import { RectButton } from 'react-native-gesture-handler';
import SafeAreaView from 'react-native-safe-area-view'; import SafeAreaView from 'react-native-safe-area-view';
import equal from 'deep-equal';
import Navigation from '../../lib/Navigation'; import Navigation from '../../lib/Navigation';
import { openRoom as openRoomAction, closeRoom as closeRoomAction, setLastOpen as setLastOpenAction } from '../../actions/room'; import { openRoom as openRoomAction, closeRoom as closeRoomAction, setLastOpen as setLastOpenAction } from '../../actions/room';
@ -99,7 +100,6 @@ export default class RoomView extends LoggedView {
joined: this.rooms.length > 0, joined: this.rooms.length > 0,
room: {} room: {}
}; };
this.focused = true;
this.onReactionPress = this.onReactionPress.bind(this); this.onReactionPress = this.onReactionPress.bind(this);
Navigation.events().bindComponent(this); Navigation.events().bindComponent(this);
} }
@ -142,6 +142,8 @@ export default class RoomView extends LoggedView {
return true; return true;
} else if (appState !== nextProps.appState) { } else if (appState !== nextProps.appState) {
return true; return true;
} else if (!equal(room.muted, nextState.room.muted)) {
return true;
} }
return false; return false;
} }
@ -180,16 +182,6 @@ export default class RoomView extends LoggedView {
this.rooms.removeAllListeners(); this.rooms.removeAllListeners();
} }
// eslint-disable-next-line
componentDidAppear() {
this.focused = true;
}
// eslint-disable-next-line
componentDidDisappear() {
this.focused = false;
}
onMessageLongPress = (message) => { onMessageLongPress = (message) => {
const { actionsShow } = this.props; const { actionsShow } = this.props;
actionsShow(message); actionsShow(message);
@ -243,9 +235,6 @@ export default class RoomView extends LoggedView {
updateRoom = () => { updateRoom = () => {
const { openRoom, setLastOpen } = this.props; const { openRoom, setLastOpen } = this.props;
if (!this.focused) {
return;
}
if (this.rooms.length > 0) { if (this.rooms.length > 0) {
const { room: prevRoom } = this.state; const { room: prevRoom } = this.state;
const room = JSON.parse(JSON.stringify(this.rooms[0] || {})); const room = JSON.parse(JSON.stringify(this.rooms[0] || {}));
@ -300,12 +289,12 @@ export default class RoomView extends LoggedView {
isMuted = () => { isMuted = () => {
const { room } = this.state; const { room } = this.state;
const { user } = this.props; const { user } = this.props;
return room && room.muted && Array.from(Object.keys(room.muted), i => room.muted[i].value).includes(user.username); return room && room.muted && !!Array.from(Object.keys(room.muted), i => room.muted[i].value).includes(user.username);
} }
isReadOnly = () => { isReadOnly = () => {
const { room } = this.state; const { room } = this.state;
return room.ro && this.isMuted() && !this.isOwner(); return (room.ro && !room.broadcast) || this.isMuted() || room.archived;
} }
isBlocked = () => { isBlocked = () => {
@ -342,7 +331,7 @@ export default class RoomView extends LoggedView {
} }
renderFooter = () => { renderFooter = () => {
const { joined, room } = this.state; const { joined } = this.state;
if (!joined) { if (!joined) {
return ( return (
@ -359,7 +348,7 @@ export default class RoomView extends LoggedView {
</View> </View>
); );
} }
if (room.archived || this.isReadOnly()) { if (this.isReadOnly()) {
return ( return (
<View style={styles.readOnly} key='room-view-read-only'> <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 File

@ -4,7 +4,6 @@ import {
} from 'react-native'; } from 'react-native';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import * as SDK from '@rocket.chat/sdk';
import equal from 'deep-equal'; import equal from 'deep-equal';
import Navigation from '../../lib/Navigation'; import Navigation from '../../lib/Navigation';
@ -139,7 +138,7 @@ export default class ServerDropdown extends Component {
if (!token) { if (!token) {
appStart(); appStart();
try { try {
SDK.driver.disconnect(); this.sdk.disconnect();
} catch (error) { } catch (error) {
console.warn(error); console.warn(error);
} }

View File

@ -43,7 +43,8 @@ export default class SetUsernameView extends LoggedView {
componentId: PropTypes.string, componentId: PropTypes.string,
server: PropTypes.string, server: PropTypes.string,
userId: PropTypes.string, userId: PropTypes.string,
loginRequest: PropTypes.func loginRequest: PropTypes.func,
token: PropTypes.string
} }
constructor(props) { constructor(props) {
@ -100,7 +101,6 @@ export default class SetUsernameView extends LoggedView {
this.setState({ saving: true }); this.setState({ saving: true });
try { try {
await RocketChat.setUsername(username); await RocketChat.setUsername(username);
RocketChat.setApiUser({ userId: null, authToken: null });
await loginRequest({ resume: token }); await loginRequest({ resume: token });
} catch (e) { } catch (e) {
console.log('SetUsernameView -> catch -> e', e); console.log('SetUsernameView -> catch -> e', e);

View File

@ -5,9 +5,9 @@ const data = {
alternateServer: 'https://unstable.rocket.chat', alternateServer: 'https://unstable.rocket.chat',
user: `user${ value }`, user: `user${ value }`,
password: `password${ value }`, password: `password${ value }`,
alternateUser: 'detox', alternateUser: 'detoxrn',
alternateUserPassword: '123', alternateUserPassword: '123',
alternateUserTOTPSecret: 'KFJW6SZMH5EUI5LHPJ2XCOKKGRHDA2ZDN5YD4YLBMMSSMVCEPJSQ', alternateUserTOTPSecret: 'KESVIUCQMZWEYNBMJJAUW4LYKRBVWYZ7HBWTIWDPIAZUOURTF4WA',
email: `diego.mello+e2e${ value }@rocket.chat`, email: `diego.mello+e2e${ value }@rocket.chat`,
random: value random: value
} }

24279
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -12,9 +12,7 @@
"log-android": "react-native log-android", "log-android": "react-native log-android",
"android": "react-native run-android", "android": "react-native run-android",
"storybook": "storybook start -p 7007 | react-native start --projectRoot storybook", "storybook": "storybook start -p 7007 | react-native start --projectRoot storybook",
"snyk-protect": "snyk protect", "snyk-protect": "snyk protect"
"fabric-ios": "./scripts/fabric-ios.sh",
"fabric-android": "./scripts/fabric-android.sh"
}, },
"rnpm": { "rnpm": {
"assets": [ "assets": [
@ -23,7 +21,7 @@
}, },
"dependencies": { "dependencies": {
"@remobile/react-native-toast": "^1.0.7", "@remobile/react-native-toast": "^1.0.7",
"@rocket.chat/sdk": "git+https://github.com/RocketChat/Rocket.Chat.js.SDK.git#temp-ddp", "@rocket.chat/sdk": "1.0.0-alpha.24",
"deep-equal": "^1.0.1", "deep-equal": "^1.0.1",
"ejson": "^2.1.2", "ejson": "^2.1.2",
"js-base64": "^2.5.1", "js-base64": "^2.5.1",
@ -52,7 +50,7 @@
"react-native-markdown-renderer": "^3.2.8", "react-native-markdown-renderer": "^3.2.8",
"react-native-modal": "^7.0.2", "react-native-modal": "^7.0.2",
"react-native-navigation": "^2.8.0", "react-native-navigation": "^2.8.0",
"react-native-notifications": "^1.1.23", "react-native-notifications": "1.1.23",
"react-native-optimized-flatlist": "^1.0.4", "react-native-optimized-flatlist": "^1.0.4",
"react-native-picker-select": "^5.2.3", "react-native-picker-select": "^5.2.3",
"react-native-responsive-ui": "^1.1.1", "react-native-responsive-ui": "^1.1.1",

13411
yarn.lock Normal file

File diff suppressed because it is too large Load Diff