Use Rest API calls (#558)
This commit is contained in:
parent
bef34f7f96
commit
a2821af95b
|
@ -34,7 +34,7 @@ exports[`Storyshots Avatar avatar 1`] = `
|
|||
source={
|
||||
Object {
|
||||
"priority": "high",
|
||||
"uri": "baseUrl/avatar/test?format=png&size=50",
|
||||
"uri": "baseUrl/avatar/test?format=png&width=50&height=50",
|
||||
}
|
||||
}
|
||||
style={
|
||||
|
@ -80,7 +80,7 @@ exports[`Storyshots Avatar avatar 1`] = `
|
|||
source={
|
||||
Object {
|
||||
"priority": "high",
|
||||
"uri": "baseUrl/avatar/aa?format=png&size=50",
|
||||
"uri": "baseUrl/avatar/aa?format=png&width=50&height=50",
|
||||
}
|
||||
}
|
||||
style={
|
||||
|
@ -126,7 +126,7 @@ exports[`Storyshots Avatar avatar 1`] = `
|
|||
source={
|
||||
Object {
|
||||
"priority": "high",
|
||||
"uri": "baseUrl/avatar/bb?format=png&size=50",
|
||||
"uri": "baseUrl/avatar/bb?format=png&width=50&height=50",
|
||||
}
|
||||
}
|
||||
style={
|
||||
|
@ -172,7 +172,7 @@ exports[`Storyshots Avatar avatar 1`] = `
|
|||
source={
|
||||
Object {
|
||||
"priority": "high",
|
||||
"uri": "baseUrl/avatar/test?format=png&size=50",
|
||||
"uri": "baseUrl/avatar/test?format=png&width=50&height=50",
|
||||
}
|
||||
}
|
||||
style={
|
||||
|
|
|
@ -17,4 +17,5 @@ if (__DEV__) {
|
|||
// $ adb reverse tcp:9090 tcp:9090
|
||||
Reactotron.clear();
|
||||
console.warn = Reactotron.log;
|
||||
console.log = Reactotron.log;
|
||||
}
|
||||
|
|
|
@ -11,19 +11,10 @@ function createRequestTypes(base, types = defaultTypes) {
|
|||
// Login events
|
||||
export const LOGIN = createRequestTypes('LOGIN', [
|
||||
...defaultTypes,
|
||||
'SET_TOKEN',
|
||||
'RESTORE_TOKEN',
|
||||
'SUBMIT',
|
||||
'REGISTER_SUBMIT',
|
||||
'REGISTER_REQUEST',
|
||||
'SET_USERNAME_SUBMIT',
|
||||
'SET_USERNAME_REQUEST',
|
||||
'SET_USERNAME_SUCCESS',
|
||||
'SET_SERVICES',
|
||||
'SET_PREFERENCE',
|
||||
'SET_SORT_PREFERENCE'
|
||||
]);
|
||||
export const FORGOT_PASSWORD = createRequestTypes('FORGOT_PASSWORD');
|
||||
export const USER = createRequestTypes('USER', ['SET']);
|
||||
export const ROOMS = createRequestTypes('ROOMS', [
|
||||
...defaultTypes,
|
||||
|
@ -82,7 +73,7 @@ export const SERVER = createRequestTypes('SERVER', [
|
|||
'INIT_ADD',
|
||||
'FINISH_ADD'
|
||||
]);
|
||||
export const METEOR = createRequestTypes('METEOR_CONNECT', [...defaultTypes, 'DISCONNECT', 'DISCONNECT_BY_USER']);
|
||||
export const METEOR = createRequestTypes('METEOR_CONNECT', [...defaultTypes, 'DISCONNECT']);
|
||||
export const LOGOUT = 'LOGOUT'; // logout is always success
|
||||
export const ACTIVE_USERS = createRequestTypes('ACTIVE_USERS', ['SET']);
|
||||
export const ROLES = createRequestTypes('ROLES', ['SET']);
|
||||
|
@ -93,6 +84,3 @@ export const SNIPPETED_MESSAGES = createRequestTypes('SNIPPETED_MESSAGES', ['OPE
|
|||
export const ROOM_FILES = createRequestTypes('ROOM_FILES', ['OPEN', 'READY', 'CLOSE', 'MESSAGES_RECEIVED']);
|
||||
export const DEEP_LINKING = createRequestTypes('DEEP_LINKING', ['OPEN']);
|
||||
export const SORT_PREFERENCES = createRequestTypes('SORT_PREFERENCES', ['SET_ALL', 'SET']);
|
||||
|
||||
export const INCREMENT = 'INCREMENT';
|
||||
export const DECREMENT = 'DECREMENT';
|
||||
|
|
|
@ -12,21 +12,9 @@ export function connectSuccess() {
|
|||
};
|
||||
}
|
||||
|
||||
export function connectFailure(err) {
|
||||
return {
|
||||
type: types.METEOR.FAILURE,
|
||||
err
|
||||
};
|
||||
}
|
||||
|
||||
export function disconnect(err) {
|
||||
return {
|
||||
type: types.METEOR.DISCONNECT,
|
||||
err
|
||||
};
|
||||
}
|
||||
export function disconnect_by_user() {
|
||||
return {
|
||||
type: types.METEOR.DISCONNECT_BY_USER
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
import * as types from './actionsTypes';
|
||||
|
||||
export function loginSubmit(credentials) {
|
||||
return {
|
||||
type: types.LOGIN.SUBMIT,
|
||||
credentials
|
||||
};
|
||||
}
|
||||
export function loginRequest(credentials) {
|
||||
return {
|
||||
type: types.LOGIN.REQUEST,
|
||||
|
@ -13,45 +7,10 @@ export function loginRequest(credentials) {
|
|||
};
|
||||
}
|
||||
|
||||
export function registerSubmit(credentials) {
|
||||
return {
|
||||
type: types.LOGIN.REGISTER_SUBMIT,
|
||||
credentials
|
||||
};
|
||||
}
|
||||
|
||||
export function registerRequest(credentials) {
|
||||
return {
|
||||
type: types.LOGIN.REGISTER_REQUEST,
|
||||
credentials
|
||||
};
|
||||
}
|
||||
|
||||
export function setUsernameSubmit(credentials) {
|
||||
return {
|
||||
type: types.LOGIN.SET_USERNAME_SUBMIT,
|
||||
credentials
|
||||
};
|
||||
}
|
||||
|
||||
export function setUsernameRequest(credentials) {
|
||||
return {
|
||||
type: types.LOGIN.SET_USERNAME_REQUEST,
|
||||
credentials
|
||||
};
|
||||
}
|
||||
|
||||
export function setUsernameSuccess() {
|
||||
return {
|
||||
type: types.LOGIN.SET_USERNAME_SUCCESS
|
||||
};
|
||||
}
|
||||
|
||||
export function loginSuccess(user) {
|
||||
return {
|
||||
type: types.LOGIN.SUCCESS,
|
||||
user,
|
||||
token: user.token
|
||||
user
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -62,58 +21,16 @@ export function loginFailure(err) {
|
|||
};
|
||||
}
|
||||
|
||||
export function setToken(user = {}) {
|
||||
return {
|
||||
type: types.LOGIN.SET_TOKEN,
|
||||
...user
|
||||
};
|
||||
}
|
||||
|
||||
export function restoreToken(token) {
|
||||
return {
|
||||
type: types.LOGIN.RESTORE_TOKEN,
|
||||
token
|
||||
};
|
||||
}
|
||||
|
||||
export function logout() {
|
||||
return {
|
||||
type: types.LOGOUT
|
||||
};
|
||||
}
|
||||
|
||||
export function forgotPasswordInit() {
|
||||
export function setUser(user) {
|
||||
return {
|
||||
type: types.FORGOT_PASSWORD.INIT
|
||||
};
|
||||
}
|
||||
|
||||
export function forgotPasswordRequest(email) {
|
||||
return {
|
||||
type: types.FORGOT_PASSWORD.REQUEST,
|
||||
email
|
||||
};
|
||||
}
|
||||
|
||||
export function forgotPasswordSuccess() {
|
||||
return {
|
||||
type: types.FORGOT_PASSWORD.SUCCESS
|
||||
};
|
||||
}
|
||||
|
||||
export function forgotPasswordFailure(err) {
|
||||
return {
|
||||
type: types.FORGOT_PASSWORD.FAILURE,
|
||||
err
|
||||
};
|
||||
}
|
||||
|
||||
export function setUser(action) {
|
||||
return {
|
||||
// do not change this params order
|
||||
// since we use spread operator, sometimes `type` is overriden
|
||||
...action,
|
||||
type: types.USER.SET
|
||||
type: types.USER.SET,
|
||||
user
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -35,17 +35,19 @@ export function closeRoom() {
|
|||
};
|
||||
}
|
||||
|
||||
export function leaveRoom(rid) {
|
||||
export function leaveRoom(rid, t) {
|
||||
return {
|
||||
type: types.ROOM.LEAVE,
|
||||
rid
|
||||
rid,
|
||||
t
|
||||
};
|
||||
}
|
||||
|
||||
export function eraseRoom(rid) {
|
||||
export function eraseRoom(rid, t) {
|
||||
return {
|
||||
type: types.ROOM.ERASE,
|
||||
rid
|
||||
rid,
|
||||
t
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,8 @@ export default {
|
|||
},
|
||||
UI_Use_Real_Name: {
|
||||
type: 'valueAsBoolean'
|
||||
},
|
||||
Assets_favicon_512: {
|
||||
type: null
|
||||
}
|
||||
};
|
||||
export const settingsUpdatedAt = new Date('2018-11-14');
|
||||
|
|
|
@ -33,8 +33,15 @@ export default class Avatar extends React.PureComponent {
|
|||
borderRadius
|
||||
};
|
||||
|
||||
if (!text && !avatar) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const room = type === 'd' ? text : `@${ text }`;
|
||||
const uri = avatar || `${ baseUrl }/avatar/${ room }?format=png&size=${ size === 100 ? 100 : 50 }`;
|
||||
// Avoid requesting several sizes by having only two sizes on cache
|
||||
const uriSize = size === 100 ? 100 : 50;
|
||||
const uri = avatar || `${ baseUrl }/avatar/${ room }?format=png&width=${ uriSize }&height=${ uriSize }`;
|
||||
|
||||
const image = (
|
||||
<FastImage
|
||||
style={avatarStyle}
|
||||
|
|
|
@ -245,10 +245,11 @@ export default class MessageActions extends React.Component {
|
|||
showToast(I18n.t('Copied_to_clipboard'));
|
||||
}
|
||||
|
||||
handleShare = () => {
|
||||
handleShare = async() => {
|
||||
const { actionMessage } = this.props;
|
||||
const permalink = await this.getPermalink(actionMessage);
|
||||
Share.share({
|
||||
message: actionMessage.msg.content.replace(/<(?:.|\n)*?>/gm, '')
|
||||
message: permalink
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -101,7 +101,6 @@ export default class extends React.PureComponent {
|
|||
}
|
||||
} catch (err) {
|
||||
this.finishRecording(false);
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import { connect } from 'react-redux';
|
|||
import Icon from 'react-native-vector-icons/MaterialIcons';
|
||||
import { Navigation } from 'react-native-navigation';
|
||||
|
||||
import { appStart as appStartAction, setStackRoot as setStackRootAction } from '../actions';
|
||||
import { setStackRoot as setStackRootAction } from '../actions';
|
||||
import { logout as logoutAction } from '../actions/login';
|
||||
import Avatar from './Avatar';
|
||||
import Status from './status';
|
||||
|
@ -95,7 +95,6 @@ const keyExtractor = item => item.id;
|
|||
baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
|
||||
}), dispatch => ({
|
||||
logout: () => dispatch(logoutAction()),
|
||||
appStart: () => dispatch(appStartAction('outside')),
|
||||
setStackRoot: stackRoot => dispatch(setStackRootAction(stackRoot))
|
||||
}))
|
||||
export default class Sidebar extends Component {
|
||||
|
@ -106,7 +105,6 @@ export default class Sidebar extends Component {
|
|||
stackRoot: PropTypes.string.isRequired,
|
||||
user: PropTypes.object,
|
||||
logout: PropTypes.func.isRequired,
|
||||
appStart: PropTypes.func,
|
||||
setStackRoot: PropTypes.func
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ export default class extends React.PureComponent {
|
|||
const { baseUrl, file, user } = this.props;
|
||||
const img = `${ baseUrl }${ file.image_url }?rc_uid=${ user.id }&rc_token=${ user.token }`;
|
||||
|
||||
if (!baseUrl) {
|
||||
if (!img) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
export default {
|
||||
'1_online_member': '1 online member',
|
||||
'1_person_reacted': '1 person reacted',
|
||||
'1_user': '1 user',
|
||||
'error-action-not-allowed': '{{action}} is not allowed',
|
||||
|
@ -184,6 +183,7 @@ export default {
|
|||
Login_error: 'Your credentials were rejected! Please try again.',
|
||||
Login_with: 'Login with',
|
||||
Logout: 'Logout',
|
||||
members: 'members',
|
||||
Members: 'Members',
|
||||
Mentioned_Messages: 'Mentioned Messages',
|
||||
mentioned: 'mentioned',
|
||||
|
@ -198,7 +198,6 @@ export default {
|
|||
Mute: 'Mute',
|
||||
muted: 'muted',
|
||||
My_servers: 'My servers',
|
||||
N_online_members: '{{n}} online members',
|
||||
N_people_reacted: '{{n}} people reacted',
|
||||
N_users: '{{n}} users',
|
||||
name: 'name',
|
||||
|
@ -254,6 +253,7 @@ export default {
|
|||
Reply: 'Reply',
|
||||
Resend: 'Resend',
|
||||
Reset_password: 'Reset password',
|
||||
resetting_password: 'resetting password',
|
||||
RESET: 'RESET',
|
||||
Roles: 'Roles',
|
||||
Room_actions: 'Room actions',
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
export default {
|
||||
'1_online_member': '1 membro online',
|
||||
'1_person_reacted': '1 pessoa reagiu',
|
||||
'1_user': '1 usuário',
|
||||
'error-action-not-allowed': '{{action}} não é permitido',
|
||||
|
@ -202,7 +201,6 @@ export default {
|
|||
Microphone_Permission: 'Acesso ao Microfone',
|
||||
Mute: 'Mudo',
|
||||
muted: 'mudo',
|
||||
N_online_members: '{{n}} membros online',
|
||||
N_people_reacted: '{{n}} pessoas reagiram',
|
||||
N_users: '{{n}} usuários',
|
||||
name: 'nome',
|
||||
|
@ -257,6 +255,7 @@ export default {
|
|||
Reply: 'Responder',
|
||||
Resend: 'Reenviar',
|
||||
Reset_password: 'Resetar senha',
|
||||
resetting_password: 'redefinindo senha',
|
||||
RESET: 'RESETAR',
|
||||
Roles: 'Papéis',
|
||||
Room_actions: 'Ações',
|
||||
|
@ -305,7 +304,7 @@ export default {
|
|||
Take_a_photo: 'Tirar uma foto',
|
||||
Terms_of_Service: ' Termos de Serviço ',
|
||||
The_URL_is_invalid: 'A URL fornecida é inválida ou não acessível. Por favor tente novamente, mas com uma url diferente.',
|
||||
There_was_an_error_while_action: 'Acontece um erro {{action}}!',
|
||||
There_was_an_error_while_action: 'Aconteceu um erro {{action}}!',
|
||||
This_room_is_blocked: 'Este quarto está bloqueado',
|
||||
This_room_is_read_only: 'Este quarto é apenas de leitura',
|
||||
Timezone: 'Fuso horário',
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
export default {
|
||||
'1_online_member': '1 участник онлайн',
|
||||
'1_person_reacted': '1 человек отреагировал',
|
||||
'error-action-not-allowed': '{{action}} не допускается',
|
||||
'error-application-not-found': 'Приложение не найдено',
|
||||
|
@ -175,7 +174,6 @@ export default {
|
|||
Mute: 'Заглушить',
|
||||
muted: 'Заглушен',
|
||||
My_servers: 'Мои серверы',
|
||||
N_online_members: '{{n}} пользователей онлайн',
|
||||
N_person_reacted: '{{n}} людей отреагировало',
|
||||
Name: 'Имя',
|
||||
New_in_RocketChat_question_mark: 'Новичок в Rocket.Chat?',
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
export default {
|
||||
'1_online_member': '1 人在线',
|
||||
'1_person_reacted': '1 人回复了',
|
||||
'1_user': '1 位用户',
|
||||
'error-action-not-allowed': '不允许 {{action}}',
|
||||
|
@ -199,7 +198,6 @@ export default {
|
|||
Mute: '静音',
|
||||
muted: '被静音',
|
||||
My_servers: '我的服务器',
|
||||
N_online_members: '{{n}} 位会员在线',
|
||||
N_people_reacted: '{{n}} 人回复',
|
||||
N_users: '{{n}} 位用户',
|
||||
name: '名字',
|
||||
|
|
|
@ -99,8 +99,6 @@ iconsLoaded();
|
|||
export default class App extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
store.dispatch(appInit());
|
||||
store.subscribe(this.onStoreUpdate.bind(this));
|
||||
initializePushNotifications();
|
||||
|
||||
Navigation.events().registerAppLaunchedListener(() => {
|
||||
|
|
|
@ -1,57 +1,37 @@
|
|||
import * as SDK from '@rocket.chat/sdk';
|
||||
|
||||
import database from '../realm';
|
||||
import log from '../../utils/log';
|
||||
|
||||
// TODO: api fix
|
||||
const ddpTypes = {
|
||||
channel: 'c', direct: 'd', group: 'p'
|
||||
};
|
||||
const restTypes = {
|
||||
channel: 'channels', direct: 'im', group: 'groups'
|
||||
};
|
||||
|
||||
async function canOpenRoomREST({ type, rid }) {
|
||||
async function open({ type, rid }) {
|
||||
try {
|
||||
await SDK.api.post(`${ restTypes[type] }.open`, { roomId: rid });
|
||||
return true;
|
||||
} catch (error) {
|
||||
// TODO: workround for 'already open for the sender' error
|
||||
if (!error.errorType) {
|
||||
} catch (e) {
|
||||
if (e.data && /is already open/.test(e.data.error)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function canOpenRoomDDP(...args) {
|
||||
try {
|
||||
const [{ type, name }] = args;
|
||||
await SDK.driver.asyncCall('getRoomByTypeAndName', ddpTypes[type], name);
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (error.isClientSafe) {
|
||||
return false;
|
||||
}
|
||||
return canOpenRoomREST.call(this, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
export default async function canOpenRoom({ rid, path }) {
|
||||
const { database: db } = database;
|
||||
const [type] = path.split('/');
|
||||
if (type === 'channel') {
|
||||
return true;
|
||||
}
|
||||
|
||||
const room = db.objects('subscriptions').filtered('rid == $0', rid);
|
||||
const room = database.objects('subscriptions').filtered('rid == $0', rid);
|
||||
if (room.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const [type, name] = path.split('/');
|
||||
|
||||
try {
|
||||
const data = await (this.connected() ? canOpenRoomDDP.call(this, { rid, type, name }) : canOpenRoomREST.call(this, { type, rid }));
|
||||
return data;
|
||||
return await open.call(this, { type, rid });
|
||||
} catch (e) {
|
||||
log('canOpenRoom', e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@ const getLastMessage = () => {
|
|||
export default async function() {
|
||||
try {
|
||||
const lastMessage = getLastMessage();
|
||||
let emojis = await SDK.driver.asyncCall('listEmojiCustom');
|
||||
const result = await SDK.api.get('emoji-custom');
|
||||
let { emojis } = result;
|
||||
emojis = emojis.filter(emoji => !lastMessage || emoji._updatedAt > lastMessage);
|
||||
emojis = this._prepareEmojis(emojis);
|
||||
InteractionManager.runAfterInteractions(() => database.write(() => {
|
||||
|
|
|
@ -5,18 +5,14 @@ import database from '../realm';
|
|||
import log from '../../utils/log';
|
||||
import defaultPermissions from '../../constants/permissions';
|
||||
|
||||
const getLastUpdate = () => {
|
||||
const setting = database.objects('permissions').sorted('_updatedAt', true)[0];
|
||||
return setting && setting._updatedAt;
|
||||
};
|
||||
|
||||
export default async function() {
|
||||
try {
|
||||
const lastUpdate = getLastUpdate();
|
||||
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));
|
||||
const result = await SDK.api.get('permissions.list');
|
||||
|
||||
if (!result.success) {
|
||||
return;
|
||||
}
|
||||
const permissions = result.permissions.filter(permission => defaultPermissions.includes(permission._id));
|
||||
permissions
|
||||
.map((permission) => {
|
||||
permission._updatedAt = new Date();
|
||||
|
|
|
@ -12,31 +12,17 @@ const lastMessage = () => {
|
|||
return message && new Date(message.roomUpdatedAt).toISOString();
|
||||
};
|
||||
|
||||
const getRoomRest = async function() {
|
||||
const updatedSince = lastMessage();
|
||||
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 updatedSince = lastMessage();
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
export default function() {
|
||||
const { database: db } = database;
|
||||
|
||||
return new Promise(async(resolve, reject) => {
|
||||
try {
|
||||
const { subscriptions, rooms } = await (this.connected() ? getRoomDpp.apply(this) : getRoomRest.apply(this));
|
||||
const updatedSince = lastMessage();
|
||||
const [subscriptionsResult, roomsResult] = 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')])
|
||||
);
|
||||
const { subscriptions, rooms } = mergeSubscriptionsRooms(subscriptionsResult, roomsResult);
|
||||
|
||||
const data = rooms.map(room => ({ room, sub: database.objects('subscriptions').filtered('rid == $0', room._id) }));
|
||||
|
||||
|
|
|
@ -5,12 +5,7 @@ import reduxStore from '../createStore';
|
|||
import database from '../realm';
|
||||
import * as actions from '../../actions';
|
||||
import log from '../../utils/log';
|
||||
import { settingsUpdatedAt } from '../../constants/settings';
|
||||
|
||||
const getLastUpdate = () => {
|
||||
const [setting] = database.objects('settings').sorted('_updatedAt', true);
|
||||
return setting && setting._updatedAt;
|
||||
};
|
||||
import settings from '../../constants/settings';
|
||||
|
||||
function updateServer(param) {
|
||||
database.databases.serversDB.write(() => {
|
||||
|
@ -20,19 +15,14 @@ function updateServer(param) {
|
|||
|
||||
export default async function() {
|
||||
try {
|
||||
// if (!SDK.driver.dd) {
|
||||
// // TODO: should implement loop or get from rest?
|
||||
// return;
|
||||
// }
|
||||
const settingsParams = JSON.stringify(Object.keys(settings));
|
||||
const result = await fetch(`${ SDK.api.url }settings.public?query={"_id":{"$in":${ settingsParams }}}`).then(response => response.json());
|
||||
|
||||
const lastUpdate = getLastUpdate();
|
||||
const fetchNewSettings = lastUpdate < settingsUpdatedAt;
|
||||
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));
|
||||
if (!result.success) {
|
||||
return;
|
||||
}
|
||||
const data = result.settings || [];
|
||||
const filteredSettings = this._prepareSettings(data.filter(item => item._id !== 'Assets_favicon_512'));
|
||||
|
||||
InteractionManager.runAfterInteractions(
|
||||
() => database.write(
|
||||
|
|
|
@ -5,47 +5,28 @@ import buildMessage from './helpers/buildMessage';
|
|||
import database from '../realm';
|
||||
import log from '../../utils/log';
|
||||
|
||||
// TODO: api fix
|
||||
const types = {
|
||||
c: 'channels', d: 'im', p: 'groups'
|
||||
};
|
||||
|
||||
async function loadMessagesForRoomRest({ rid: roomId, latest, t }) {
|
||||
async function load({ rid: roomId, latest, t }) {
|
||||
let params = { roomId, count: 50 };
|
||||
if (latest) {
|
||||
latest = new Date(latest).toISOString();
|
||||
params = { ...params, latest: new Date(latest).toISOString() };
|
||||
}
|
||||
const data = await SDK.api.get(`${ types[t] }.history`, { roomId, latest, count: 50 });
|
||||
const data = await SDK.api.get(`${ this.roomTypeToApiType(t) }.history`, params);
|
||||
if (!data || data.status === 'error') {
|
||||
return [];
|
||||
}
|
||||
return data.messages;
|
||||
}
|
||||
|
||||
async function loadMessagesForRoomDDP(...args) {
|
||||
const [{ rid: roomId, latest }] = args;
|
||||
try {
|
||||
const data = await SDK.driver.asyncCall('loadHistory', roomId, latest, 50);
|
||||
if (!data || !data.messages.length) {
|
||||
return [];
|
||||
}
|
||||
return data.messages;
|
||||
} catch (e) {
|
||||
return loadMessagesForRoomRest.call(this, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
export default function loadMessagesForRoom(...args) {
|
||||
const { database: db } = database;
|
||||
return new Promise(async(resolve, reject) => {
|
||||
try {
|
||||
const data = (await (this.connected()
|
||||
? loadMessagesForRoomDDP.call(this, ...args)
|
||||
: loadMessagesForRoomRest.call(this, ...args))).map(buildMessage);
|
||||
const data = await load.call(this, ...args);
|
||||
|
||||
if (data && data.length) {
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
db.write(() => data.forEach((message) => {
|
||||
db.create('messages', message, true);
|
||||
db.create('messages', buildMessage(message), true);
|
||||
}));
|
||||
return resolve(data);
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@ import buildMessage from './helpers/buildMessage';
|
|||
import database from '../realm';
|
||||
import log from '../../utils/log';
|
||||
|
||||
async function loadMissedMessagesRest({ rid: roomId, lastOpen }) {
|
||||
async function load({ rid: roomId, lastOpen }) {
|
||||
let lastUpdate;
|
||||
if (lastOpen) {
|
||||
lastUpdate = new Date(lastOpen).toISOString();
|
||||
|
@ -16,22 +16,11 @@ async function loadMissedMessagesRest({ rid: roomId, lastOpen }) {
|
|||
return result;
|
||||
}
|
||||
|
||||
async function loadMissedMessagesDDP(...args) {
|
||||
const [{ rid, lastOpen: lastUpdate }] = args;
|
||||
|
||||
try {
|
||||
const result = await SDK.driver.asyncCall('messages/get', rid, { lastUpdate: new Date(lastUpdate), count: 50 });
|
||||
return result;
|
||||
} catch (e) {
|
||||
return loadMissedMessagesRest.call(this, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
export default function loadMissedMessages(...args) {
|
||||
const { database: db } = database;
|
||||
return new Promise(async(resolve, reject) => {
|
||||
try {
|
||||
const data = (await (this.connected() ? loadMissedMessagesDDP.call(this, ...args) : loadMissedMessagesRest.call(this, ...args)));
|
||||
const data = (await load.call(this, ...args));
|
||||
|
||||
if (data) {
|
||||
if (data.updated && data.updated.length) {
|
||||
|
|
|
@ -3,25 +3,12 @@ import * as SDK from '@rocket.chat/sdk';
|
|||
import database from '../realm';
|
||||
import log from '../../utils/log';
|
||||
|
||||
const readMessagesREST = function readMessagesREST(rid) {
|
||||
return SDK.api.post('subscriptions.read', { rid });
|
||||
};
|
||||
|
||||
const readMessagesDDP = function readMessagesDDP(rid) {
|
||||
try {
|
||||
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 {
|
||||
const data = await (this.connected() ? readMessagesDDP.call(this, rid) : readMessagesREST.call(this, rid));
|
||||
const [subscription] = db.objects('subscriptions').filtered('rid = $0', rid);
|
||||
db.write(() => {
|
||||
const data = await SDK.api.post('subscriptions.read', { rid });
|
||||
const [subscription] = database.objects('subscriptions').filtered('rid = $0', rid);
|
||||
database.write(() => {
|
||||
subscription.open = true;
|
||||
subscription.alert = false;
|
||||
subscription.unread = 0;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import Random from 'react-native-meteor/lib/Random';
|
||||
import * as SDK from '@rocket.chat/sdk';
|
||||
|
||||
import messagesStatus from '../../constants/messagesStatus';
|
||||
|
@ -6,9 +5,10 @@ import buildMessage from './helpers/buildMessage';
|
|||
import database from '../realm';
|
||||
import reduxStore from '../createStore';
|
||||
import log from '../../utils/log';
|
||||
import random from '../../utils/random';
|
||||
|
||||
export const getMessage = (rid, msg = {}) => {
|
||||
const _id = Random.id();
|
||||
const _id = random(17);
|
||||
const message = {
|
||||
_id,
|
||||
rid,
|
||||
|
@ -31,21 +31,9 @@ export const getMessage = (rid, msg = {}) => {
|
|||
return message;
|
||||
};
|
||||
|
||||
function sendMessageByRest(args) {
|
||||
return SDK.api.post('chat.sendMessage', { message: args });
|
||||
}
|
||||
|
||||
function sendMessageByDDP(...args) {
|
||||
try {
|
||||
return SDK.driver.asyncCall('sendMessage', ...args);
|
||||
} catch (error) {
|
||||
return sendMessageByRest.call(this, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
export async function _sendMessageCall(message) {
|
||||
export async function sendMessageCall(message) {
|
||||
const { _id, rid, msg } = message;
|
||||
const data = await (this.connected() ? sendMessageByDDP.call(this, { _id, rid, msg }) : sendMessageByRest.call(this, { _id, rid, msg }));
|
||||
const data = await SDK.api.post('chat.sendMessage', { message: { _id, rid, msg } });
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -55,12 +43,13 @@ export default async function(rid, msg) {
|
|||
const message = getMessage(rid, msg);
|
||||
const room = db.objects('subscriptions').filtered('rid == $0', rid);
|
||||
|
||||
// TODO: do we need this?
|
||||
db.write(() => {
|
||||
room.lastMessage = message;
|
||||
});
|
||||
|
||||
try {
|
||||
const ret = await _sendMessageCall.call(this, message);
|
||||
const ret = await sendMessageCall.call(this, message);
|
||||
db.write(() => {
|
||||
db.create('messages', buildMessage({ ...message, ...ret }), true);
|
||||
});
|
||||
|
|
|
@ -7,9 +7,7 @@ const subscribe = rid => Promise.all([
|
|||
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);
|
||||
}));
|
||||
const unsubscribe = subscriptions => subscriptions.forEach(sub => sub.unsubscribe().catch(() => console.log('unsubscribeRoom')));
|
||||
|
||||
let timer = null;
|
||||
let promises;
|
||||
|
@ -43,26 +41,26 @@ export default function subscribeRoom({ rid, t }) {
|
|||
}, 5000);
|
||||
};
|
||||
|
||||
if (!this.connected()) {
|
||||
loop();
|
||||
} else {
|
||||
SDK.driver.on('logged', () => {
|
||||
clearTimeout(timer);
|
||||
timer = false;
|
||||
});
|
||||
// if (!this.connected()) {
|
||||
// loop();
|
||||
// } else {
|
||||
SDK.driver.on('logged', () => {
|
||||
clearTimeout(timer);
|
||||
timer = false;
|
||||
});
|
||||
|
||||
SDK.driver.on('disconnected', () => {
|
||||
if (SDK.driver.userId) {
|
||||
loop();
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
promises = subscribe(rid);
|
||||
} catch (e) {
|
||||
log('subscribeRoom', e);
|
||||
SDK.driver.on('disconnected', () => {
|
||||
if (SDK.driver.userId) {
|
||||
loop();
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
promises = subscribe(rid);
|
||||
} catch (e) {
|
||||
log('subscribeRoom', e);
|
||||
}
|
||||
// }
|
||||
|
||||
return {
|
||||
stop: () => stop()
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import Random from 'react-native-meteor/lib/Random';
|
||||
import * as SDK from '@rocket.chat/sdk';
|
||||
|
||||
import database from '../../realm';
|
||||
|
@ -6,6 +5,7 @@ import { merge } from '../helpers/mergeSubscriptionsRooms';
|
|||
import protectedFunction from '../helpers/protectedFunction';
|
||||
import messagesStatus from '../../../constants/messagesStatus';
|
||||
import log from '../../../utils/log';
|
||||
import random from '../../../utils/random';
|
||||
|
||||
export default async function subscribeRooms(id) {
|
||||
const promises = Promise.all([
|
||||
|
@ -30,85 +30,81 @@ export default async function subscribeRooms(id) {
|
|||
}, 5000);
|
||||
};
|
||||
|
||||
if (!this.connected()) {
|
||||
loop();
|
||||
} else {
|
||||
SDK.driver.on('logged', () => {
|
||||
clearTimeout(timer);
|
||||
timer = false;
|
||||
});
|
||||
SDK.driver.on('logged', () => {
|
||||
clearTimeout(timer);
|
||||
timer = false;
|
||||
});
|
||||
|
||||
SDK.driver.on('logout', () => {
|
||||
clearTimeout(timer);
|
||||
timer = true;
|
||||
});
|
||||
SDK.driver.on('logout', () => {
|
||||
clearTimeout(timer);
|
||||
timer = true;
|
||||
});
|
||||
|
||||
SDK.driver.on('disconnected', () => {
|
||||
if (SDK.driver.userId) {
|
||||
loop();
|
||||
}
|
||||
});
|
||||
SDK.driver.on('disconnected', () => {
|
||||
if (SDK.driver.userId) {
|
||||
loop();
|
||||
}
|
||||
});
|
||||
|
||||
SDK.driver.on('stream-notify-user', protectedFunction((e, ddpMessage) => {
|
||||
if (!this.ddp || ddpMessage.msg === 'added') {
|
||||
return;
|
||||
}
|
||||
const [type, data] = ddpMessage.fields.args;
|
||||
const [, ev] = ddpMessage.fields.eventName.split('/');
|
||||
if (/subscriptions/.test(ev)) {
|
||||
if (type === 'removed') {
|
||||
let messages = [];
|
||||
const [subscription] = database.objects('subscriptions').filtered('_id == $0', data._id);
|
||||
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)) {
|
||||
if (type === 'removed') {
|
||||
let messages = [];
|
||||
const [subscription] = database.objects('subscriptions').filtered('_id == $0', data._id);
|
||||
|
||||
if (subscription) {
|
||||
messages = database.objects('messages').filtered('rid == $0', subscription.rid);
|
||||
}
|
||||
database.write(() => {
|
||||
database.delete(messages);
|
||||
database.delete(subscription);
|
||||
});
|
||||
} else {
|
||||
const rooms = database.objects('rooms').filtered('_id == $0', data.rid);
|
||||
const tpm = merge(data, rooms[0]);
|
||||
database.write(() => {
|
||||
database.create('subscriptions', tpm, true);
|
||||
database.delete(rooms);
|
||||
});
|
||||
if (subscription) {
|
||||
messages = database.objects('messages').filtered('rid == $0', subscription.rid);
|
||||
}
|
||||
database.write(() => {
|
||||
database.delete(messages);
|
||||
database.delete(subscription);
|
||||
});
|
||||
} else {
|
||||
const rooms = database.objects('rooms').filtered('_id == $0', data.rid);
|
||||
const tpm = merge(data, rooms[0]);
|
||||
database.write(() => {
|
||||
database.create('subscriptions', tpm, true);
|
||||
database.delete(rooms);
|
||||
});
|
||||
}
|
||||
if (/rooms/.test(ev)) {
|
||||
if (type === 'updated') {
|
||||
const [sub] = database.objects('subscriptions').filtered('rid == $0', data._id);
|
||||
database.write(() => {
|
||||
merge(sub, data);
|
||||
});
|
||||
} else if (type === 'inserted') {
|
||||
database.write(() => {
|
||||
database.create('rooms', data, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (/rooms/.test(ev)) {
|
||||
if (type === 'updated') {
|
||||
const [sub] = database.objects('subscriptions').filtered('rid == $0', data._id);
|
||||
database.write(() => {
|
||||
merge(sub, data);
|
||||
});
|
||||
} else if (type === 'inserted') {
|
||||
database.write(() => {
|
||||
database.create('rooms', data, true);
|
||||
});
|
||||
}
|
||||
if (/message/.test(ev)) {
|
||||
const [args] = ddpMessage.fields.args;
|
||||
const _id = Random.id();
|
||||
const message = {
|
||||
}
|
||||
if (/message/.test(ev)) {
|
||||
const [args] = ddpMessage.fields.args;
|
||||
const _id = random(17);
|
||||
const message = {
|
||||
_id,
|
||||
rid: args.rid,
|
||||
msg: args.msg,
|
||||
ts: new Date(),
|
||||
_updatedAt: new Date(),
|
||||
status: messagesStatus.SENT,
|
||||
u: {
|
||||
_id,
|
||||
rid: args.rid,
|
||||
msg: args.msg,
|
||||
ts: new Date(),
|
||||
_updatedAt: new Date(),
|
||||
status: messagesStatus.SENT,
|
||||
u: {
|
||||
_id,
|
||||
username: 'rocket.cat'
|
||||
}
|
||||
};
|
||||
requestAnimationFrame(() => database.write(() => {
|
||||
database.create('messages', message, true);
|
||||
}));
|
||||
}
|
||||
}));
|
||||
}
|
||||
username: 'rocket.cat'
|
||||
}
|
||||
};
|
||||
requestAnimationFrame(() => database.write(() => {
|
||||
database.create('messages', message, true);
|
||||
}));
|
||||
}
|
||||
}));
|
||||
|
||||
try {
|
||||
await promises;
|
||||
|
|
|
@ -8,12 +8,11 @@ import defaultSettings from '../constants/settings';
|
|||
import messagesStatus from '../constants/messagesStatus';
|
||||
import database from './realm';
|
||||
import log from '../utils/log';
|
||||
// import * as actions from '../actions';
|
||||
|
||||
import {
|
||||
setUser, setLoginServices, loginRequest, loginSuccess, loginFailure, logout
|
||||
setUser, setLoginServices, loginRequest, loginFailure, logout
|
||||
} from '../actions/login';
|
||||
import { disconnect, connectSuccess } from '../actions/connect';
|
||||
import { disconnect, connectSuccess, connectRequest } from '../actions/connect';
|
||||
import { setActiveUser } from '../actions/activeUsers';
|
||||
import { starredMessagesReceived, starredMessageUnstarred } from '../actions/starredMessages';
|
||||
import { pinnedMessagesReceived, pinnedMessageUnpinned } from '../actions/pinnedMessages';
|
||||
|
@ -39,7 +38,7 @@ import _buildMessage from './methods/helpers/buildMessage';
|
|||
import loadMessagesForRoom from './methods/loadMessagesForRoom';
|
||||
import loadMissedMessages from './methods/loadMissedMessages';
|
||||
|
||||
import sendMessage, { getMessage, _sendMessageCall } from './methods/sendMessage';
|
||||
import sendMessage, { getMessage, sendMessageCall } from './methods/sendMessage';
|
||||
import { sendFileMessage, cancelUpload, isUploadActive } from './methods/sendFileMessage';
|
||||
|
||||
import { getDeviceToken } from '../push';
|
||||
|
@ -124,320 +123,257 @@ const RocketChat = {
|
|||
this.activeUsers[ddpMessage.id] = { ...this.activeUsers[ddpMessage.id], ...activeUser, ...ddpMessage.fields };
|
||||
}
|
||||
},
|
||||
async loginSuccess(user) {
|
||||
if (!user) {
|
||||
const { user: u } = reduxStore.getState().login;
|
||||
user = Object.assign({}, u);
|
||||
}
|
||||
|
||||
// TODO: one api call
|
||||
// call /me only one time
|
||||
try {
|
||||
if (!user.username) {
|
||||
// get me from api
|
||||
let me = await SDK.api.get('me');
|
||||
// if server didn't found username
|
||||
if (!me.username) {
|
||||
// search username from credentials (sent during registerSubmit)
|
||||
const { username } = reduxStore.getState().login.credentials;
|
||||
if (username) {
|
||||
// set username
|
||||
await RocketChat.setUsername({ username });
|
||||
me = { ...me, username };
|
||||
}
|
||||
}
|
||||
user = { ...user, ...me };
|
||||
}
|
||||
} catch (e) {
|
||||
log('SDK.loginSuccess set username', e);
|
||||
}
|
||||
|
||||
try {
|
||||
if (user.username) {
|
||||
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('SDK.loginSuccess', e);
|
||||
}
|
||||
loginSuccess({ user }) {
|
||||
SDK.driver.login({ resume: user.token });
|
||||
reduxStore.dispatch(setUser(user));
|
||||
this.getRooms().catch(e => console.log(e));
|
||||
this.getPermissions();
|
||||
this.getCustomEmoji();
|
||||
this.registerPushToken().then(result => console.log(result)).catch(e => alert(e));
|
||||
},
|
||||
connect(url, login) {
|
||||
return new Promise(() => {
|
||||
if (this.ddp) {
|
||||
RocketChat.disconnect();
|
||||
this.ddp = null;
|
||||
connect({ server, user }) {
|
||||
database.setActiveDB(server);
|
||||
|
||||
if (this.ddp) {
|
||||
RocketChat.disconnect();
|
||||
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://
|
||||
const useSsl = !/http:\/\//.test(server);
|
||||
|
||||
reduxStore.dispatch(connectRequest());
|
||||
SDK.driver.connect({ host: server, useSsl }, (err, ddp) => {
|
||||
if (err) {
|
||||
return console.warn(err);
|
||||
}
|
||||
|
||||
SDK.api.setBaseUrl(url);
|
||||
|
||||
if (login) {
|
||||
SDK.api.setAuth({ authToken: login.token, userId: login.id });
|
||||
RocketChat.setApiUser({ userId: login.id, authToken: login.token });
|
||||
this.ddp = ddp;
|
||||
if (user && user.token) {
|
||||
SDK.driver.login({ resume: user.token });
|
||||
}
|
||||
|
||||
SDK.driver.connect({ host: url, useSsl: true }, (err, ddp) => {
|
||||
if (err) {
|
||||
return console.warn(err);
|
||||
}
|
||||
this.ddp = ddp;
|
||||
if (login) {
|
||||
SDK.driver.login({ resume: login.resume });
|
||||
}
|
||||
});
|
||||
|
||||
SDK.driver.on('connected', () => {
|
||||
reduxStore.dispatch(connectSuccess());
|
||||
SDK.driver.subscribe('activeUsers');
|
||||
SDK.driver.subscribe('roles');
|
||||
RocketChat.getSettings();
|
||||
RocketChat.getPermissions();
|
||||
RocketChat.getCustomEmoji();
|
||||
});
|
||||
|
||||
SDK.driver.on('login', protectedFunction(() => reduxStore.dispatch(loginRequest())));
|
||||
|
||||
SDK.driver.on('forbidden', protectedFunction(() => reduxStore.dispatch(logout())));
|
||||
|
||||
SDK.driver.on('users', protectedFunction((error, ddpMessage) => RocketChat._setUser(ddpMessage)));
|
||||
|
||||
// SDK.driver.on('background', () => this.getRooms().catch(e => log('background getRooms', e)));
|
||||
|
||||
SDK.driver.on('logged', protectedFunction((error, user) => {
|
||||
RocketChat.setApiUser({ userId: user.id, authToken: user.token });
|
||||
this.loginSuccess(user);
|
||||
this.getRooms().catch(e => log('logged getRooms', e));
|
||||
this.subscribeRooms(user.id);
|
||||
}));
|
||||
|
||||
SDK.driver.on('disconnected', protectedFunction(() => {
|
||||
reduxStore.dispatch(disconnect());
|
||||
}));
|
||||
|
||||
SDK.driver.on('stream-room-messages', (error, ddpMessage) => {
|
||||
// TODO: debounce
|
||||
const message = _buildMessage(ddpMessage.fields.args[0]);
|
||||
requestAnimationFrame(() => reduxStore.dispatch(roomMessageReceived(message)));
|
||||
});
|
||||
|
||||
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] }));
|
||||
} else if (ev === 'deleteMessage') {
|
||||
database.write(() => {
|
||||
if (ddpMessage && ddpMessage.fields && ddpMessage.fields.args.length > 0) {
|
||||
const { _id } = ddpMessage.fields.args[0];
|
||||
const message = database.objects('messages').filtered('_id = $0', _id);
|
||||
database.delete(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
SDK.driver.on('rocketchat_starred_message', protectedFunction((error, ddpMessage) => {
|
||||
if (ddpMessage.msg === 'added') {
|
||||
this.starredMessages = this.starredMessages || [];
|
||||
|
||||
if (this.starredMessagesTimer) {
|
||||
clearTimeout(this.starredMessagesTimer);
|
||||
this.starredMessagesTimer = null;
|
||||
}
|
||||
|
||||
this.starredMessagesTimer = setTimeout(protectedFunction(() => {
|
||||
reduxStore.dispatch(starredMessagesReceived(this.starredMessages));
|
||||
this.starredMessagesTimer = null;
|
||||
return this.starredMessages = [];
|
||||
}), 1000);
|
||||
const message = ddpMessage.fields;
|
||||
message._id = ddpMessage.id;
|
||||
const starredMessage = _buildMessage(message);
|
||||
this.starredMessages = [...this.starredMessages, starredMessage];
|
||||
}
|
||||
if (ddpMessage.msg === 'removed') {
|
||||
if (reduxStore.getState().starredMessages.isOpen) {
|
||||
return reduxStore.dispatch(starredMessageUnstarred(ddpMessage.id));
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
SDK.driver.on('rocketchat_pinned_message', protectedFunction((error, ddpMessage) => {
|
||||
if (ddpMessage.msg === 'added') {
|
||||
this.pinnedMessages = this.pinnedMessages || [];
|
||||
|
||||
if (this.pinnedMessagesTimer) {
|
||||
clearTimeout(this.pinnedMessagesTimer);
|
||||
this.pinnedMessagesTimer = null;
|
||||
}
|
||||
|
||||
this.pinnedMessagesTimer = setTimeout(() => {
|
||||
reduxStore.dispatch(pinnedMessagesReceived(this.pinnedMessages));
|
||||
this.pinnedMessagesTimer = null;
|
||||
return this.pinnedMessages = [];
|
||||
}, 1000);
|
||||
const message = ddpMessage.fields;
|
||||
message._id = ddpMessage.id;
|
||||
const pinnedMessage = _buildMessage(message);
|
||||
this.pinnedMessages = [...this.pinnedMessages, pinnedMessage];
|
||||
}
|
||||
if (ddpMessage.msg === 'removed') {
|
||||
if (reduxStore.getState().pinnedMessages.isOpen) {
|
||||
return reduxStore.dispatch(pinnedMessageUnpinned(ddpMessage.id));
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
SDK.driver.on('rocketchat_mentioned_message', protectedFunction((error, ddpMessage) => {
|
||||
if (ddpMessage.msg === 'added') {
|
||||
this.mentionedMessages = this.mentionedMessages || [];
|
||||
|
||||
if (this.mentionedMessagesTimer) {
|
||||
clearTimeout(this.mentionedMessagesTimer);
|
||||
this.mentionedMessagesTimer = null;
|
||||
}
|
||||
|
||||
this.mentionedMessagesTimer = setTimeout(() => {
|
||||
reduxStore.dispatch(mentionedMessagesReceived(this.mentionedMessages));
|
||||
this.mentionedMessagesTimer = null;
|
||||
return this.mentionedMessages = [];
|
||||
}, 1000);
|
||||
const message = ddpMessage.fields;
|
||||
message._id = ddpMessage.id;
|
||||
const mentionedMessage = _buildMessage(message);
|
||||
this.mentionedMessages = [...this.mentionedMessages, mentionedMessage];
|
||||
}
|
||||
}));
|
||||
|
||||
SDK.driver.on('rocketchat_snippeted_message', protectedFunction((error, ddpMessage) => {
|
||||
if (ddpMessage.msg === 'added') {
|
||||
this.snippetedMessages = this.snippetedMessages || [];
|
||||
|
||||
if (this.snippetedMessagesTimer) {
|
||||
clearTimeout(this.snippetedMessagesTimer);
|
||||
this.snippetedMessagesTimer = null;
|
||||
}
|
||||
|
||||
this.snippetedMessagesTimer = setTimeout(() => {
|
||||
reduxStore.dispatch(snippetedMessagesReceived(this.snippetedMessages));
|
||||
this.snippetedMessagesTimer = null;
|
||||
return this.snippetedMessages = [];
|
||||
}, 1000);
|
||||
const message = ddpMessage.fields;
|
||||
message._id = ddpMessage.id;
|
||||
const snippetedMessage = _buildMessage(message);
|
||||
this.snippetedMessages = [...this.snippetedMessages, snippetedMessage];
|
||||
}
|
||||
}));
|
||||
|
||||
SDK.driver.on('room_files', protectedFunction((error, ddpMessage) => {
|
||||
if (ddpMessage.msg === 'added') {
|
||||
this.roomFiles = this.roomFiles || [];
|
||||
|
||||
if (this.roomFilesTimer) {
|
||||
clearTimeout(this.roomFilesTimer);
|
||||
this.roomFilesTimer = null;
|
||||
}
|
||||
|
||||
this.roomFilesTimer = setTimeout(() => {
|
||||
reduxStore.dispatch(roomFilesReceived(this.roomFiles));
|
||||
this.roomFilesTimer = null;
|
||||
return this.roomFiles = [];
|
||||
}, 1000);
|
||||
const { fields } = ddpMessage;
|
||||
const message = {
|
||||
_id: ddpMessage.id,
|
||||
ts: fields.uploadedAt,
|
||||
msg: fields.description,
|
||||
status: 0,
|
||||
attachments: [{
|
||||
title: fields.name
|
||||
}],
|
||||
urls: [],
|
||||
reactions: [],
|
||||
u: {
|
||||
username: fields.user.username
|
||||
}
|
||||
};
|
||||
const fileUrl = `/file-upload/${ ddpMessage.id }/${ fields.name }`;
|
||||
if (/image/.test(fields.type)) {
|
||||
message.attachments[0].image_type = fields.type;
|
||||
message.attachments[0].image_url = fileUrl;
|
||||
} else if (/audio/.test(fields.type)) {
|
||||
message.attachments[0].audio_type = fields.type;
|
||||
message.attachments[0].audio_url = fileUrl;
|
||||
} else if (/video/.test(fields.type)) {
|
||||
message.attachments[0].video_type = fields.type;
|
||||
message.attachments[0].video_url = fileUrl;
|
||||
}
|
||||
this.roomFiles = [...this.roomFiles, message];
|
||||
}
|
||||
}));
|
||||
|
||||
SDK.driver.on('rocketchat_roles', protectedFunction((error, ddpMessage) => {
|
||||
this.roles = this.roles || {};
|
||||
|
||||
if (this.roleTimer) {
|
||||
clearTimeout(this.roleTimer);
|
||||
this.roleTimer = null;
|
||||
}
|
||||
this.roleTimer = setTimeout(() => {
|
||||
reduxStore.dispatch(setRoles(this.roles));
|
||||
|
||||
database.write(() => {
|
||||
foreach(this.roles, (description, _id) => {
|
||||
database.create('roles', { _id, description }, true);
|
||||
});
|
||||
});
|
||||
|
||||
this.roleTimer = null;
|
||||
return this.roles = {};
|
||||
}, 1000);
|
||||
this.roles[ddpMessage.id] = (ddpMessage.fields && ddpMessage.fields.description) || undefined;
|
||||
}));
|
||||
|
||||
// SDK.driver.on('error', (err) => {
|
||||
// log('SDK.onerror', err);
|
||||
// reduxStore.dispatch(connectFailure());
|
||||
// });
|
||||
|
||||
// SDK.driver.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();
|
||||
// }));
|
||||
}).catch((e) => {
|
||||
log('SDK.connect catch', e);
|
||||
});
|
||||
},
|
||||
connected() {
|
||||
return SDK.driver.ddp && SDK.driver.ddp._logged;
|
||||
|
||||
SDK.driver.on('connected', () => {
|
||||
reduxStore.dispatch(connectSuccess());
|
||||
});
|
||||
|
||||
SDK.driver.on('disconnected', protectedFunction(() => {
|
||||
reduxStore.dispatch(disconnect());
|
||||
}));
|
||||
|
||||
SDK.driver.on('logged', protectedFunction((error, u) => {
|
||||
this.subscribeRooms(u.id);
|
||||
SDK.driver.subscribe('activeUsers');
|
||||
SDK.driver.subscribe('roles');
|
||||
}));
|
||||
|
||||
SDK.driver.on('forbidden', protectedFunction(() => reduxStore.dispatch(logout())));
|
||||
|
||||
SDK.driver.on('users', protectedFunction((error, ddpMessage) => RocketChat._setUser(ddpMessage)));
|
||||
|
||||
SDK.driver.on('stream-room-messages', (error, ddpMessage) => {
|
||||
// TODO: debounce
|
||||
const message = _buildMessage(ddpMessage.fields.args[0]);
|
||||
requestAnimationFrame(() => reduxStore.dispatch(roomMessageReceived(message)));
|
||||
});
|
||||
|
||||
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] }));
|
||||
} else if (ev === 'deleteMessage') {
|
||||
database.write(() => {
|
||||
if (ddpMessage && ddpMessage.fields && ddpMessage.fields.args.length > 0) {
|
||||
const { _id } = ddpMessage.fields.args[0];
|
||||
const message = database.objects('messages').filtered('_id = $0', _id);
|
||||
database.delete(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
SDK.driver.on('rocketchat_starred_message', protectedFunction((error, ddpMessage) => {
|
||||
if (ddpMessage.msg === 'added') {
|
||||
this.starredMessages = this.starredMessages || [];
|
||||
|
||||
if (this.starredMessagesTimer) {
|
||||
clearTimeout(this.starredMessagesTimer);
|
||||
this.starredMessagesTimer = null;
|
||||
}
|
||||
|
||||
this.starredMessagesTimer = setTimeout(protectedFunction(() => {
|
||||
reduxStore.dispatch(starredMessagesReceived(this.starredMessages));
|
||||
this.starredMessagesTimer = null;
|
||||
return this.starredMessages = [];
|
||||
}), 1000);
|
||||
const message = ddpMessage.fields;
|
||||
message._id = ddpMessage.id;
|
||||
const starredMessage = _buildMessage(message);
|
||||
this.starredMessages = [...this.starredMessages, starredMessage];
|
||||
}
|
||||
if (ddpMessage.msg === 'removed') {
|
||||
if (reduxStore.getState().starredMessages.isOpen) {
|
||||
return reduxStore.dispatch(starredMessageUnstarred(ddpMessage.id));
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
SDK.driver.on('rocketchat_pinned_message', protectedFunction((error, ddpMessage) => {
|
||||
if (ddpMessage.msg === 'added') {
|
||||
this.pinnedMessages = this.pinnedMessages || [];
|
||||
|
||||
if (this.pinnedMessagesTimer) {
|
||||
clearTimeout(this.pinnedMessagesTimer);
|
||||
this.pinnedMessagesTimer = null;
|
||||
}
|
||||
|
||||
this.pinnedMessagesTimer = setTimeout(() => {
|
||||
reduxStore.dispatch(pinnedMessagesReceived(this.pinnedMessages));
|
||||
this.pinnedMessagesTimer = null;
|
||||
return this.pinnedMessages = [];
|
||||
}, 1000);
|
||||
const message = ddpMessage.fields;
|
||||
message._id = ddpMessage.id;
|
||||
const pinnedMessage = _buildMessage(message);
|
||||
this.pinnedMessages = [...this.pinnedMessages, pinnedMessage];
|
||||
}
|
||||
if (ddpMessage.msg === 'removed') {
|
||||
if (reduxStore.getState().pinnedMessages.isOpen) {
|
||||
return reduxStore.dispatch(pinnedMessageUnpinned(ddpMessage.id));
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
SDK.driver.on('rocketchat_mentioned_message', protectedFunction((error, ddpMessage) => {
|
||||
if (ddpMessage.msg === 'added') {
|
||||
this.mentionedMessages = this.mentionedMessages || [];
|
||||
|
||||
if (this.mentionedMessagesTimer) {
|
||||
clearTimeout(this.mentionedMessagesTimer);
|
||||
this.mentionedMessagesTimer = null;
|
||||
}
|
||||
|
||||
this.mentionedMessagesTimer = setTimeout(() => {
|
||||
reduxStore.dispatch(mentionedMessagesReceived(this.mentionedMessages));
|
||||
this.mentionedMessagesTimer = null;
|
||||
return this.mentionedMessages = [];
|
||||
}, 1000);
|
||||
const message = ddpMessage.fields;
|
||||
message._id = ddpMessage.id;
|
||||
const mentionedMessage = _buildMessage(message);
|
||||
this.mentionedMessages = [...this.mentionedMessages, mentionedMessage];
|
||||
}
|
||||
}));
|
||||
|
||||
SDK.driver.on('rocketchat_snippeted_message', protectedFunction((error, ddpMessage) => {
|
||||
if (ddpMessage.msg === 'added') {
|
||||
this.snippetedMessages = this.snippetedMessages || [];
|
||||
|
||||
if (this.snippetedMessagesTimer) {
|
||||
clearTimeout(this.snippetedMessagesTimer);
|
||||
this.snippetedMessagesTimer = null;
|
||||
}
|
||||
|
||||
this.snippetedMessagesTimer = setTimeout(() => {
|
||||
reduxStore.dispatch(snippetedMessagesReceived(this.snippetedMessages));
|
||||
this.snippetedMessagesTimer = null;
|
||||
return this.snippetedMessages = [];
|
||||
}, 1000);
|
||||
const message = ddpMessage.fields;
|
||||
message._id = ddpMessage.id;
|
||||
const snippetedMessage = _buildMessage(message);
|
||||
this.snippetedMessages = [...this.snippetedMessages, snippetedMessage];
|
||||
}
|
||||
}));
|
||||
|
||||
SDK.driver.on('room_files', protectedFunction((error, ddpMessage) => {
|
||||
if (ddpMessage.msg === 'added') {
|
||||
this.roomFiles = this.roomFiles || [];
|
||||
|
||||
if (this.roomFilesTimer) {
|
||||
clearTimeout(this.roomFilesTimer);
|
||||
this.roomFilesTimer = null;
|
||||
}
|
||||
|
||||
this.roomFilesTimer = setTimeout(() => {
|
||||
reduxStore.dispatch(roomFilesReceived(this.roomFiles));
|
||||
this.roomFilesTimer = null;
|
||||
return this.roomFiles = [];
|
||||
}, 1000);
|
||||
const { fields } = ddpMessage;
|
||||
const message = {
|
||||
_id: ddpMessage.id,
|
||||
ts: fields.uploadedAt,
|
||||
msg: fields.description,
|
||||
status: 0,
|
||||
attachments: [{
|
||||
title: fields.name
|
||||
}],
|
||||
urls: [],
|
||||
reactions: [],
|
||||
u: {
|
||||
username: fields.user.username
|
||||
}
|
||||
};
|
||||
const fileUrl = `/file-upload/${ ddpMessage.id }/${ fields.name }`;
|
||||
if (/image/.test(fields.type)) {
|
||||
message.attachments[0].image_type = fields.type;
|
||||
message.attachments[0].image_url = fileUrl;
|
||||
} else if (/audio/.test(fields.type)) {
|
||||
message.attachments[0].audio_type = fields.type;
|
||||
message.attachments[0].audio_url = fileUrl;
|
||||
} else if (/video/.test(fields.type)) {
|
||||
message.attachments[0].video_type = fields.type;
|
||||
message.attachments[0].video_url = fileUrl;
|
||||
}
|
||||
this.roomFiles = [...this.roomFiles, message];
|
||||
}
|
||||
}));
|
||||
|
||||
SDK.driver.on('rocketchat_roles', protectedFunction((error, ddpMessage) => {
|
||||
this.roles = this.roles || {};
|
||||
|
||||
if (this.roleTimer) {
|
||||
clearTimeout(this.roleTimer);
|
||||
this.roleTimer = null;
|
||||
}
|
||||
this.roleTimer = setTimeout(() => {
|
||||
reduxStore.dispatch(setRoles(this.roles));
|
||||
|
||||
database.write(() => {
|
||||
foreach(this.roles, (description, _id) => {
|
||||
database.create('roles', { _id, description }, true);
|
||||
});
|
||||
});
|
||||
|
||||
this.roleTimer = null;
|
||||
return this.roles = {};
|
||||
}, 1000);
|
||||
this.roles[ddpMessage.id] = (ddpMessage.fields && ddpMessage.fields.description) || undefined;
|
||||
}));
|
||||
},
|
||||
|
||||
register({ credentials }) {
|
||||
return call('registerUser', credentials);
|
||||
register(credentials) {
|
||||
return SDK.api.post('users.register', credentials, false);
|
||||
},
|
||||
|
||||
setUsername({ username }) {
|
||||
setUsername(username) {
|
||||
return call('setUsername', username);
|
||||
},
|
||||
|
||||
forgotPassword(email) {
|
||||
return call('sendForgotPasswordEmail', email);
|
||||
return SDK.api.post('users.forgotPassword', { email }, false);
|
||||
},
|
||||
|
||||
async loginWithPassword({ username, password, code }) {
|
||||
let params = { username, password };
|
||||
async loginWithPassword({ user, password, code }) {
|
||||
let params = { user, password };
|
||||
const state = reduxStore.getState();
|
||||
|
||||
if (state.settings.LDAP_Enable) {
|
||||
|
@ -451,16 +387,12 @@ const RocketChat = {
|
|||
...params,
|
||||
crowd: true
|
||||
};
|
||||
} else if (typeof username === 'string' && username.indexOf('@') !== -1) {
|
||||
params.email = username;
|
||||
delete params.username;
|
||||
}
|
||||
|
||||
if (code) {
|
||||
params = {
|
||||
...params,
|
||||
code,
|
||||
totp: true
|
||||
code
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -471,59 +403,84 @@ const RocketChat = {
|
|||
}
|
||||
},
|
||||
|
||||
async loginOAuth(params) {
|
||||
try {
|
||||
const result = await SDK.driver.login(params);
|
||||
reduxStore.dispatch(loginRequest({ resume: result.token }));
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
async login(params) {
|
||||
try {
|
||||
await SDK.driver.login(params);
|
||||
return await SDK.api.login(params);
|
||||
} catch (e) {
|
||||
reduxStore.dispatch(loginFailure(e));
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
logout({ server }) {
|
||||
async logout({ server }) {
|
||||
// this.removePushToken().catch(error => console.log(error));
|
||||
try {
|
||||
RocketChat.disconnect();
|
||||
SDK.driver.logout();
|
||||
await this.removePushToken();
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
console.log('logout -> removePushToken -> catch -> error', error);
|
||||
}
|
||||
AsyncStorage.removeItem(TOKEN_KEY);
|
||||
AsyncStorage.removeItem(`${ TOKEN_KEY }-${ server }`);
|
||||
try {
|
||||
await SDK.api.logout();
|
||||
} catch (error) {
|
||||
console.log('logout -> api logout -> catch -> error', error);
|
||||
}
|
||||
SDK.driver.ddp.disconnect();
|
||||
this.ddp = null;
|
||||
|
||||
Promise.all([
|
||||
AsyncStorage.removeItem('currentServer'),
|
||||
AsyncStorage.removeItem(TOKEN_KEY),
|
||||
AsyncStorage.removeItem(`${ TOKEN_KEY }-${ server }`)
|
||||
]).catch(error => console.log(error));
|
||||
|
||||
try {
|
||||
database.deleteAll();
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
disconnect() {
|
||||
try {
|
||||
SDK.driver.unsubscribeAll();
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
console.log(error);
|
||||
}
|
||||
RocketChat.setApiUser({ userId: null, authToken: null });
|
||||
},
|
||||
setApiUser({ userId, authToken }) {
|
||||
SDK.api.setAuth({ userId, authToken });
|
||||
SDK.api.currentLogin = { userId, authToken };
|
||||
SDK.api.currentLogin = null;
|
||||
},
|
||||
registerPushToken(userId) {
|
||||
const deviceToken = getDeviceToken();
|
||||
if (deviceToken) {
|
||||
const key = Platform.OS === 'ios' ? 'apn' : 'gcm';
|
||||
const data = {
|
||||
id: `RocketChatRN${ userId }`,
|
||||
token: { [key]: deviceToken },
|
||||
appName: 'chat.rocket.reactnative', // TODO: try to get from config file
|
||||
userId,
|
||||
metadata: {}
|
||||
};
|
||||
return call('raix:push-update', data);
|
||||
registerPushToken() {
|
||||
return new Promise((resolve) => {
|
||||
const token = getDeviceToken();
|
||||
if (token) {
|
||||
const type = Platform.OS === 'ios' ? 'apn' : 'gcm';
|
||||
const data = {
|
||||
value: token,
|
||||
type,
|
||||
appName: 'chat.rocket.reactnative' // TODO: try to get from config file
|
||||
};
|
||||
return SDK.api.post('push.token', data);
|
||||
}
|
||||
return resolve();
|
||||
});
|
||||
},
|
||||
removePushToken() {
|
||||
const token = getDeviceToken();
|
||||
if (token) {
|
||||
return SDK.api.del('push.token', { token });
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
// updatePushToken(pushId) {
|
||||
// return call('raix:push-setuser', pushId);
|
||||
// },
|
||||
loadMissedMessages,
|
||||
loadMessagesForRoom,
|
||||
getMessage,
|
||||
|
@ -532,11 +489,18 @@ const RocketChat = {
|
|||
readMessages,
|
||||
async resendMessage(messageId) {
|
||||
const message = await database.objects('messages').filtered('_id = $0', messageId)[0];
|
||||
database.write(() => {
|
||||
message.status = messagesStatus.TEMP;
|
||||
database.create('messages', message, true);
|
||||
});
|
||||
return _sendMessageCall.call(this, JSON.parse(JSON.stringify(message)));
|
||||
try {
|
||||
database.write(() => {
|
||||
message.status = messagesStatus.TEMP;
|
||||
database.create('messages', message, true);
|
||||
});
|
||||
await sendMessageCall.call(this, JSON.parse(JSON.stringify(message)));
|
||||
} catch (error) {
|
||||
database.write(() => {
|
||||
message.status = messagesStatus.ERROR;
|
||||
database.create('messages', message, true);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
async search({ text, filterUsers = true, filterRooms = true }) {
|
||||
|
@ -596,10 +560,11 @@ const RocketChat = {
|
|||
},
|
||||
|
||||
createDirectMessage(username) {
|
||||
return call('createDirectMessage', username);
|
||||
return SDK.api.post('im.create', { username });
|
||||
},
|
||||
joinRoom(rid) {
|
||||
return call('joinRoom', rid);
|
||||
joinRoom(roomId) {
|
||||
// TODO: join code
|
||||
return SDK.api.post('channels.join', { roomId });
|
||||
},
|
||||
sendFileMessage,
|
||||
cancelUpload,
|
||||
|
@ -608,8 +573,7 @@ const RocketChat = {
|
|||
getPermissions,
|
||||
getCustomEmoji,
|
||||
parseSettings: settings => settings.reduce((ret, item) => {
|
||||
ret[item._id] = item[defaultSettings[item._id].type] || item.valueAsString || item.valueAsNumber
|
||||
|| item.valueAsBoolean || item.value;
|
||||
ret[item._id] = item[defaultSettings[item._id].type];
|
||||
return ret;
|
||||
}, {}),
|
||||
_prepareSettings(settings) {
|
||||
|
@ -618,7 +582,6 @@ const RocketChat = {
|
|||
return setting;
|
||||
});
|
||||
},
|
||||
_filterSettings: settings => settings.filter(setting => defaultSettings[setting._id] && (setting.value || setting.valueAsString || setting.valueAsNumber || setting.valueAsBoolean)),
|
||||
parseEmojis: emojis => emojis.reduce((ret, item) => {
|
||||
ret[item.name] = item.extension;
|
||||
item.aliases.forEach((alias) => {
|
||||
|
@ -633,20 +596,24 @@ const RocketChat = {
|
|||
return emojis;
|
||||
},
|
||||
deleteMessage(message) {
|
||||
return call('deleteMessage', { _id: message._id });
|
||||
const { _id, rid } = message;
|
||||
return SDK.api.post('chat.delete', { roomId: rid, msgId: _id });
|
||||
},
|
||||
editMessage(message) {
|
||||
const { _id, msg, rid } = message;
|
||||
return call('updateMessage', { _id, msg, rid });
|
||||
return SDK.api.post('chat.update', { roomId: rid, msgId: _id, text: msg });
|
||||
},
|
||||
toggleStarMessage(message) {
|
||||
return call('starMessage', { _id: message._id, rid: message.rid, starred: !message.starred });
|
||||
if (message.starred) {
|
||||
return SDK.api.post('chat.unStarMessage', { messageId: message._id });
|
||||
}
|
||||
return SDK.api.post('chat.starMessage', { messageId: message._id });
|
||||
},
|
||||
togglePinMessage(message) {
|
||||
if (message.pinned) {
|
||||
return call('unpinMessage', message);
|
||||
return SDK.api.post('chat.unPinMessage', { messageId: message._id });
|
||||
}
|
||||
return call('pinMessage', message);
|
||||
return SDK.api.post('chat.pinMessage', { messageId: message._id });
|
||||
},
|
||||
getRoom(rid) {
|
||||
const [result] = database.objects('subscriptions').filtered('rid = $0', rid);
|
||||
|
@ -655,6 +622,9 @@ const RocketChat = {
|
|||
}
|
||||
return Promise.resolve(result);
|
||||
},
|
||||
getRoomInfo(roomId) {
|
||||
return SDK.api.get('rooms.info', { roomId });
|
||||
},
|
||||
async getPermalink(message) {
|
||||
let room;
|
||||
try {
|
||||
|
@ -691,10 +661,10 @@ const RocketChat = {
|
|||
return call('UserPresence:setDefaultStatus', status);
|
||||
},
|
||||
setReaction(emoji, messageId) {
|
||||
return call('setReaction', emoji, messageId);
|
||||
return SDK.api.post('chat.react', { emoji, messageId });
|
||||
},
|
||||
toggleFavorite(rid, f) {
|
||||
return call('toggleFavorite', rid, !f);
|
||||
toggleFavorite(roomId, favorite) {
|
||||
return SDK.api.post('rooms.favorite', { roomId, favorite });
|
||||
},
|
||||
getRoomMembers(rid, allUsers) {
|
||||
return call('getUsersOfRoom', rid, allUsers);
|
||||
|
@ -702,6 +672,9 @@ const RocketChat = {
|
|||
getUserRoles() {
|
||||
return call('getUserRoles');
|
||||
},
|
||||
getRoomCounters(roomId, t) {
|
||||
return SDK.api.get(`${ this.roomTypeToApiType(t) }.counters`, { roomId });
|
||||
},
|
||||
async getRoomMember(rid, currentUserId) {
|
||||
try {
|
||||
const membersResult = await RocketChat.getRoomMembers(rid, true);
|
||||
|
@ -716,8 +689,8 @@ const RocketChat = {
|
|||
}
|
||||
return call('unblockUser', { rid, blocked });
|
||||
},
|
||||
leaveRoom(rid) {
|
||||
return call('leaveRoom', rid);
|
||||
leaveRoom(roomId, t) {
|
||||
return SDK.api.post(`${ this.roomTypeToApiType(t) }.leave`, { roomId });
|
||||
},
|
||||
eraseRoom(rid) {
|
||||
return call('eraseRoom', rid);
|
||||
|
@ -743,8 +716,8 @@ const RocketChat = {
|
|||
saveUserPreferences(params) {
|
||||
return call('saveUserPreferences', params);
|
||||
},
|
||||
saveNotificationSettings(rid, param, value) {
|
||||
return call('saveNotificationSettings', rid, param, value);
|
||||
saveNotificationSettings(roomId, notifications) {
|
||||
return SDK.api.post('rooms.saveNotification', { roomId, notifications });
|
||||
},
|
||||
messageSearch(text, rid, limit) {
|
||||
return call('messageSearch', text, rid, limit);
|
||||
|
@ -824,7 +797,13 @@ const RocketChat = {
|
|||
}
|
||||
},
|
||||
getUsernameSuggestion() {
|
||||
return SDK.driver.asyncCall('getUsernameSuggestion');
|
||||
return SDK.api.get('users.getUsernameSuggestion');
|
||||
},
|
||||
roomTypeToApiType(t) {
|
||||
const types = {
|
||||
c: 'channels', d: 'im', p: 'groups'
|
||||
};
|
||||
return types[t];
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import { APP } from '../actions/actionsTypes';
|
|||
const initialState = {
|
||||
root: null,
|
||||
stackRoot: 'RoomsListView',
|
||||
starting: true,
|
||||
ready: false,
|
||||
inactive: false,
|
||||
background: false
|
||||
|
@ -46,14 +45,12 @@ export default function app(state = initialState, action) {
|
|||
case APP.INIT:
|
||||
return {
|
||||
...state,
|
||||
ready: false,
|
||||
starting: true
|
||||
ready: false
|
||||
};
|
||||
case APP.READY:
|
||||
return {
|
||||
...state,
|
||||
ready: true,
|
||||
starting: false
|
||||
ready: true
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
|
|
|
@ -2,10 +2,7 @@ import { METEOR } from '../actions/actionsTypes';
|
|||
|
||||
const initialState = {
|
||||
connecting: false,
|
||||
connected: false,
|
||||
errorMessage: '',
|
||||
disconnected_by_user: false,
|
||||
failure: false
|
||||
connected: false
|
||||
};
|
||||
|
||||
export default function connect(state = initialState, action) {
|
||||
|
@ -13,28 +10,13 @@ export default function connect(state = initialState, action) {
|
|||
case METEOR.REQUEST:
|
||||
return {
|
||||
...state,
|
||||
connecting: true,
|
||||
disconnected_by_user: false
|
||||
connecting: true
|
||||
};
|
||||
case METEOR.SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
connecting: false,
|
||||
connected: true,
|
||||
failure: false
|
||||
};
|
||||
case METEOR.FAILURE:
|
||||
return {
|
||||
...state,
|
||||
connecting: false,
|
||||
connected: false,
|
||||
failure: true,
|
||||
errorMessage: action.err
|
||||
};
|
||||
case METEOR.DISCONNECT_BY_USER:
|
||||
return {
|
||||
...state,
|
||||
disconnected_by_user: true
|
||||
connected: true
|
||||
};
|
||||
case METEOR.DISCONNECT:
|
||||
return initialState;
|
||||
|
|
|
@ -3,11 +3,9 @@ import * as types from '../actions/actionsTypes';
|
|||
const initialState = {
|
||||
isAuthenticated: false,
|
||||
isFetching: false,
|
||||
token: '',
|
||||
user: {},
|
||||
error: '',
|
||||
services: {},
|
||||
credentials: {}
|
||||
error: {},
|
||||
services: {}
|
||||
};
|
||||
|
||||
export default function login(state = initialState, action) {
|
||||
|
@ -20,21 +18,16 @@ export default function login(state = initialState, action) {
|
|||
isFetching: true,
|
||||
isAuthenticated: false,
|
||||
failure: false,
|
||||
error: ''
|
||||
error: {}
|
||||
};
|
||||
case types.LOGIN.SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
isFetching: false,
|
||||
isAuthenticated: true,
|
||||
user: {
|
||||
...state.user,
|
||||
...action.user
|
||||
},
|
||||
token: action.user.token,
|
||||
user: action.user,
|
||||
failure: false,
|
||||
error: '',
|
||||
credentials: {}
|
||||
error: {}
|
||||
};
|
||||
case types.LOGIN.FAILURE:
|
||||
return {
|
||||
|
@ -46,70 +39,12 @@ export default function login(state = initialState, action) {
|
|||
};
|
||||
case types.LOGOUT:
|
||||
return initialState;
|
||||
case types.LOGIN.SET_TOKEN:
|
||||
return {
|
||||
...state,
|
||||
token: action.token,
|
||||
user: action.user
|
||||
};
|
||||
case types.LOGIN.RESTORE_TOKEN:
|
||||
return {
|
||||
...state,
|
||||
token: action.token
|
||||
};
|
||||
case types.LOGIN.REGISTER_SUBMIT:
|
||||
return {
|
||||
...state,
|
||||
isFetching: true,
|
||||
failure: false,
|
||||
error: '',
|
||||
credentials: action.credentials
|
||||
};
|
||||
case types.LOGIN.REGISTER_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
isFetching: false,
|
||||
failure: false,
|
||||
error: '',
|
||||
credentials: {}
|
||||
};
|
||||
case types.LOGIN.SET_USERNAME_SUBMIT:
|
||||
return {
|
||||
...state,
|
||||
isFetching: true,
|
||||
credentials: action.credentials
|
||||
};
|
||||
case types.LOGIN.SET_USERNAME_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
isFetching: false
|
||||
};
|
||||
case types.FORGOT_PASSWORD.REQUEST:
|
||||
return {
|
||||
...state,
|
||||
isFetching: true,
|
||||
failure: false,
|
||||
success: false
|
||||
};
|
||||
case types.FORGOT_PASSWORD.SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
isFetching: false,
|
||||
success: true
|
||||
};
|
||||
case types.FORGOT_PASSWORD.FAILURE:
|
||||
return {
|
||||
...state,
|
||||
isFetching: false,
|
||||
failure: true,
|
||||
error: action.err
|
||||
};
|
||||
case types.USER.SET:
|
||||
return {
|
||||
...state,
|
||||
user: {
|
||||
...state.user,
|
||||
...action
|
||||
...action.user
|
||||
}
|
||||
};
|
||||
case types.LOGIN.SET_SERVICES:
|
||||
|
|
|
@ -2,9 +2,9 @@ import { SORT_PREFERENCES } from '../actions/actionsTypes';
|
|||
|
||||
const initialState = {
|
||||
sortBy: 'activity',
|
||||
groupByType: true,
|
||||
showFavorites: true,
|
||||
showUnread: true
|
||||
groupByType: false,
|
||||
showFavorites: false,
|
||||
showUnread: false
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
import {
|
||||
call, takeLatest, select, put
|
||||
} from 'redux-saga/effects';
|
||||
import { AsyncStorage } from 'react-native';
|
||||
import { METEOR } from '../actions/actionsTypes';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
import { setToken } from '../actions/login';
|
||||
|
||||
const getServer = ({ server }) => server.server;
|
||||
const getToken = function* getToken() {
|
||||
const currentServer = yield select(getServer);
|
||||
const user = yield call([AsyncStorage, 'getItem'], `${ RocketChat.TOKEN_KEY }-${ currentServer }`);
|
||||
if (user) {
|
||||
yield put(setToken(JSON.parse(user)));
|
||||
try {
|
||||
yield call([AsyncStorage, 'setItem'], RocketChat.TOKEN_KEY, JSON.parse(user).token || '');
|
||||
} catch (error) {
|
||||
console.warn('getToken', error);
|
||||
}
|
||||
return JSON.parse(user);
|
||||
}
|
||||
|
||||
yield AsyncStorage.removeItem(RocketChat.TOKEN_KEY);
|
||||
yield put(setToken());
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
const connect = (...args) => RocketChat.connect(...args);
|
||||
|
||||
const test = function* test() {
|
||||
try {
|
||||
const server = yield select(getServer);
|
||||
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 } : null);
|
||||
// yield put(connectSuccess(response));
|
||||
} catch (err) {
|
||||
console.warn('test', err);
|
||||
// yield put(connectFailure(err.status));
|
||||
}
|
||||
};
|
||||
|
||||
const root = function* root() {
|
||||
yield takeLatest(METEOR.REQUEST, test);
|
||||
// yield take(METEOR.SUCCESS, watchConnect);
|
||||
// yield takeLatest(METEOR.SUCCESS, watchConnect);
|
||||
};
|
||||
export default root;
|
|
@ -1,6 +1,5 @@
|
|||
import { all } from 'redux-saga/effects';
|
||||
import login from './login';
|
||||
import connect from './connect';
|
||||
import rooms from './rooms';
|
||||
import messages from './messages';
|
||||
import selectServer from './selectServer';
|
||||
|
@ -20,7 +19,6 @@ const root = function* root() {
|
|||
createChannel(),
|
||||
rooms(),
|
||||
login(),
|
||||
connect(),
|
||||
messages(),
|
||||
selectServer(),
|
||||
state(),
|
||||
|
|
|
@ -1,44 +1,33 @@
|
|||
import { AsyncStorage } from 'react-native';
|
||||
import { call, put, takeLatest } from 'redux-saga/effects';
|
||||
import { put, takeLatest, all } from 'redux-saga/effects';
|
||||
|
||||
import * as actions from '../actions';
|
||||
import { selectServerRequest } from '../actions/server';
|
||||
import { restoreToken, setUser } from '../actions/login';
|
||||
import { setAllPreferences } from '../actions/sortPreferences';
|
||||
import { APP } from '../actions/actionsTypes';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
import log from '../utils/log';
|
||||
import I18n from '../i18n';
|
||||
|
||||
const restore = function* restore() {
|
||||
try {
|
||||
const token = yield call([AsyncStorage, 'getItem'], RocketChat.TOKEN_KEY);
|
||||
if (token) {
|
||||
yield put(restoreToken(token));
|
||||
} else {
|
||||
yield put(actions.appStart('outside'));
|
||||
}
|
||||
|
||||
const currentServer = yield call([AsyncStorage, 'getItem'], 'currentServer');
|
||||
if (currentServer) {
|
||||
const user = yield call([AsyncStorage, 'getItem'], `${ RocketChat.TOKEN_KEY }-${ currentServer }`);
|
||||
if (user) {
|
||||
const userParsed = JSON.parse(user);
|
||||
if (userParsed.language) {
|
||||
I18n.locale = userParsed.language;
|
||||
}
|
||||
yield put(selectServerRequest(currentServer));
|
||||
yield put(setUser(userParsed));
|
||||
} else {
|
||||
yield put(actions.appStart('outside'));
|
||||
}
|
||||
} else {
|
||||
yield put(actions.appStart('outside'));
|
||||
}
|
||||
const { token, server } = yield all({
|
||||
token: AsyncStorage.getItem(RocketChat.TOKEN_KEY),
|
||||
server: AsyncStorage.getItem('currentServer')
|
||||
});
|
||||
|
||||
const sortPreferences = yield RocketChat.getSortPreferences();
|
||||
yield put(setAllPreferences(sortPreferences));
|
||||
|
||||
if (!token || !server) {
|
||||
yield all([
|
||||
AsyncStorage.removeItem(RocketChat.TOKEN_KEY),
|
||||
AsyncStorage.removeItem('currentServer')
|
||||
]);
|
||||
yield put(actions.appStart('outside'));
|
||||
} else if (server) {
|
||||
yield put(selectServerRequest(server));
|
||||
}
|
||||
|
||||
yield put(actions.appReady({}));
|
||||
} catch (e) {
|
||||
log('restore', e);
|
||||
|
|
|
@ -1,83 +1,68 @@
|
|||
import { AsyncStorage } from 'react-native';
|
||||
import { delay } from 'redux-saga';
|
||||
import {
|
||||
put, call, takeLatest, select, all
|
||||
put, call, takeLatest, select
|
||||
} from 'redux-saga/effects';
|
||||
import { Navigation } from 'react-native-navigation';
|
||||
|
||||
import * as types from '../actions/actionsTypes';
|
||||
import { appStart } from '../actions';
|
||||
import { serverFinishAdd } from '../actions/server';
|
||||
import {
|
||||
registerRequest,
|
||||
loginFailure,
|
||||
setUsernameRequest,
|
||||
setUsernameSuccess,
|
||||
forgotPasswordSuccess,
|
||||
forgotPasswordFailure
|
||||
} from '../actions/login';
|
||||
import { loginFailure, loginSuccess } from '../actions/login';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
import log from '../utils/log';
|
||||
import I18n from '../i18n';
|
||||
|
||||
const getUser = state => state.login.user;
|
||||
const getServer = state => state.server.server;
|
||||
|
||||
const loginCall = args => RocketChat.loginWithPassword(args);
|
||||
const registerCall = args => RocketChat.register(args);
|
||||
const setUsernameCall = args => RocketChat.setUsername(args);
|
||||
const loginSuccessCall = () => RocketChat.loginSuccess();
|
||||
const loginWithPasswordCall = args => RocketChat.loginWithPassword(args);
|
||||
const loginCall = args => RocketChat.login(args);
|
||||
const logoutCall = args => RocketChat.logout(args);
|
||||
const forgotPasswordCall = args => RocketChat.forgotPassword(args);
|
||||
|
||||
const handleLoginSuccess = function* handleLoginSuccess() {
|
||||
const handleLoginRequest = function* handleLoginRequest({ credentials }) {
|
||||
try {
|
||||
const user = yield select(getUser);
|
||||
const adding = yield select(state => state.server.adding);
|
||||
yield AsyncStorage.setItem(RocketChat.TOKEN_KEY, user.token);
|
||||
|
||||
if (!user.username) {
|
||||
return yield put(appStart('setUsername'));
|
||||
}
|
||||
|
||||
if (adding) {
|
||||
yield put(serverFinishAdd());
|
||||
yield Navigation.dismissAllModals();
|
||||
let result;
|
||||
if (credentials.resume) {
|
||||
result = yield call(loginCall, credentials);
|
||||
} else {
|
||||
yield put(appStart('inside'));
|
||||
result = yield call(loginWithPasswordCall, credentials);
|
||||
}
|
||||
} catch (e) {
|
||||
log('handleLoginSuccess', e);
|
||||
if (result.status === 'success') {
|
||||
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
|
||||
};
|
||||
return yield put(loginSuccess(user));
|
||||
}
|
||||
} catch (error) {
|
||||
yield put(loginFailure(error));
|
||||
}
|
||||
};
|
||||
|
||||
const handleRegisterSubmit = function* handleRegisterSubmit({ credentials }) {
|
||||
yield put(registerRequest(credentials));
|
||||
};
|
||||
const handleLoginSuccess = function* handleLoginSuccess({ user }) {
|
||||
const adding = yield select(state => state.server.adding);
|
||||
yield AsyncStorage.setItem(RocketChat.TOKEN_KEY, user.token);
|
||||
|
||||
const handleRegisterRequest = function* handleRegisterRequest({ credentials }) {
|
||||
const server = yield select(getServer);
|
||||
try {
|
||||
yield call(registerCall, { credentials });
|
||||
yield call(loginCall, {
|
||||
username: credentials.email,
|
||||
password: credentials.pass
|
||||
});
|
||||
} catch (err) {
|
||||
yield put(loginFailure(err));
|
||||
RocketChat.loginSuccess({ user });
|
||||
I18n.locale = user.language;
|
||||
yield AsyncStorage.setItem(`${ RocketChat.TOKEN_KEY }-${ server }`, JSON.stringify(user));
|
||||
} catch (error) {
|
||||
console.log('loginSuccess saga -> error', error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSetUsernameSubmit = function* handleSetUsernameSubmit({ credentials }) {
|
||||
yield put(setUsernameRequest(credentials));
|
||||
};
|
||||
|
||||
const handleSetUsernameRequest = function* handleSetUsernameRequest({ credentials }) {
|
||||
try {
|
||||
yield call(setUsernameCall, credentials);
|
||||
yield put(setUsernameSuccess());
|
||||
yield call(loginSuccessCall);
|
||||
} catch (err) {
|
||||
yield put(loginFailure(err));
|
||||
if (!user.username) {
|
||||
RocketChat.loginSuccess({ user });
|
||||
yield put(appStart('setUsername'));
|
||||
} else if (adding) {
|
||||
yield put(serverFinishAdd());
|
||||
yield Navigation.dismissAllModals();
|
||||
} else {
|
||||
yield put(appStart('inside'));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -85,42 +70,24 @@ const handleLogout = function* handleLogout() {
|
|||
const server = yield select(getServer);
|
||||
if (server) {
|
||||
try {
|
||||
yield put(appStart('outside'));
|
||||
yield call(logoutCall, { server });
|
||||
yield put(appStart('outside'));
|
||||
} catch (e) {
|
||||
log('handleLogout', e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleForgotPasswordRequest = function* handleForgotPasswordRequest({ email }) {
|
||||
try {
|
||||
yield call(forgotPasswordCall, email);
|
||||
yield put(forgotPasswordSuccess());
|
||||
} catch (err) {
|
||||
yield put(forgotPasswordFailure(err));
|
||||
}
|
||||
};
|
||||
|
||||
const handleSetUser = function* handleSetUser() {
|
||||
yield delay(2000);
|
||||
const [server, user] = yield all([select(getServer), select(getUser)]);
|
||||
if (user && user.id) {
|
||||
if (user.language) {
|
||||
I18n.locale = user.language;
|
||||
}
|
||||
yield AsyncStorage.setItem(`${ RocketChat.TOKEN_KEY }-${ server }`, JSON.stringify(user));
|
||||
const handleSetUser = function handleSetUser({ user }) {
|
||||
if (user && user.language) {
|
||||
I18n.locale = user.language;
|
||||
}
|
||||
};
|
||||
|
||||
const root = function* root() {
|
||||
yield takeLatest(types.LOGIN.REQUEST, handleLoginRequest);
|
||||
yield takeLatest(types.LOGIN.SUCCESS, handleLoginSuccess);
|
||||
yield takeLatest(types.LOGIN.REGISTER_REQUEST, handleRegisterRequest);
|
||||
yield takeLatest(types.LOGIN.REGISTER_SUBMIT, handleRegisterSubmit);
|
||||
yield takeLatest(types.LOGIN.SET_USERNAME_SUBMIT, handleSetUsernameSubmit);
|
||||
yield takeLatest(types.LOGIN.SET_USERNAME_REQUEST, handleSetUsernameRequest);
|
||||
yield takeLatest(types.LOGOUT, handleLogout);
|
||||
yield takeLatest(types.FORGOT_PASSWORD.REQUEST, handleForgotPasswordRequest);
|
||||
yield takeLatest(types.USER.SET, handleSetUser);
|
||||
};
|
||||
export default root;
|
||||
|
|
|
@ -34,8 +34,7 @@ const get = function* get({ room }) {
|
|||
}
|
||||
yield put(messagesSuccess());
|
||||
} catch (err) {
|
||||
console.warn('messagesFailure', err);
|
||||
yield put(messagesFailure(err.status));
|
||||
yield put(messagesFailure(err));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -3,37 +3,21 @@ import {
|
|||
put, call, takeLatest, take, select, race, fork, cancel, takeEvery
|
||||
} from 'redux-saga/effects';
|
||||
import { delay } from 'redux-saga';
|
||||
import { BACKGROUND } from 'redux-enhancer-react-native-appstate';
|
||||
import { Navigation } from 'react-native-navigation';
|
||||
|
||||
import * as types from '../actions/actionsTypes';
|
||||
// import { roomsSuccess, roomsFailure } from '../actions/rooms';
|
||||
import { addUserTyping, removeUserTyping, setLastOpen } from '../actions/room';
|
||||
import { addUserTyping, removeUserTyping } from '../actions/room';
|
||||
import { messagesRequest, editCancel, replyCancel } from '../actions/messages';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
import database from '../lib/realm';
|
||||
import log from '../utils/log';
|
||||
import I18n from '../i18n';
|
||||
|
||||
const leaveRoom = rid => RocketChat.leaveRoom(rid);
|
||||
const eraseRoom = rid => RocketChat.eraseRoom(rid);
|
||||
|
||||
let sub;
|
||||
let thread;
|
||||
|
||||
// const getRooms = function* getRooms() {
|
||||
// return yield RocketChat.getRooms();
|
||||
// };
|
||||
|
||||
// const watchRoomsRequest = function* watchRoomsRequest() {
|
||||
// try {
|
||||
// yield call(getRooms);
|
||||
// yield put(roomsSuccess());
|
||||
// } catch (err) {
|
||||
// yield put(roomsFailure(err.status));
|
||||
// }
|
||||
// };
|
||||
|
||||
const cancelTyping = function* cancelTyping(username) {
|
||||
while (true) {
|
||||
const { typing, timeout } = yield race({
|
||||
|
@ -89,7 +73,13 @@ const watchRoomOpen = function* watchRoomOpen({ room }) {
|
|||
if (room._id) {
|
||||
RocketChat.readMessages(room.rid);
|
||||
}
|
||||
|
||||
const auth = yield select(state => state.login.isAuthenticated);
|
||||
if (!auth) {
|
||||
yield take(types.LOGIN.SUCCESS);
|
||||
}
|
||||
sub = yield RocketChat.subscribeRoom(room);
|
||||
|
||||
thread = yield fork(usersTyping, { rid: room.rid });
|
||||
yield race({
|
||||
open: take(types.ROOM.OPEN),
|
||||
|
@ -129,20 +119,8 @@ const watchuserTyping = function* watchuserTyping({ status }) {
|
|||
}
|
||||
};
|
||||
|
||||
// const updateRoom = function* updateRoom() {
|
||||
// const room = yield select(state => state.room);
|
||||
// if (!room || !room.rid) {
|
||||
// return;
|
||||
// }
|
||||
// yield put(messagesRequest({ rid: room.rid }));
|
||||
// };
|
||||
|
||||
const updateLastOpen = function* updateLastOpen() {
|
||||
yield put(setLastOpen());
|
||||
};
|
||||
|
||||
const goRoomsListAndDelete = function* goRoomsListAndDelete(rid, type) {
|
||||
yield Navigation.popToRoot(type === 'erase' ? 'RoomActionsView' : 'RoomInfoEditView');
|
||||
const goRoomsListAndDelete = function* goRoomsListAndDelete(rid) {
|
||||
yield Navigation.popToRoot('RoomsListView');
|
||||
try {
|
||||
database.write(() => {
|
||||
const messages = database.objects('messages').filtered('rid = $0', rid);
|
||||
|
@ -155,16 +133,16 @@ const goRoomsListAndDelete = function* goRoomsListAndDelete(rid, type) {
|
|||
}
|
||||
};
|
||||
|
||||
const handleLeaveRoom = function* handleLeaveRoom({ rid }) {
|
||||
const handleLeaveRoom = function* handleLeaveRoom({ rid, t }) {
|
||||
try {
|
||||
sub.stop();
|
||||
yield call(leaveRoom, rid);
|
||||
yield goRoomsListAndDelete(rid, 'delete');
|
||||
yield RocketChat.leaveRoom(rid, t);
|
||||
yield goRoomsListAndDelete(rid);
|
||||
} catch (e) {
|
||||
if (e.error === 'error-you-are-last-owner') {
|
||||
Alert.alert(I18n.t(e.error));
|
||||
if (e.data && e.data.errorType === 'error-you-are-last-owner') {
|
||||
Alert.alert(I18n.t('Oops'), I18n.t(e.data.errorType));
|
||||
} else {
|
||||
Alert.alert(I18n.t('There_was_an_error_while_action', { action: I18n.t('leaving_room') }));
|
||||
Alert.alert(I18n.t('Oops'), I18n.t('There_was_an_error_while_action', { action: I18n.t('leaving_room') }));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -172,10 +150,10 @@ const handleLeaveRoom = function* handleLeaveRoom({ rid }) {
|
|||
const handleEraseRoom = function* handleEraseRoom({ rid }) {
|
||||
try {
|
||||
sub.stop();
|
||||
yield call(eraseRoom, rid);
|
||||
yield eraseRoom(rid);
|
||||
yield goRoomsListAndDelete(rid, 'erase');
|
||||
} catch (e) {
|
||||
Alert.alert(I18n.t('There_was_an_error_while_action', { action: I18n.t('erasing_room') }));
|
||||
Alert.alert(I18n.t('Oops'), I18n.t('There_was_an_error_while_action', { action: I18n.t('erasing_room') }));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -183,9 +161,6 @@ const root = function* root() {
|
|||
yield takeLatest(types.ROOM.USER_TYPING, watchuserTyping);
|
||||
yield takeLatest(types.ROOM.OPEN, watchRoomOpen);
|
||||
yield takeEvery(types.ROOM.MESSAGE_RECEIVED, handleMessageReceived);
|
||||
// yield takeLatest(FOREGROUND, updateRoom);
|
||||
// yield takeLatest(FOREGROUND, watchRoomsRequest);
|
||||
yield takeLatest(BACKGROUND, updateLastOpen);
|
||||
yield takeLatest(types.ROOM.LEAVE, handleLeaveRoom);
|
||||
yield takeLatest(types.ROOM.ERASE, handleEraseRoom);
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { put, call, takeLatest } from 'redux-saga/effects';
|
||||
import { put, takeLatest } from 'redux-saga/effects';
|
||||
import { AsyncStorage } from 'react-native';
|
||||
import { Navigation } from 'react-native-navigation';
|
||||
import { Provider } from 'react-redux';
|
||||
|
@ -6,9 +6,9 @@ import { gestureHandlerRootHOC } from 'react-native-gesture-handler';
|
|||
|
||||
import { SERVER } from '../actions/actionsTypes';
|
||||
import * as actions from '../actions';
|
||||
import { connectRequest } from '../actions/connect';
|
||||
import { serverFailure, selectServerRequest, selectServerSuccess } from '../actions/server';
|
||||
import { setRoles } from '../actions/roles';
|
||||
import { setUser } from '../actions/login';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
import database from '../lib/realm';
|
||||
import log from '../utils/log';
|
||||
|
@ -19,16 +19,20 @@ let LoginView = null;
|
|||
|
||||
const handleSelectServer = function* handleSelectServer({ server }) {
|
||||
try {
|
||||
yield database.setActiveDB(server);
|
||||
yield put(connectRequest());
|
||||
yield call([AsyncStorage, 'setItem'], 'currentServer', server);
|
||||
const token = yield AsyncStorage.getItem(`${ RocketChat.TOKEN_KEY }-${ server }`);
|
||||
if (token) {
|
||||
yield AsyncStorage.setItem('currentServer', server);
|
||||
const userStringified = yield AsyncStorage.getItem(`${ RocketChat.TOKEN_KEY }-${ server }`);
|
||||
|
||||
if (userStringified) {
|
||||
const user = JSON.parse(userStringified);
|
||||
yield put(setUser(user));
|
||||
yield put(actions.appStart('inside'));
|
||||
RocketChat.connect({ server, user });
|
||||
} else {
|
||||
RocketChat.connect({ server });
|
||||
}
|
||||
|
||||
const settings = database.objects('settings');
|
||||
yield put(actions.setAllSettings(RocketChat.parseSettings(RocketChat._filterSettings(settings.slice(0, settings.length)))));
|
||||
yield put(actions.setAllSettings(RocketChat.parseSettings(settings.slice(0, settings.length))));
|
||||
const emojis = database.objects('customEmojis');
|
||||
yield put(actions.setCustomEmojis(RocketChat.parseEmojis(emojis.slice(0, emojis.length))));
|
||||
const roles = database.objects('roles');
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { takeLatest, select } from 'redux-saga/effects';
|
||||
import { FOREGROUND, BACKGROUND, INACTIVE } from 'redux-enhancer-react-native-appstate';
|
||||
import { FOREGROUND, BACKGROUND } from 'redux-enhancer-react-native-appstate';
|
||||
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
import log from '../utils/log';
|
||||
import { setBadgeCount } from '../push';
|
||||
|
||||
const appHasComeBackToForeground = function* appHasComeBackToForeground() {
|
||||
|
@ -18,7 +17,7 @@ const appHasComeBackToForeground = function* appHasComeBackToForeground() {
|
|||
setBadgeCount();
|
||||
return yield RocketChat.setUserPresenceOnline();
|
||||
} catch (e) {
|
||||
log('appHasComeBackToForeground', e);
|
||||
console.log('appHasComeBackToForeground', e);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -34,7 +33,7 @@ const appHasComeBackToBackground = function* appHasComeBackToBackground() {
|
|||
try {
|
||||
return yield RocketChat.setUserPresenceAway();
|
||||
} catch (e) {
|
||||
log('appHasComeBackToBackground', e);
|
||||
console.log('appHasComeBackToBackground', e);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -47,10 +46,10 @@ const root = function* root() {
|
|||
BACKGROUND,
|
||||
appHasComeBackToBackground
|
||||
);
|
||||
yield takeLatest(
|
||||
INACTIVE,
|
||||
appHasComeBackToBackground
|
||||
);
|
||||
// yield takeLatest(
|
||||
// INACTIVE,
|
||||
// appHasComeBackToBackground
|
||||
// );
|
||||
};
|
||||
|
||||
export default root;
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
export default function isValidEmail(email) {
|
||||
/* eslint-disable no-useless-escape */
|
||||
const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
return reg.test(email);
|
||||
}
|
|
@ -4,7 +4,7 @@ export default (event, error) => {
|
|||
if (typeof error !== 'object') {
|
||||
error = { error };
|
||||
}
|
||||
Answers.logCustom(event, error);
|
||||
Answers.logCustom(event);
|
||||
if (__DEV__) {
|
||||
console.warn(event, error);
|
||||
}
|
||||
|
|
|
@ -1,26 +1,21 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Text, ScrollView } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import { Navigation } from 'react-native-navigation';
|
||||
import SafeAreaView from 'react-native-safe-area-view';
|
||||
|
||||
import LoggedView from './View';
|
||||
import { forgotPasswordRequest as forgotPasswordRequestAction } from '../actions/login';
|
||||
import KeyboardView from '../presentation/KeyboardView';
|
||||
import TextInput from '../containers/TextInput';
|
||||
import Button from '../containers/Button';
|
||||
import sharedStyles from './Styles';
|
||||
import { showErrorAlert } from '../utils/info';
|
||||
import isValidEmail from '../utils/isValidEmail';
|
||||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||
import I18n from '../i18n';
|
||||
import { DARK_HEADER } from '../constants/headerOptions';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
|
||||
@connect(state => ({
|
||||
login: state.login
|
||||
}), dispatch => ({
|
||||
forgotPasswordRequest: email => dispatch(forgotPasswordRequestAction(email))
|
||||
}))
|
||||
/** @extends React.Component */
|
||||
export default class ForgotPasswordView extends LoggedView {
|
||||
static options() {
|
||||
|
@ -30,9 +25,7 @@ export default class ForgotPasswordView extends LoggedView {
|
|||
}
|
||||
|
||||
static propTypes = {
|
||||
componentId: PropTypes.string,
|
||||
forgotPasswordRequest: PropTypes.func.isRequired,
|
||||
login: PropTypes.object
|
||||
componentId: PropTypes.string
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
|
@ -40,7 +33,8 @@ export default class ForgotPasswordView extends LoggedView {
|
|||
|
||||
this.state = {
|
||||
email: '',
|
||||
invalidEmail: true
|
||||
invalidEmail: true,
|
||||
isFetching: false
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -50,16 +44,6 @@ export default class ForgotPasswordView extends LoggedView {
|
|||
}, 600);
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const { login, componentId } = this.props;
|
||||
if (login.success) {
|
||||
Navigation.pop(componentId);
|
||||
setTimeout(() => {
|
||||
showErrorAlert(I18n.t('Forgot_password_If_this_email_is_registered'), I18n.t('Alert'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
|
@ -67,27 +51,35 @@ export default class ForgotPasswordView extends LoggedView {
|
|||
}
|
||||
|
||||
validate = (email) => {
|
||||
/* eslint-disable no-useless-escape */
|
||||
const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
if (!reg.test(email)) {
|
||||
if (!isValidEmail(email)) {
|
||||
this.setState({ invalidEmail: true });
|
||||
return;
|
||||
}
|
||||
this.setState({ email, invalidEmail: false });
|
||||
}
|
||||
|
||||
resetPassword = () => {
|
||||
resetPassword = async() => {
|
||||
const { email, invalidEmail } = this.state;
|
||||
const { forgotPasswordRequest } = this.props;
|
||||
if (invalidEmail || !email) {
|
||||
return;
|
||||
}
|
||||
forgotPasswordRequest(email);
|
||||
try {
|
||||
this.setState({ isFetching: true });
|
||||
const result = await RocketChat.forgotPassword(email);
|
||||
if (result.success) {
|
||||
const { componentId } = this.props;
|
||||
Navigation.pop(componentId);
|
||||
showErrorAlert(I18n.t('Forgot_password_If_this_email_is_registered'), I18n.t('Alert'));
|
||||
}
|
||||
} catch (e) {
|
||||
const msg = (e.data && e.data.error) || I18n.t('There_was_an_error_while_action', I18n.t('resetting_password'));
|
||||
showErrorAlert(msg, I18n.t('Alert'));
|
||||
}
|
||||
this.setState({ isFetching: false });
|
||||
}
|
||||
|
||||
render() {
|
||||
const { invalidEmail } = this.state;
|
||||
const { login } = this.props;
|
||||
const { invalidEmail, isFetching } = this.state;
|
||||
|
||||
return (
|
||||
<KeyboardView
|
||||
|
@ -113,7 +105,7 @@ export default class ForgotPasswordView extends LoggedView {
|
|||
type='primary'
|
||||
onPress={this.resetPassword}
|
||||
testID='forgot-password-view-submit'
|
||||
loading={login.isFetching}
|
||||
loading={isFetching}
|
||||
disabled={invalidEmail}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
|
|
|
@ -95,8 +95,6 @@ const SERVICES_COLLAPSED_HEIGHT = 174;
|
|||
@connect(state => ({
|
||||
server: state.server.server,
|
||||
isFetching: state.login.isFetching,
|
||||
Accounts_EmailOrUsernamePlaceholder: state.settings.Accounts_EmailOrUsernamePlaceholder,
|
||||
Accounts_PasswordPlaceholder: state.settings.Accounts_PasswordPlaceholder,
|
||||
Site_Name: state.settings.Site_Name,
|
||||
services: state.login.services
|
||||
}))
|
||||
|
@ -120,16 +118,8 @@ export default class LoginSignupView extends LoggedView {
|
|||
componentId: PropTypes.string,
|
||||
isFetching: PropTypes.bool,
|
||||
server: PropTypes.string,
|
||||
Accounts_EmailOrUsernamePlaceholder: PropTypes.bool,
|
||||
Accounts_PasswordPlaceholder: PropTypes.string,
|
||||
Accounts_OAuth_Facebook: PropTypes.bool,
|
||||
Accounts_OAuth_Github: PropTypes.bool,
|
||||
Accounts_OAuth_Gitlab: PropTypes.bool,
|
||||
Accounts_OAuth_Google: PropTypes.bool,
|
||||
Accounts_OAuth_Linkedin: PropTypes.bool,
|
||||
Accounts_OAuth_Meteor: PropTypes.bool,
|
||||
Accounts_OAuth_Twitter: PropTypes.bool,
|
||||
services: PropTypes.object
|
||||
services: PropTypes.object,
|
||||
Site_Name: PropTypes.string
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
|
|
|
@ -8,8 +8,8 @@ import { Navigation } from 'react-native-navigation';
|
|||
import { Answers } from 'react-native-fabric';
|
||||
import SafeAreaView from 'react-native-safe-area-view';
|
||||
import { gestureHandlerRootHOC } from 'react-native-gesture-handler';
|
||||
import equal from 'deep-equal';
|
||||
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
import KeyboardView from '../presentation/KeyboardView';
|
||||
import TextInput from '../containers/TextInput';
|
||||
import Button from '../containers/Button';
|
||||
|
@ -19,6 +19,7 @@ import LoggedView from './View';
|
|||
import I18n from '../i18n';
|
||||
import store from '../lib/createStore';
|
||||
import { DARK_HEADER } from '../constants/headerOptions';
|
||||
import { loginRequest as loginRequestAction } from '../actions/login';
|
||||
|
||||
let RegisterView = null;
|
||||
let ForgotPasswordView = null;
|
||||
|
@ -52,11 +53,13 @@ const styles = StyleSheet.create({
|
|||
|
||||
@connect(state => ({
|
||||
isFetching: state.login.isFetching,
|
||||
failure: state.login.failure,
|
||||
error: state.login.error,
|
||||
Site_Name: state.settings.Site_Name,
|
||||
Accounts_EmailOrUsernamePlaceholder: state.settings.Accounts_EmailOrUsernamePlaceholder,
|
||||
Accounts_PasswordPlaceholder: state.settings.Accounts_PasswordPlaceholder
|
||||
}), () => ({
|
||||
loginSubmit: params => RocketChat.loginWithPassword(params)
|
||||
}), dispatch => ({
|
||||
loginRequest: params => dispatch(loginRequestAction(params))
|
||||
}))
|
||||
/** @extends React.Component */
|
||||
export default class LoginView extends LoggedView {
|
||||
|
@ -76,18 +79,19 @@ export default class LoginView extends LoggedView {
|
|||
|
||||
static propTypes = {
|
||||
componentId: PropTypes.string,
|
||||
loginSubmit: PropTypes.func.isRequired,
|
||||
login: PropTypes.object,
|
||||
loginRequest: PropTypes.func.isRequired,
|
||||
error: PropTypes.object,
|
||||
Site_Name: PropTypes.string,
|
||||
Accounts_EmailOrUsernamePlaceholder: PropTypes.string,
|
||||
Accounts_PasswordPlaceholder: PropTypes.string,
|
||||
isFetching: PropTypes.bool
|
||||
isFetching: PropTypes.bool,
|
||||
failure: PropTypes.bool
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super('LoginView', props);
|
||||
this.state = {
|
||||
username: '',
|
||||
user: '',
|
||||
password: '',
|
||||
code: '',
|
||||
showTOTP: false
|
||||
|
@ -103,10 +107,22 @@ export default class LoginView extends LoggedView {
|
|||
}, 600);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const { componentId, Site_Name } = this.props;
|
||||
if (Site_Name && prevProps.Site_Name !== Site_Name) {
|
||||
this.setTitle(componentId, Site_Name);
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const { componentId, Site_Name, error } = this.props;
|
||||
if (Site_Name && nextProps.Site_Name !== Site_Name) {
|
||||
this.setTitle(componentId, nextProps.Site_Name);
|
||||
} else if (nextProps.failure && !equal(error, nextProps.error)) {
|
||||
if (nextProps.error && nextProps.error.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'));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,12 +163,12 @@ export default class LoginView extends LoggedView {
|
|||
|
||||
valid = () => {
|
||||
const {
|
||||
username, password, code, showTOTP
|
||||
user, password, code, showTOTP
|
||||
} = this.state;
|
||||
if (showTOTP) {
|
||||
return code.trim();
|
||||
}
|
||||
return username.trim() && password.trim();
|
||||
return user.trim() && password.trim();
|
||||
}
|
||||
|
||||
submit = async() => {
|
||||
|
@ -160,12 +176,12 @@ export default class LoginView extends LoggedView {
|
|||
return;
|
||||
}
|
||||
|
||||
const { username, password, code } = this.state;
|
||||
const { loginSubmit } = this.props;
|
||||
const { user, password, code } = this.state;
|
||||
const { loginRequest } = this.props;
|
||||
Keyboard.dismiss();
|
||||
|
||||
try {
|
||||
await loginSubmit({ username, password, code });
|
||||
await loginRequest({ user, password, code });
|
||||
Answers.logLogin('Email', true);
|
||||
} catch (e) {
|
||||
if (e && e.error === 'totp-required') {
|
||||
|
@ -265,7 +281,7 @@ export default class LoginView extends LoggedView {
|
|||
keyboardType='email-address'
|
||||
returnKeyType='next'
|
||||
iconLeft='mention'
|
||||
onChangeText={value => this.setState({ username: value })}
|
||||
onChangeText={value => this.setState({ user: value })}
|
||||
onSubmitEditing={() => { this.passwordInput.focus(); }}
|
||||
testID='login-view-email'
|
||||
/>
|
||||
|
|
|
@ -37,6 +37,9 @@ export default class OAuthView extends React.PureComponent {
|
|||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
logging: false
|
||||
};
|
||||
this.redirectRegex = new RegExp(`(?=.*(${ props.server }))(?=.*(credentialToken))(?=.*(credentialSecret))`, 'g');
|
||||
Navigation.events().bindComponent(this);
|
||||
}
|
||||
|
@ -53,11 +56,20 @@ export default class OAuthView extends React.PureComponent {
|
|||
}
|
||||
|
||||
login = async(params) => {
|
||||
const { logging } = this.state;
|
||||
if (logging) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({ logging: true });
|
||||
|
||||
try {
|
||||
await RocketChat.login(params);
|
||||
await RocketChat.loginOAuth(params);
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
}
|
||||
this.setState({ logging: false });
|
||||
this.dismiss();
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -72,7 +84,6 @@ export default class OAuthView extends React.PureComponent {
|
|||
const parts = url.split('#');
|
||||
const credentials = JSON.parse(parts[1]);
|
||||
this.login({ oauth: { ...credentials } });
|
||||
this.dismiss();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
|
|
@ -7,9 +7,7 @@ import { connect, Provider } from 'react-redux';
|
|||
import { Navigation } from 'react-native-navigation';
|
||||
import SafeAreaView from 'react-native-safe-area-view';
|
||||
import { gestureHandlerRootHOC } from 'react-native-gesture-handler';
|
||||
import equal from 'deep-equal';
|
||||
|
||||
import { registerSubmit as registerSubmitAction } from '../actions/login';
|
||||
import TextInput from '../containers/TextInput';
|
||||
import Button from '../containers/Button';
|
||||
import KeyboardView from '../presentation/KeyboardView';
|
||||
|
@ -19,16 +17,16 @@ import LoggedView from './View';
|
|||
import I18n from '../i18n';
|
||||
import store from '../lib/createStore';
|
||||
import { DARK_HEADER } from '../constants/headerOptions';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
import { loginRequest as loginRequestAction } from '../actions/login';
|
||||
import isValidEmail from '../utils/isValidEmail';
|
||||
|
||||
let TermsServiceView = null;
|
||||
let PrivacyPolicyView = null;
|
||||
let LegalView = null;
|
||||
|
||||
@connect(state => ({
|
||||
server: state.server.server,
|
||||
login: state.login
|
||||
}), dispatch => ({
|
||||
registerSubmit: params => dispatch(registerSubmitAction(params))
|
||||
@connect(null, dispatch => ({
|
||||
loginRequest: params => dispatch(loginRequestAction(params))
|
||||
}))
|
||||
/** @extends React.Component */
|
||||
export default class RegisterView extends LoggedView {
|
||||
|
@ -48,13 +46,7 @@ export default class RegisterView extends LoggedView {
|
|||
|
||||
static propTypes = {
|
||||
componentId: PropTypes.string,
|
||||
server: PropTypes.string,
|
||||
registerSubmit: PropTypes.func.isRequired,
|
||||
Accounts_UsernamePlaceholder: PropTypes.string,
|
||||
Accounts_NamePlaceholder: PropTypes.string,
|
||||
Accounts_EmailOrUsernamePlaceholder: PropTypes.string,
|
||||
Accounts_PasswordPlaceholder: PropTypes.string,
|
||||
login: PropTypes.object
|
||||
loginRequest: PropTypes.func
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
|
@ -63,7 +55,8 @@ export default class RegisterView extends LoggedView {
|
|||
name: '',
|
||||
email: '',
|
||||
password: '',
|
||||
username: ''
|
||||
username: '',
|
||||
saving: false
|
||||
};
|
||||
Navigation.events().bindComponent(this);
|
||||
}
|
||||
|
@ -75,10 +68,8 @@ export default class RegisterView extends LoggedView {
|
|||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const { login, componentId, Site_Name } = this.props;
|
||||
if (login && login.failure && login.error && !equal(login.error, prevProps.login.error)) {
|
||||
Alert.alert(I18n.t('Oops'), login.error.reason);
|
||||
} else if (Site_Name && prevProps.Site_Name !== Site_Name) {
|
||||
const { componentId, Site_Name } = this.props;
|
||||
if (Site_Name && prevProps.Site_Name !== Site_Name) {
|
||||
this.setTitle(componentId, Site_Name);
|
||||
}
|
||||
}
|
||||
|
@ -122,26 +113,30 @@ export default class RegisterView extends LoggedView {
|
|||
const {
|
||||
name, email, password, username
|
||||
} = this.state;
|
||||
return name.trim() && email.trim() && password.trim() && username.trim();
|
||||
return name.trim() && email.trim() && password.trim() && username.trim() && isValidEmail(email);
|
||||
}
|
||||
|
||||
invalidEmail = () => {
|
||||
const { login } = this.props;
|
||||
return login.failure && /Email/.test(login.error && login.error.reason) ? login.error : {};
|
||||
}
|
||||
|
||||
submit = () => {
|
||||
submit = async() => {
|
||||
if (!this.valid()) {
|
||||
return;
|
||||
}
|
||||
this.setState({ saving: true });
|
||||
Keyboard.dismiss();
|
||||
|
||||
const {
|
||||
name, email, password, username
|
||||
} = this.state;
|
||||
const { registerSubmit } = this.props;
|
||||
registerSubmit({
|
||||
name, email, pass: password, username
|
||||
});
|
||||
Keyboard.dismiss();
|
||||
const { loginRequest } = this.props;
|
||||
|
||||
try {
|
||||
await RocketChat.register({
|
||||
name, email, pass: password, username
|
||||
});
|
||||
await loginRequest({ user: email, password });
|
||||
} catch (e) {
|
||||
Alert.alert(I18n.t('Oops'), e.data.error);
|
||||
}
|
||||
this.setState({ saving: false });
|
||||
}
|
||||
|
||||
termsService = () => {
|
||||
|
@ -187,7 +182,7 @@ export default class RegisterView extends LoggedView {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { login } = this.props;
|
||||
const { saving } = this.state;
|
||||
return (
|
||||
<KeyboardView contentContainerStyle={sharedStyles.container}>
|
||||
<ScrollView {...scrollPersistTaps} contentContainerStyle={sharedStyles.containerScrollView}>
|
||||
|
@ -219,7 +214,6 @@ export default class RegisterView extends LoggedView {
|
|||
iconLeft='mail'
|
||||
onChangeText={email => this.setState({ email })}
|
||||
onSubmitEditing={() => { this.passwordInput.focus(); }}
|
||||
error={this.invalidEmail()}
|
||||
testID='register-view-email'
|
||||
/>
|
||||
<TextInput
|
||||
|
@ -240,7 +234,7 @@ export default class RegisterView extends LoggedView {
|
|||
onPress={this.submit}
|
||||
testID='register-view-submit'
|
||||
disabled={!this.valid()}
|
||||
loading={login.isFetching}
|
||||
loading={saving}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
</ScrollView>
|
||||
|
|
|
@ -35,7 +35,7 @@ const modules = {};
|
|||
username: state.login.user && state.login.user.username,
|
||||
baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
|
||||
}), dispatch => ({
|
||||
leaveRoom: rid => dispatch(leaveRoomAction(rid))
|
||||
leaveRoom: (rid, t) => dispatch(leaveRoomAction(rid, t))
|
||||
}))
|
||||
/** @extends React.Component */
|
||||
export default class RoomActionsView extends LoggedView {
|
||||
|
@ -67,16 +67,26 @@ export default class RoomActionsView extends LoggedView {
|
|||
this.rooms = database.objects('subscriptions').filtered('rid = $0', rid);
|
||||
this.state = {
|
||||
room: this.rooms[0] || {},
|
||||
onlineMembers: [],
|
||||
allMembers: [],
|
||||
membersCount: 0,
|
||||
member: {}
|
||||
};
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const { room } = this.state;
|
||||
if (room && room.t !== 'd' && this.canViewMembers) {
|
||||
const { rid } = this.props;
|
||||
try {
|
||||
const counters = await RocketChat.getRoomCounters(rid, room.t);
|
||||
if (counters.success) {
|
||||
this.setState({ membersCount: counters.members, joined: counters.joined });
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('RoomActionsView -> getRoomCounters -> error', error);
|
||||
}
|
||||
}
|
||||
|
||||
this.rooms.addListener(this.updateRoom);
|
||||
const [members, member] = await Promise.all([this.updateRoomMembers(), this.updateRoomMember()]);
|
||||
this.setState({ ...members, ...member });
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
@ -96,10 +106,6 @@ export default class RoomActionsView extends LoggedView {
|
|||
name: item.route,
|
||||
passProps: item.params
|
||||
}
|
||||
// screen: item.route,
|
||||
// title: item.name,
|
||||
// passProps: item.params,
|
||||
// backButtonTitle: ''
|
||||
});
|
||||
}
|
||||
if (item.event) {
|
||||
|
@ -108,12 +114,10 @@ export default class RoomActionsView extends LoggedView {
|
|||
}
|
||||
|
||||
get canAddUser() {
|
||||
const { allMembers, room } = this.state;
|
||||
const { username } = this.props;
|
||||
const { room, joined } = this.state;
|
||||
const { rid, t } = room;
|
||||
|
||||
// TODO: same test joined
|
||||
const userInRoom = !!allMembers.find(m => m.username === username);
|
||||
const userInRoom = joined;
|
||||
const permissions = RocketChat.hasPermission(['add-user-to-joined-room', 'add-user-to-any-c-room', 'add-user-to-any-p-room'], rid);
|
||||
|
||||
if (userInRoom && permissions['add-user-to-joined-room']) {
|
||||
|
@ -138,11 +142,16 @@ export default class RoomActionsView extends LoggedView {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
return (t === 'c' || t === 'p');
|
||||
|
||||
// This method is executed only in componentDidMount and returns a value
|
||||
// We save the state to read in render
|
||||
const result = (t === 'c' || t === 'p');
|
||||
this.setState({ canViewMembers: result });
|
||||
return result;
|
||||
}
|
||||
|
||||
get sections() {
|
||||
const { onlineMembers, room } = this.state;
|
||||
const { room, membersCount, canViewMembers } = this.state;
|
||||
const {
|
||||
rid, t, blocker, notifications
|
||||
} = room;
|
||||
|
@ -255,15 +264,13 @@ export default class RoomActionsView extends LoggedView {
|
|||
} else if (t === 'c' || t === 'p') {
|
||||
const actions = [];
|
||||
|
||||
if (this.canViewMembers) {
|
||||
if (canViewMembers) {
|
||||
actions.push({
|
||||
icon: 'ios-people',
|
||||
name: I18n.t('Members'),
|
||||
description: (onlineMembers.length === 1
|
||||
? I18n.t('1_online_member')
|
||||
: I18n.t('N_online_members', { n: onlineMembers.length })),
|
||||
description: `${ membersCount } ${ I18n.t('members') }`,
|
||||
route: 'RoomMembersView',
|
||||
params: { rid, members: onlineMembers },
|
||||
params: { rid },
|
||||
testID: 'room-actions-members',
|
||||
require: () => require('../RoomMembersView').default
|
||||
});
|
||||
|
@ -299,47 +306,6 @@ export default class RoomActionsView extends LoggedView {
|
|||
return sections;
|
||||
}
|
||||
|
||||
updateRoomMembers = async() => {
|
||||
const { room } = this.state;
|
||||
const { rid, t } = room;
|
||||
|
||||
if (!this.canViewMembers) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (t === 'c' || t === 'p') {
|
||||
let onlineMembers = [];
|
||||
let allMembers = [];
|
||||
try {
|
||||
const onlineMembersCall = RocketChat.getRoomMembers(rid, false);
|
||||
const allMembersCall = RocketChat.getRoomMembers(rid, true);
|
||||
const [onlineMembersResult, allMembersResult] = await Promise.all([onlineMembersCall, allMembersCall]);
|
||||
onlineMembers = onlineMembersResult.records;
|
||||
allMembers = allMembersResult.records;
|
||||
return { onlineMembers, allMembers };
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateRoomMember = async() => {
|
||||
const { room } = this.state;
|
||||
const { rid, t } = room;
|
||||
const { userId } = this.props;
|
||||
|
||||
if (t !== 'd') {
|
||||
return {};
|
||||
}
|
||||
try {
|
||||
const member = await RocketChat.getRoomMember(rid, userId);
|
||||
return { member };
|
||||
} catch (e) {
|
||||
log('RoomActions updateRoomMember', e);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
updateRoom = () => {
|
||||
this.setState({ room: this.rooms[0] || {} });
|
||||
}
|
||||
|
@ -370,7 +336,7 @@ export default class RoomActionsView extends LoggedView {
|
|||
{
|
||||
text: I18n.t('Yes_action_it', { action: I18n.t('leave') }),
|
||||
style: 'destructive',
|
||||
onPress: () => leaveRoom(room.rid)
|
||||
onPress: () => leaveRoom(room.rid, room.t)
|
||||
}
|
||||
]
|
||||
);
|
||||
|
@ -379,7 +345,10 @@ export default class RoomActionsView extends LoggedView {
|
|||
toggleNotifications = () => {
|
||||
const { room } = this.state;
|
||||
try {
|
||||
RocketChat.saveNotificationSettings(room.rid, 'mobilePushNotifications', room.notifications ? 'default' : 'nothing');
|
||||
const notifications = {
|
||||
mobilePushNotifications: room.notifications ? 'default' : 'nothing'
|
||||
};
|
||||
RocketChat.saveNotificationSettings(room.rid, notifications);
|
||||
} catch (e) {
|
||||
log('toggleNotifications', e);
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ export default class RoomInfoView extends LoggedView {
|
|||
if (room.t === 'd') {
|
||||
try {
|
||||
const roomUser = await RocketChat.getRoomMember(room.rid, userId);
|
||||
this.setState({ roomUser });
|
||||
this.setState({ roomUser: roomUser || {} });
|
||||
const username = room.name;
|
||||
|
||||
const activeUser = activeUsers[roomUser._id];
|
||||
|
|
|
@ -67,12 +67,13 @@ export default class RoomMembersView extends LoggedView {
|
|||
members,
|
||||
membersFiltered: [],
|
||||
userLongPressed: {},
|
||||
room: {}
|
||||
room: this.rooms[0] || {}
|
||||
};
|
||||
Navigation.events().bindComponent(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.fetchMembers();
|
||||
this.rooms.addListener(this.updateRoom);
|
||||
}
|
||||
|
||||
|
@ -91,7 +92,8 @@ export default class RoomMembersView extends LoggedView {
|
|||
rightButtons: [{
|
||||
id: 'toggleOnline',
|
||||
text: allUsers ? I18n.t('Online') : I18n.t('All'),
|
||||
testID: 'room-members-view-toggle-status'
|
||||
testID: 'room-members-view-toggle-status',
|
||||
color: Platform.OS === 'android' ? '#FFF' : undefined
|
||||
}]
|
||||
}
|
||||
});
|
||||
|
@ -121,8 +123,10 @@ export default class RoomMembersView extends LoggedView {
|
|||
if (subscriptions.length) {
|
||||
this.goRoom({ rid: subscriptions[0].rid });
|
||||
} else {
|
||||
const room = await RocketChat.createDirectMessage(item.username);
|
||||
this.goRoom({ rid: room.rid });
|
||||
const result = await RocketChat.createDirectMessage(item.username);
|
||||
if (result.success) {
|
||||
this.goRoom({ rid: result.room._id });
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
log('onPressUser', e);
|
||||
|
@ -151,6 +155,13 @@ export default class RoomMembersView extends LoggedView {
|
|||
}
|
||||
}
|
||||
|
||||
fetchMembers = async(status) => {
|
||||
const { rid } = this.state;
|
||||
const membersResult = await RocketChat.getRoomMembers(rid, status);
|
||||
const members = membersResult.records;
|
||||
this.setState({ allUsers: status, members });
|
||||
}
|
||||
|
||||
updateRoom = async() => {
|
||||
const [room] = this.rooms;
|
||||
await this.setState({ room });
|
||||
|
|
|
@ -32,7 +32,8 @@ export class List extends React.Component {
|
|||
renderFooter: PropTypes.func,
|
||||
renderRow: PropTypes.func,
|
||||
room: PropTypes.string,
|
||||
end: PropTypes.bool
|
||||
end: PropTypes.bool,
|
||||
loadingMore: PropTypes.bool
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
|
@ -49,8 +50,8 @@ export class List extends React.Component {
|
|||
}
|
||||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
const { end } = this.props;
|
||||
return end !== nextProps.end;
|
||||
const { end, loadingMore } = this.props;
|
||||
return end !== nextProps.end || loadingMore !== nextProps.loadingMore;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
|
|
@ -23,7 +23,6 @@ import UploadProgress from './UploadProgress';
|
|||
import styles from './styles';
|
||||
import log from '../../utils/log';
|
||||
import I18n from '../../i18n';
|
||||
import debounce from '../../utils/debounce';
|
||||
import { iconsMap } from '../../Icons';
|
||||
import store from '../../lib/createStore';
|
||||
import ConnectionBadge from '../../containers/ConnectionBadge';
|
||||
|
@ -39,7 +38,8 @@ let RoomActionsView = null;
|
|||
},
|
||||
actionMessage: state.messages.actionMessage,
|
||||
showActions: state.messages.showActions,
|
||||
showErrorActions: state.messages.showErrorActions
|
||||
showErrorActions: state.messages.showErrorActions,
|
||||
appState: state.app.ready && state.app.foreground ? 'foreground' : 'background'
|
||||
}), dispatch => ({
|
||||
openRoom: room => dispatch(openRoomAction(room)),
|
||||
setLastOpen: date => dispatch(setLastOpenAction(date)),
|
||||
|
@ -87,6 +87,7 @@ export default class RoomView extends LoggedView {
|
|||
showActions: PropTypes.bool,
|
||||
showErrorActions: PropTypes.bool,
|
||||
actionMessage: PropTypes.object,
|
||||
appState: PropTypes.string,
|
||||
toggleReactionPicker: PropTypes.func.isRequired,
|
||||
actionsShow: PropTypes.func,
|
||||
closeRoom: PropTypes.func
|
||||
|
@ -100,23 +101,33 @@ export default class RoomView extends LoggedView {
|
|||
loaded: false,
|
||||
joined: this.rooms.length > 0,
|
||||
room: {},
|
||||
end: false
|
||||
end: false,
|
||||
loadingMore: false
|
||||
};
|
||||
this.onReactionPress = this.onReactionPress.bind(this);
|
||||
Navigation.events().bindComponent(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.updateRoom();
|
||||
async componentDidMount() {
|
||||
if (this.rooms.length === 0 && this.rid) {
|
||||
const result = await RocketChat.getRoomInfo(this.rid);
|
||||
if (result.success) {
|
||||
const { room } = result;
|
||||
this.setState(
|
||||
{ room: { rid: room._id, t: room.t, name: room.name } },
|
||||
() => this.updateRoom()
|
||||
);
|
||||
}
|
||||
}
|
||||
this.rooms.addListener(this.updateRoom);
|
||||
this.internalSetState({ loaded: true });
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
const {
|
||||
room, loaded, joined, end
|
||||
room, loaded, joined, end, loadingMore
|
||||
} = this.state;
|
||||
const { showActions, showErrorActions } = this.props;
|
||||
const { showActions, showErrorActions, appState } = this.props;
|
||||
|
||||
if (room.ro !== nextState.room.ro) {
|
||||
return true;
|
||||
|
@ -128,17 +139,21 @@ export default class RoomView extends LoggedView {
|
|||
return true;
|
||||
} else if (end !== nextState.end) {
|
||||
return true;
|
||||
} else if (loadingMore !== nextState.loadingMore) {
|
||||
return true;
|
||||
} else if (showActions !== nextProps.showActions) {
|
||||
return true;
|
||||
} else if (showErrorActions !== nextProps.showErrorActions) {
|
||||
return true;
|
||||
} else if (appState !== nextProps.appState) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
const { room } = this.state;
|
||||
const { componentId } = this.props;
|
||||
const { componentId, appState } = this.props;
|
||||
|
||||
if (prevState.room.f !== room.f) {
|
||||
Navigation.mergeOptions(componentId, {
|
||||
|
@ -154,32 +169,41 @@ export default class RoomView extends LoggedView {
|
|||
}]
|
||||
}
|
||||
});
|
||||
} else if (appState === 'foreground' && appState !== prevProps.appState) {
|
||||
RocketChat.loadMissedMessages(room).catch(e => console.log(e));
|
||||
RocketChat.readMessages(room.rid).catch(e => console.log(e));
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
const { closeRoom } = this.props;
|
||||
this.rooms.removeAllListeners();
|
||||
this.onEndReached.stop();
|
||||
if (this.onEndReached && this.onEndReached.stop) {
|
||||
this.onEndReached.stop();
|
||||
}
|
||||
closeRoom();
|
||||
}
|
||||
|
||||
onEndReached = debounce((lastRowData) => {
|
||||
onEndReached = async(lastRowData) => {
|
||||
if (!lastRowData) {
|
||||
this.internalSetState({ end: true });
|
||||
return;
|
||||
}
|
||||
|
||||
requestAnimationFrame(async() => {
|
||||
const { room } = this.state;
|
||||
try {
|
||||
const result = await RocketChat.loadMessagesForRoom({ rid: this.rid, t: room.t, latest: lastRowData.ts });
|
||||
this.internalSetState({ end: result < 50 });
|
||||
} catch (e) {
|
||||
log('RoomView.onEndReached', e);
|
||||
}
|
||||
});
|
||||
})
|
||||
const { loadingMore, end } = this.state;
|
||||
if (loadingMore || end) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({ loadingMore: true });
|
||||
const { room } = this.state;
|
||||
try {
|
||||
const result = await RocketChat.loadMessagesForRoom({ rid: this.rid, t: room.t, latest: lastRowData.ts });
|
||||
this.internalSetState({ end: result.length < 50, loadingMore: false });
|
||||
} catch (e) {
|
||||
this.internalSetState({ loadingMore: false });
|
||||
log('RoomView.onEndReached', e);
|
||||
}
|
||||
}
|
||||
|
||||
onMessageLongPress = (message) => {
|
||||
const { actionsShow } = this.props;
|
||||
|
@ -228,7 +252,7 @@ export default class RoomView extends LoggedView {
|
|||
});
|
||||
} else if (buttonId === 'star') {
|
||||
try {
|
||||
RocketChat.toggleFavorite(rid, f);
|
||||
RocketChat.toggleFavorite(rid, !f);
|
||||
} catch (e) {
|
||||
log('toggleFavorite', e);
|
||||
}
|
||||
|
@ -254,7 +278,8 @@ export default class RoomView extends LoggedView {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
openRoom({ rid: this.rid });
|
||||
const { room } = this.state;
|
||||
openRoom(room);
|
||||
this.internalSetState({ joined: false });
|
||||
}
|
||||
}
|
||||
|
@ -270,10 +295,12 @@ export default class RoomView extends LoggedView {
|
|||
joinRoom = async() => {
|
||||
const { rid } = this.props;
|
||||
try {
|
||||
await RocketChat.joinRoom(rid);
|
||||
this.internalSetState({
|
||||
joined: true
|
||||
});
|
||||
const result = await RocketChat.joinRoom(rid);
|
||||
if (result.success) {
|
||||
this.internalSetState({
|
||||
joined: true
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
log('joinRoom', e);
|
||||
}
|
||||
|
@ -364,15 +391,15 @@ export default class RoomView extends LoggedView {
|
|||
};
|
||||
|
||||
renderHeader = () => {
|
||||
const { end } = this.state;
|
||||
if (!end) {
|
||||
return <ActivityIndicator style={[styles.loading, { transform: [{ scaleY: -1 }] }]} />;
|
||||
const { loadingMore } = this.state;
|
||||
if (loadingMore) {
|
||||
return <ActivityIndicator style={styles.loadingMore} />;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
renderList = () => {
|
||||
const { loaded, end } = this.state;
|
||||
const { loaded, end, loadingMore } = this.state;
|
||||
if (!loaded) {
|
||||
return <ActivityIndicator style={styles.loading} />;
|
||||
}
|
||||
|
@ -381,6 +408,7 @@ export default class RoomView extends LoggedView {
|
|||
<List
|
||||
key='room-view-messages'
|
||||
end={end}
|
||||
loadingMore={loadingMore}
|
||||
room={this.rid}
|
||||
renderFooter={this.renderHeader}
|
||||
onEndReached={this.onEndReached}
|
||||
|
|
|
@ -66,7 +66,8 @@ let NewMessageView = null;
|
|||
groupByType: state.sortPreferences.groupByType,
|
||||
showFavorites: state.sortPreferences.showFavorites,
|
||||
showUnread: state.sortPreferences.showUnread,
|
||||
useRealName: state.settings.UI_Use_Real_Name
|
||||
useRealName: state.settings.UI_Use_Real_Name,
|
||||
appState: state.app.ready && state.app.foreground ? 'foreground' : 'background'
|
||||
}), dispatch => ({
|
||||
toggleSortDropdown: () => dispatch(toggleSortDropdownAction()),
|
||||
openSearchHeader: () => dispatch(openSearchHeaderAction()),
|
||||
|
@ -114,6 +115,7 @@ export default class RoomsListView extends LoggedView {
|
|||
showFavorites: PropTypes.bool,
|
||||
showUnread: PropTypes.bool,
|
||||
useRealName: PropTypes.bool,
|
||||
appState: PropTypes.string,
|
||||
toggleSortDropdown: PropTypes.func,
|
||||
openSearchHeader: PropTypes.func,
|
||||
closeSearchHeader: PropTypes.func,
|
||||
|
@ -164,7 +166,7 @@ export default class RoomsListView extends LoggedView {
|
|||
|
||||
componentDidUpdate(prevProps) {
|
||||
const {
|
||||
sortBy, groupByType, showFavorites, showUnread
|
||||
sortBy, groupByType, showFavorites, showUnread, appState
|
||||
} = this.props;
|
||||
|
||||
if (!(
|
||||
|
@ -174,6 +176,8 @@ export default class RoomsListView extends LoggedView {
|
|||
&& (prevProps.showUnread === showUnread)
|
||||
)) {
|
||||
this.getSubscriptions();
|
||||
} else if (appState === 'foreground' && appState !== prevProps.appState) {
|
||||
RocketChat.getRooms().catch(e => console.log(e));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,9 +420,10 @@ export default class RoomsListView extends LoggedView {
|
|||
// if user is using the search we need first to join/create room
|
||||
try {
|
||||
const { username } = item;
|
||||
const sub = await RocketChat.createDirectMessage(username);
|
||||
const { rid } = sub;
|
||||
return this.goRoom(rid);
|
||||
const result = await RocketChat.createDirectMessage(username);
|
||||
if (result.success) {
|
||||
return this.goRoom(result.room._id);
|
||||
}
|
||||
} catch (e) {
|
||||
log('RoomsListView._onPressItem', e);
|
||||
}
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Text, ScrollView, Alert, StyleSheet
|
||||
Text, ScrollView, StyleSheet
|
||||
} from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import SafeAreaView from 'react-native-safe-area-view';
|
||||
import equal from 'deep-equal';
|
||||
import { Navigation } from 'react-native-navigation';
|
||||
|
||||
import { setUsernameSubmit as setUsernameSubmitAction } from '../actions/login';
|
||||
import { loginRequest as loginRequestAction } from '../actions/login';
|
||||
import TextInput from '../containers/TextInput';
|
||||
import Button from '../containers/Button';
|
||||
import KeyboardView from '../presentation/KeyboardView';
|
||||
|
@ -28,9 +27,9 @@ const styles = StyleSheet.create({
|
|||
|
||||
@connect(state => ({
|
||||
server: state.server.server,
|
||||
login: state.login
|
||||
token: state.login.user && state.login.user.token
|
||||
}), dispatch => ({
|
||||
setUsernameSubmit: params => dispatch(setUsernameSubmitAction(params))
|
||||
loginRequest: params => dispatch(loginRequestAction(params))
|
||||
}))
|
||||
/** @extends React.Component */
|
||||
export default class SetUsernameView extends LoggedView {
|
||||
|
@ -43,15 +42,15 @@ export default class SetUsernameView extends LoggedView {
|
|||
static propTypes = {
|
||||
componentId: PropTypes.string,
|
||||
server: PropTypes.string,
|
||||
setUsernameSubmit: PropTypes.func.isRequired,
|
||||
Accounts_UsernamePlaceholder: PropTypes.string,
|
||||
login: PropTypes.object
|
||||
userId: PropTypes.string,
|
||||
loginRequest: PropTypes.func
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super('SetUsernameView', props);
|
||||
this.state = {
|
||||
username: ''
|
||||
username: '',
|
||||
saving: false
|
||||
};
|
||||
const { componentId, server } = this.props;
|
||||
Navigation.mergeOptions(componentId, {
|
||||
|
@ -68,13 +67,8 @@ export default class SetUsernameView extends LoggedView {
|
|||
this.usernameInput.focus();
|
||||
}, 600);
|
||||
const suggestion = await RocketChat.getUsernameSuggestion();
|
||||
this.setState({ username: suggestion });
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const { login } = this.props;
|
||||
if (login && login.failure && login.error && !equal(login.error, prevProps.login.error)) {
|
||||
Alert.alert(I18n.t('Oops'), login.error.reason);
|
||||
if (suggestion.success) {
|
||||
this.setState({ username: suggestion.result });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,15 +78,27 @@ export default class SetUsernameView extends LoggedView {
|
|||
}
|
||||
}
|
||||
|
||||
submit = () => {
|
||||
submit = async() => {
|
||||
const { username } = this.state;
|
||||
const { setUsernameSubmit } = this.props;
|
||||
setUsernameSubmit({ username });
|
||||
const { loginRequest, token } = this.props;
|
||||
|
||||
if (!username.trim()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({ saving: true });
|
||||
try {
|
||||
await RocketChat.setUsername(username);
|
||||
RocketChat.setApiUser({ userId: null, authToken: null });
|
||||
await loginRequest({ resume: token });
|
||||
} catch (e) {
|
||||
console.log('SetUsernameView -> catch -> e', e);
|
||||
}
|
||||
this.setState({ saving: false });
|
||||
}
|
||||
|
||||
render() {
|
||||
const { username } = this.state;
|
||||
const { login } = this.props;
|
||||
const { username, saving } = this.state;
|
||||
return (
|
||||
<KeyboardView contentContainerStyle={sharedStyles.container}>
|
||||
<ScrollView {...scrollPersistTaps} contentContainerStyle={sharedStyles.containerScrollView}>
|
||||
|
@ -117,7 +123,7 @@ export default class SetUsernameView extends LoggedView {
|
|||
onPress={this.submit}
|
||||
testID='set-username-view-submit'
|
||||
disabled={!username}
|
||||
loading={login.isFetching}
|
||||
loading={saving}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
</ScrollView>
|
||||
|
|
|
@ -32,7 +32,7 @@ describe('Forgot password screen', () => {
|
|||
|
||||
describe('Usage', async() => {
|
||||
it('should reset password and navigate to login', async() => {
|
||||
await element(by.id('forgot-password-view-email')).replaceText(data.email);
|
||||
await element(by.id('forgot-password-view-email')).replaceText('diego.mello@rocket.chat');
|
||||
await element(by.id('forgot-password-view-submit')).tap();
|
||||
await waitFor(element(by.id('login-view'))).toBeVisible().withTimeout(60000);
|
||||
await expect(element(by.id('login-view'))).toBeVisible();
|
||||
|
|
|
@ -58,17 +58,15 @@ describe('Create user screen', () => {
|
|||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
it('should submit invalid email and raise error', async() => {
|
||||
const invalidEmail = 'invalidemail';
|
||||
await element(by.id('register-view-name')).replaceText(data.user);
|
||||
await element(by.id('register-view-username')).replaceText(data.user);
|
||||
await element(by.id('register-view-email')).replaceText(invalidEmail);
|
||||
await element(by.id('register-view-password')).replaceText(data.password);
|
||||
await element(by.id('register-view-submit')).tap();
|
||||
await waitFor(element(by.text(`Invalid email ${ invalidEmail }`)).atIndex(0)).toExist().withTimeout(10000);
|
||||
await expect(element(by.text(`Invalid email ${ invalidEmail }`)).atIndex(0)).toExist();
|
||||
await element(by.text('OK')).tap();
|
||||
});
|
||||
// FIXME: Detox isn't able to check if it's tappable: https://github.com/wix/Detox/issues/246
|
||||
// it.only('should submit invalid email and do nothing', async() => {
|
||||
// const invalidEmail = 'invalidemail';
|
||||
// await element(by.id('register-view-name')).replaceText(data.user);
|
||||
// await element(by.id('register-view-username')).replaceText(data.user);
|
||||
// await element(by.id('register-view-email')).replaceText(invalidEmail);
|
||||
// await element(by.id('register-view-password')).replaceText(data.password);
|
||||
// await element(by.id('register-view-submit')).tap();
|
||||
// });
|
||||
|
||||
it('should submit email already taken and raise error', async() => {
|
||||
const invalidEmail = 'invalidemail';
|
||||
|
@ -77,8 +75,20 @@ describe('Create user screen', () => {
|
|||
await element(by.id('register-view-email')).replaceText('diego.mello@rocket.chat');
|
||||
await element(by.id('register-view-password')).replaceText(data.password);
|
||||
await element(by.id('register-view-submit')).tap();
|
||||
await waitFor(element(by.text('Email already exists.')).atIndex(0)).toExist().withTimeout(10000);
|
||||
await expect(element(by.text('Email already exists.')).atIndex(0)).toExist();
|
||||
await waitFor(element(by.text('Email already exists. [403]')).atIndex(0)).toExist().withTimeout(10000);
|
||||
await expect(element(by.text('Email already exists. [403]')).atIndex(0)).toExist();
|
||||
await element(by.text('OK')).tap();
|
||||
});
|
||||
|
||||
it('should submit email already taken and raise error', async() => {
|
||||
const invalidEmail = 'invalidemail';
|
||||
await element(by.id('register-view-name')).replaceText(data.user);
|
||||
await element(by.id('register-view-username')).replaceText('diego.mello');
|
||||
await element(by.id('register-view-email')).replaceText(data.email);
|
||||
await element(by.id('register-view-password')).replaceText(data.password);
|
||||
await element(by.id('register-view-submit')).tap();
|
||||
await waitFor(element(by.text('Username is already in use')).atIndex(0)).toExist().withTimeout(10000);
|
||||
await expect(element(by.text('Username is already in use')).atIndex(0)).toExist();
|
||||
await element(by.text('OK')).tap();
|
||||
});
|
||||
|
||||
|
@ -92,21 +102,6 @@ describe('Create user screen', () => {
|
|||
await expect(element(by.id('rooms-list-view'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should pick an existing username, suggest another and finish register', async() => {
|
||||
await logout();
|
||||
await navigateToRegister();
|
||||
await element(by.id('register-view-name')).replaceText(data.user);
|
||||
await element(by.id('register-view-username')).replaceText(data.user);
|
||||
await element(by.id('register-view-email')).replaceText(`${ data.email }2`);
|
||||
await element(by.id('register-view-password')).replaceText(data.password);
|
||||
await element(by.id('register-view-submit')).tap();
|
||||
await waitFor(element(by.id('set-username-view'))).toBeVisible().withTimeout(60000);
|
||||
await expect(element(by.id('set-username-view'))).toBeVisible();
|
||||
await element(by.id('set-username-view-submit')).tap();
|
||||
await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(60000);
|
||||
await expect(element(by.id('rooms-list-view'))).toBeVisible();
|
||||
});
|
||||
|
||||
afterEach(async() => {
|
||||
takeScreenshot();
|
||||
});
|
||||
|
|
|
@ -2149,8 +2149,8 @@
|
|||
"integrity": "sha512-iOD1PRnTSVr9sDWQdesIpfRrwJhHfeEQe5BpalQxC5OhM9thpiE6cu2NlW1KBWl0RJG4ZiJaF1xLlCo9YxU6dA=="
|
||||
},
|
||||
"@rocket.chat/sdk": {
|
||||
"version": "git+https://github.com/RocketChat/Rocket.Chat.js.SDK.git#86d0b0f544ea700f742a66f59a21e1679aa7ff50",
|
||||
"from": "git+https://github.com/RocketChat/Rocket.Chat.js.SDK.git#ddp",
|
||||
"version": "git+https://github.com/RocketChat/Rocket.Chat.js.SDK.git#3257e342690eb103f3ea5eec918fb73670ddb6a8",
|
||||
"from": "git+https://github.com/RocketChat/Rocket.Chat.js.SDK.git#temp-ddp",
|
||||
"requires": {
|
||||
"@types/lru-cache": "^4.1.0",
|
||||
"@types/node": "^9.4.6",
|
||||
|
@ -2573,9 +2573,9 @@
|
|||
"integrity": "sha512-FWR7QB7EqBRq1s9BMk0ccOSOuRLfVEWYpHQYpFPaXtCoqN6dJx2ttdsdQbUxLLnAlKpYeVjveGGhQ3583TTa7g=="
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "9.6.36",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.36.tgz",
|
||||
"integrity": "sha512-Fbw+AdRLL01vv7Rk7bYaNPecqmKoinJHGbpKnDpbUZmUj/0vj3nLqPQ4CNBzr3q2zso6Cq/4jHoCAdH78fvJrw=="
|
||||
"version": "9.6.40",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.40.tgz",
|
||||
"integrity": "sha512-M3HHoXXndsho/sTbQML2BJr7/uwNhMg8P0D4lb+UsM65JQZx268faiz9hKpY4FpocWqpwlLwa8vevw8hLtKjOw=="
|
||||
},
|
||||
"@types/react": {
|
||||
"version": "16.4.6",
|
||||
|
@ -4642,6 +4642,7 @@
|
|||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
|
||||
"integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"core-js": "^2.4.0",
|
||||
"regenerator-runtime": "^0.11.0"
|
||||
|
@ -4650,7 +4651,8 @@
|
|||
"regenerator-runtime": {
|
||||
"version": "0.11.1",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
|
||||
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
|
||||
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -6664,11 +6666,6 @@
|
|||
"randomfill": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"crypto-js": {
|
||||
"version": "3.1.8",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.8.tgz",
|
||||
"integrity": "sha1-cV8HC/YBTyrpkqmLOSkli3E/CNU="
|
||||
},
|
||||
"crypto-random-string": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
|
||||
|
@ -8246,11 +8243,6 @@
|
|||
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-1.1.1.tgz",
|
||||
"integrity": "sha1-qG5e5r2qFgVEddp5fM3fDFVphJE="
|
||||
},
|
||||
"eventemitter3": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz",
|
||||
"integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg="
|
||||
},
|
||||
"events": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz",
|
||||
|
@ -8813,9 +8805,9 @@
|
|||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.5.9",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.9.tgz",
|
||||
"integrity": "sha512-Bh65EZI/RU8nx0wbYF9shkFZlqLP+6WT/5FnA3cE/djNSuKNHJEinGGZgu/cQEkeeb2GdFOgenAmn8qaqYke2w==",
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
||||
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
||||
"requires": {
|
||||
"debug": "=3.1.0"
|
||||
},
|
||||
|
@ -10427,7 +10419,8 @@
|
|||
"hoist-non-react-statics": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz",
|
||||
"integrity": "sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs="
|
||||
"integrity": "sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs=",
|
||||
"dev": true
|
||||
},
|
||||
"home-or-tmp": {
|
||||
"version": "2.0.0",
|
||||
|
@ -14127,7 +14120,8 @@
|
|||
"lodash._getnative": {
|
||||
"version": "3.9.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
|
||||
"integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U="
|
||||
"integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.assign": {
|
||||
"version": "4.2.0",
|
||||
|
@ -14174,12 +14168,14 @@
|
|||
"lodash.isarguments": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
|
||||
"integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo="
|
||||
"integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.isarray": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
|
||||
"integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U="
|
||||
"integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
|
@ -14196,6 +14192,7 @@
|
|||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
|
||||
"integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash._getnative": "^3.0.0",
|
||||
"lodash.isarguments": "^3.0.0",
|
||||
|
@ -14958,23 +14955,6 @@
|
|||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
|
||||
},
|
||||
"minimongo-cache": {
|
||||
"version": "0.0.48",
|
||||
"resolved": "https://registry.npmjs.org/minimongo-cache/-/minimongo-cache-0.0.48.tgz",
|
||||
"integrity": "sha1-pvu3i2YnVUJJr+78EkPPfLpr6gc=",
|
||||
"requires": {
|
||||
"eventemitter3": "^1.1.0",
|
||||
"invariant": "^2.1.1",
|
||||
"lodash": "~2.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
|
||||
"integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4="
|
||||
}
|
||||
}
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.3.5",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
|
||||
|
@ -15078,11 +15058,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"mobx": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/mobx/-/mobx-2.7.0.tgz",
|
||||
"integrity": "sha1-zz2C0YwMp/RY2PKiQIF7PcflSgE="
|
||||
},
|
||||
"mocha": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz",
|
||||
|
@ -17690,21 +17665,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"raf": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/raf/-/raf-3.1.0.tgz",
|
||||
"integrity": "sha1-XYS/gbV/l5+MSSvgg3jFOLtO7Pw=",
|
||||
"requires": {
|
||||
"performance-now": "~0.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"performance-now": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
|
||||
"integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU="
|
||||
}
|
||||
}
|
||||
},
|
||||
"ramda": {
|
||||
"version": "0.24.1",
|
||||
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.24.1.tgz",
|
||||
|
@ -17970,32 +17930,11 @@
|
|||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.6.3.tgz",
|
||||
"integrity": "sha512-u7FDWtthB4rWibG/+mFbVd5FvdI20yde86qKGx4lVUTWmPlSWQ4QxbBIrrs+HnXGbxOUlUzTAP/VDmvCwaP2yA=="
|
||||
},
|
||||
"react-komposer": {
|
||||
"version": "1.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-komposer/-/react-komposer-1.13.1.tgz",
|
||||
"integrity": "sha1-S4rEvMcTI710E9yrlcgxGX9Q7tA=",
|
||||
"requires": {
|
||||
"babel-runtime": "6.x.x",
|
||||
"hoist-non-react-statics": "1.x.x",
|
||||
"invariant": "2.x.x",
|
||||
"mobx": "^2.3.4",
|
||||
"shallowequal": "0.2.x"
|
||||
}
|
||||
},
|
||||
"react-lifecycles-compat": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
|
||||
},
|
||||
"react-mixin": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-mixin/-/react-mixin-3.1.1.tgz",
|
||||
"integrity": "sha512-z9fZ0aCRDjlgxLdMeWkJ9TwhmVLhQ09r8RFpin/cEPA2T6jsb7YHNWcIe0Oii+hhJNyMymdy91CSya5mRkuCkg==",
|
||||
"requires": {
|
||||
"object-assign": "^4.0.1",
|
||||
"smart-mixin": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"react-modal": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.5.1.tgz",
|
||||
|
@ -18239,9 +18178,9 @@
|
|||
"from": "github:corymsmith/react-native-fabric#523a4edab3b2bf55ea9eeea2cf0dde82c5c29dd4"
|
||||
},
|
||||
"react-native-fast-image": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-fast-image/-/react-native-fast-image-5.1.1.tgz",
|
||||
"integrity": "sha512-kEzgZxbbXYhy27u5GnhrKitn+XDBFAHSDUJdYC6llMi5cDPjgcqhOAQABj0K+ga5pn+/xPZLmD882rrUGiwVVA=="
|
||||
"version": "5.0.11",
|
||||
"resolved": "https://registry.npmjs.org/react-native-fast-image/-/react-native-fast-image-5.0.11.tgz",
|
||||
"integrity": "sha512-5NNQwRniOfSBAvKldyPEs1xotWxrFcplOSQiVc78dv/EhH4G0IpdrLtsQmBdB91EMtPQfvoT269sKqj5MJCgyA=="
|
||||
},
|
||||
"react-native-fit-image": {
|
||||
"version": "1.5.4",
|
||||
|
@ -18277,9 +18216,8 @@
|
|||
}
|
||||
},
|
||||
"react-native-image-crop-picker": {
|
||||
"version": "0.21.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-image-crop-picker/-/react-native-image-crop-picker-0.21.3.tgz",
|
||||
"integrity": "sha512-qzY8aSYZxH4L9XYRk4V1n8x1gfq+ykNG0Kc0a9ne+JWwAQkf2P8aTKeNd4noNFZEOSJBiD4XXE/pbX55dQ5F3g=="
|
||||
"version": "git+https://github.com/RocketChat/react-native-image-crop-picker.git#6c205596b5496b207daa93408c9cef886e04bdbb",
|
||||
"from": "git+https://github.com/RocketChat/react-native-image-crop-picker.git"
|
||||
},
|
||||
"react-native-image-pan-zoom": {
|
||||
"version": "2.1.11",
|
||||
|
@ -18334,23 +18272,6 @@
|
|||
"react-native-fit-image": "^1.5.2"
|
||||
}
|
||||
},
|
||||
"react-native-meteor": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-meteor/-/react-native-meteor-1.4.0.tgz",
|
||||
"integrity": "sha512-Bm5RGTDv7LsJqqWjaR8KCv2mpeeMMPOIeZWHSx1yeTLUnEx71jVWAbHNXmEEynyH61/NVUpwDaXZKxiw9OwhFA==",
|
||||
"requires": {
|
||||
"base-64": "^0.1.0",
|
||||
"crypto-js": "^3.1.6",
|
||||
"ejson": "^2.1.2",
|
||||
"minimongo-cache": "0.0.48",
|
||||
"prop-types": "^15.5.10",
|
||||
"react-komposer": "^1.8.0",
|
||||
"react-mixin": "^3.0.3",
|
||||
"trackr": "^2.0.2",
|
||||
"underscore": "^1.8.3",
|
||||
"wolfy87-eventemitter": "^4.3.0"
|
||||
}
|
||||
},
|
||||
"react-native-modal": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-modal/-/react-native-modal-7.0.0.tgz",
|
||||
|
@ -20180,6 +20101,7 @@
|
|||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-0.2.2.tgz",
|
||||
"integrity": "sha1-HjL9W8q2rWiKSBLLDMBO/HXHAU4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash.keys": "^3.1.2"
|
||||
}
|
||||
|
@ -20301,11 +20223,6 @@
|
|||
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz",
|
||||
"integrity": "sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY="
|
||||
},
|
||||
"smart-mixin": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/smart-mixin/-/smart-mixin-2.0.0.tgz",
|
||||
"integrity": "sha1-o0oQVeMqdbMNK048oyPcmctT9Dc="
|
||||
},
|
||||
"snapdragon": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
||||
|
@ -21812,14 +21729,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"trackr": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/trackr/-/trackr-2.0.2.tgz",
|
||||
"integrity": "sha1-7jixO1gLMN9ejgJw0c89AhLEdF4=",
|
||||
"requires": {
|
||||
"raf": "~3.1.0"
|
||||
}
|
||||
},
|
||||
"trim-right": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
|
||||
|
@ -22767,11 +22676,6 @@
|
|||
"integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
|
||||
"dev": true
|
||||
},
|
||||
"wolfy87-eventemitter": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/wolfy87-eventemitter/-/wolfy87-eventemitter-4.3.0.tgz",
|
||||
"integrity": "sha1-ZJc5bJXnQ1nwa241QJM5MY2Nlk8="
|
||||
},
|
||||
"wordwrap": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@remobile/react-native-toast": "^1.0.7",
|
||||
"@rocket.chat/sdk": "git+https://github.com/RocketChat/Rocket.Chat.js.SDK.git#ddp",
|
||||
"@rocket.chat/sdk": "git+https://github.com/RocketChat/Rocket.Chat.js.SDK.git#temp-ddp",
|
||||
"deep-equal": "^1.0.1",
|
||||
"ejson": "^2.1.2",
|
||||
"js-base64": "^2.4.9",
|
||||
|
@ -41,16 +41,15 @@
|
|||
"react-native-device-info": "^0.24.3",
|
||||
"react-native-dialog": "^5.4.0",
|
||||
"react-native-fabric": "github:corymsmith/react-native-fabric#523a4edab3b2bf55ea9eeea2cf0dde82c5c29dd4",
|
||||
"react-native-fast-image": "^5.1.1",
|
||||
"react-native-fast-image": "^5.0.11",
|
||||
"react-native-gesture-handler": "^1.0.9",
|
||||
"react-native-i18n": "^2.0.15",
|
||||
"react-native-image-crop-picker": "0.21.3",
|
||||
"react-native-image-crop-picker": "git+https://github.com/RocketChat/react-native-image-crop-picker.git",
|
||||
"react-native-image-zoom-viewer": "^2.2.23",
|
||||
"react-native-keyboard-aware-scroll-view": "^0.7.4",
|
||||
"react-native-keyboard-input": "^5.3.1",
|
||||
"react-native-keyboard-tracking-view": "^5.5.0",
|
||||
"react-native-markdown-renderer": "^3.2.8",
|
||||
"react-native-meteor": "^1.4.0",
|
||||
"react-native-modal": "^7.0.0",
|
||||
"react-native-navigation": "^2.1.3",
|
||||
"react-native-notifications": "^1.1.21",
|
||||
|
|
Loading…
Reference in New Issue