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