[FIX] Remove nested room navigation (#4702)
* reset from room to room * jump from room to room it's fine * threads ipad * fix ts roomslistview * remove params * fix the ipad highlight * jump to a message from a thread to main room * the reset within the goRoom * create channel * changes in canned response * fix discussion navigation * navigation newmessageview to users * fix go room from room info view * inappnotification, deeplinking, room.js * change from room.rooms to room.subscribed * minor tweak jumptomessage * fix add existing channel to team and fixing test 02 of teams * keep the same behavior after add existing channel * keep the same behavior after add existing channel * clean cosole * changes requested about the name * inapp redux to hooks * added a comment to addexistingchanneltoteam * minor tweak jumptomessage * refactor goRoom to add the param popToRoot, also refactor the navigate in deeplinking too * refactor other places that exist goRoom * fix the didUpdate * added in app notification test * clean js * minor tweak test
This commit is contained in:
parent
82500ca719
commit
9bb1bdb7b8
|
@ -12,7 +12,6 @@ import { themes } from '../../lib/constants';
|
||||||
import { useTheme } from '../../theme';
|
import { useTheme } from '../../theme';
|
||||||
import { ROW_HEIGHT } from '../RoomItem';
|
import { ROW_HEIGHT } from '../RoomItem';
|
||||||
import { goRoom } from '../../lib/methods/helpers/goRoom';
|
import { goRoom } from '../../lib/methods/helpers/goRoom';
|
||||||
import Navigation from '../../lib/navigation/appNavigation';
|
|
||||||
import { useOrientation } from '../../dimensions';
|
import { useOrientation } from '../../dimensions';
|
||||||
import { IApplicationState, ISubscription, SubscriptionType } from '../../definitions';
|
import { IApplicationState, ISubscription, SubscriptionType } from '../../definitions';
|
||||||
|
|
||||||
|
@ -98,12 +97,7 @@ const NotifierComponent = React.memo(({ notification, isMasterDetail }: INotifie
|
||||||
prid
|
prid
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isMasterDetail) {
|
goRoom({ item, isMasterDetail, jumpToMessageId: _id, popToRoot: true });
|
||||||
Navigation.navigate('DrawerNavigator');
|
|
||||||
} else {
|
|
||||||
Navigation.navigate('RoomsListView');
|
|
||||||
}
|
|
||||||
goRoom({ item, isMasterDetail, jumpToMessageId: _id });
|
|
||||||
hideNotification();
|
hideNotification();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -124,6 +118,7 @@ const NotifierComponent = React.memo(({ notification, isMasterDetail }: INotifie
|
||||||
onPress={onPress}
|
onPress={onPress}
|
||||||
hitSlop={BUTTON_HIT_SLOP}
|
hitSlop={BUTTON_HIT_SLOP}
|
||||||
background={Touchable.SelectableBackgroundBorderless()}
|
background={Touchable.SelectableBackgroundBorderless()}
|
||||||
|
testID={`in-app-notification-${text}`}
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
<Avatar text={avatar} size={AVATAR_SIZE} type={type} rid={rid} style={styles.avatar} />
|
<Avatar text={avatar} size={AVATAR_SIZE} type={type} rid={rid} style={styles.avatar} />
|
||||||
|
|
|
@ -1,56 +1,50 @@
|
||||||
import React, { memo, useEffect } from 'react';
|
import React, { memo, useEffect } from 'react';
|
||||||
import { Easing, Notifier, NotifierRoot } from 'react-native-notifier';
|
import { Easing, Notifier, NotifierRoot } from 'react-native-notifier';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { dequal } from 'dequal';
|
|
||||||
|
|
||||||
import NotifierComponent, { INotifierComponent } from './NotifierComponent';
|
import NotifierComponent, { INotifierComponent } from './NotifierComponent';
|
||||||
import EventEmitter from '../../lib/methods/helpers/events';
|
import EventEmitter from '../../lib/methods/helpers/events';
|
||||||
import Navigation from '../../lib/navigation/appNavigation';
|
import Navigation from '../../lib/navigation/appNavigation';
|
||||||
import { getActiveRoute } from '../../lib/methods/helpers/navigation';
|
import { getActiveRoute } from '../../lib/methods/helpers/navigation';
|
||||||
import { IApplicationState } from '../../definitions';
|
import { useAppSelector } from '../../lib/hooks';
|
||||||
import { IRoom } from '../../reducers/room';
|
|
||||||
|
|
||||||
export const INAPP_NOTIFICATION_EMITTER = 'NotificationInApp';
|
export const INAPP_NOTIFICATION_EMITTER = 'NotificationInApp';
|
||||||
|
|
||||||
const InAppNotification = memo(
|
const InAppNotification = memo(() => {
|
||||||
({ rooms, appState }: { rooms: IRoom['rooms']; appState: string }) => {
|
const { appState, subscribedRoom } = useAppSelector(state => ({
|
||||||
const show = (notification: INotifierComponent['notification']) => {
|
subscribedRoom: state.room.subscribedRoom,
|
||||||
if (appState !== 'foreground') {
|
appState: state.app.ready && state.app.foreground ? 'foreground' : 'background'
|
||||||
|
}));
|
||||||
|
|
||||||
|
const show = (notification: INotifierComponent['notification']) => {
|
||||||
|
if (appState !== 'foreground') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { payload } = notification;
|
||||||
|
const state = Navigation.navigationRef.current?.getRootState();
|
||||||
|
const route = getActiveRoute(state);
|
||||||
|
if (payload.rid) {
|
||||||
|
if (payload.rid === subscribedRoom || route?.name === 'JitsiMeetView') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Notifier.showNotification({
|
||||||
const { payload } = notification;
|
showEasing: Easing.inOut(Easing.quad),
|
||||||
const state = Navigation.navigationRef.current?.getRootState();
|
Component: NotifierComponent,
|
||||||
const route = getActiveRoute(state);
|
componentProps: {
|
||||||
if (payload.rid) {
|
notification
|
||||||
if (rooms.includes(payload.rid) || route?.name === 'JitsiMeetView') {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
Notifier.showNotification({
|
});
|
||||||
showEasing: Easing.inOut(Easing.quad),
|
}
|
||||||
Component: NotifierComponent,
|
};
|
||||||
componentProps: {
|
|
||||||
notification
|
useEffect(() => {
|
||||||
}
|
const listener = EventEmitter.addEventListener(INAPP_NOTIFICATION_EMITTER, show);
|
||||||
});
|
return () => {
|
||||||
}
|
EventEmitter.removeListener(INAPP_NOTIFICATION_EMITTER, listener);
|
||||||
};
|
};
|
||||||
|
}, [subscribedRoom, appState]);
|
||||||
|
|
||||||
useEffect(() => {
|
return <NotifierRoot />;
|
||||||
const listener = EventEmitter.addEventListener(INAPP_NOTIFICATION_EMITTER, show);
|
|
||||||
return () => {
|
|
||||||
EventEmitter.removeListener(INAPP_NOTIFICATION_EMITTER, listener);
|
|
||||||
};
|
|
||||||
}, [rooms]);
|
|
||||||
|
|
||||||
return <NotifierRoot />;
|
|
||||||
},
|
|
||||||
(prevProps, nextProps) => dequal(prevProps.rooms, nextProps.rooms)
|
|
||||||
);
|
|
||||||
|
|
||||||
const mapStateToProps = (state: IApplicationState) => ({
|
|
||||||
rooms: state.room.rooms,
|
|
||||||
appState: state.app.ready && state.app.foreground ? 'foreground' : 'background'
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps)(InAppNotification);
|
export default InAppNotification;
|
||||||
|
|
|
@ -237,7 +237,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
const { rid, tmid, navigation, sharing, usedCannedResponse, isMasterDetail } = this.props;
|
const { rid, tmid, navigation, sharing, usedCannedResponse } = this.props;
|
||||||
let msg;
|
let msg;
|
||||||
try {
|
try {
|
||||||
const threadsCollection = db.get('threads');
|
const threadsCollection = db.get('threads');
|
||||||
|
@ -272,7 +272,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
|
||||||
EventEmiter.addEventListener(KEY_COMMAND, this.handleCommands);
|
EventEmiter.addEventListener(KEY_COMMAND, this.handleCommands);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMasterDetail && usedCannedResponse) {
|
if (usedCannedResponse) {
|
||||||
this.onChangeText(usedCannedResponse);
|
this.onChangeText(usedCannedResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { StyleProp, Text, TextStyle } from 'react-native';
|
import { StyleProp, Text, TextStyle } from 'react-native';
|
||||||
import { useNavigation } from '@react-navigation/native';
|
|
||||||
import { StackNavigationProp } from '@react-navigation/stack';
|
|
||||||
|
|
||||||
import { themes } from '../../lib/constants';
|
import { themes } from '../../lib/constants';
|
||||||
import { useTheme } from '../../theme';
|
import { useTheme } from '../../theme';
|
||||||
import { IUserChannel } from './interfaces';
|
import { IUserChannel } from './interfaces';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import { getSubscriptionByRoomId } from '../../lib/database/services/Subscription';
|
import { getSubscriptionByRoomId } from '../../lib/database/services/Subscription';
|
||||||
import { ChatsStackParamList } from '../../stacks/types';
|
|
||||||
import { useAppSelector } from '../../lib/hooks';
|
import { useAppSelector } from '../../lib/hooks';
|
||||||
import { goRoom } from '../../lib/methods/helpers/goRoom';
|
import { goRoom } from '../../lib/methods/helpers/goRoom';
|
||||||
|
|
||||||
|
@ -22,7 +19,6 @@ interface IHashtag {
|
||||||
const Hashtag = React.memo(({ hashtag, channels, navToRoomInfo, style = [] }: IHashtag) => {
|
const Hashtag = React.memo(({ hashtag, channels, navToRoomInfo, style = [] }: IHashtag) => {
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
const isMasterDetail = useAppSelector(state => state.app.isMasterDetail);
|
const isMasterDetail = useAppSelector(state => state.app.isMasterDetail);
|
||||||
const navigation = useNavigation<StackNavigationProp<ChatsStackParamList, 'RoomView'>>();
|
|
||||||
|
|
||||||
const handlePress = async () => {
|
const handlePress = async () => {
|
||||||
const index = channels?.findIndex(channel => channel.name === hashtag);
|
const index = channels?.findIndex(channel => channel.name === hashtag);
|
||||||
|
@ -33,7 +29,7 @@ const Hashtag = React.memo(({ hashtag, channels, navToRoomInfo, style = [] }: IH
|
||||||
};
|
};
|
||||||
const room = navParam.rid && (await getSubscriptionByRoomId(navParam.rid));
|
const room = navParam.rid && (await getSubscriptionByRoomId(navParam.rid));
|
||||||
if (room) {
|
if (room) {
|
||||||
goRoom({ item: room, isMasterDetail, navigationMethod: isMasterDetail ? navigation.replace : navigation.push });
|
goRoom({ item: room, isMasterDetail });
|
||||||
} else {
|
} else {
|
||||||
navToRoomInfo(navParam);
|
navToRoomInfo(navParam);
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,19 +73,14 @@ const QueueListView = React.memo(() => {
|
||||||
|
|
||||||
const onPressItem = (item = {} as IOmnichannelRoom) => {
|
const onPressItem = (item = {} as IOmnichannelRoom) => {
|
||||||
logEvent(events.QL_GO_ROOM);
|
logEvent(events.QL_GO_ROOM);
|
||||||
if (isMasterDetail) {
|
|
||||||
navigation.navigate('DrawerNavigator');
|
|
||||||
} else {
|
|
||||||
navigation.navigate('RoomsListView');
|
|
||||||
}
|
|
||||||
|
|
||||||
goRoom({
|
goRoom({
|
||||||
item: {
|
item: {
|
||||||
...item,
|
...item,
|
||||||
// we're calling v as visitor on our mergeSubscriptionsRooms
|
// we're calling v as visitor on our mergeSubscriptionsRooms
|
||||||
visitor: item.v
|
visitor: item.v
|
||||||
},
|
},
|
||||||
isMasterDetail
|
isMasterDetail,
|
||||||
|
popToRoot: true
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { ChatsStackParamList } from '../../../stacks/types';
|
import { CommonActions } from '@react-navigation/native';
|
||||||
|
|
||||||
import Navigation from '../../navigation/appNavigation';
|
import Navigation from '../../navigation/appNavigation';
|
||||||
import { IOmnichannelRoom, SubscriptionType, IVisitor, TSubscriptionModel, ISubscription } from '../../../definitions';
|
import { IOmnichannelRoom, SubscriptionType, IVisitor, TSubscriptionModel, ISubscription } from '../../../definitions';
|
||||||
import { getRoomTitle, getUidDirectMessage } from './helpers';
|
import { getRoomTitle, getUidDirectMessage } from './helpers';
|
||||||
|
@ -19,19 +20,14 @@ export type TGoRoomItem = IGoRoomItem | TSubscriptionModel | ISubscription | IOm
|
||||||
const navigate = ({
|
const navigate = ({
|
||||||
item,
|
item,
|
||||||
isMasterDetail,
|
isMasterDetail,
|
||||||
|
popToRoot,
|
||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
item: TGoRoomItem;
|
item: TGoRoomItem;
|
||||||
isMasterDetail: boolean;
|
isMasterDetail: boolean;
|
||||||
navigationMethod?: () => ChatsStackParamList;
|
popToRoot: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
let navigationMethod = props.navigationMethod ?? Navigation.navigate;
|
const routeParams = {
|
||||||
|
|
||||||
if (isMasterDetail) {
|
|
||||||
navigationMethod = Navigation.replace;
|
|
||||||
}
|
|
||||||
|
|
||||||
navigationMethod('RoomView', {
|
|
||||||
rid: item.rid,
|
rid: item.rid,
|
||||||
name: getRoomTitle(item),
|
name: getRoomTitle(item),
|
||||||
t: item.t,
|
t: item.t,
|
||||||
|
@ -40,6 +36,44 @@ const navigate = ({
|
||||||
visitor: item.visitor,
|
visitor: item.visitor,
|
||||||
roomUserId: getUidDirectMessage(item),
|
roomUserId: getUidDirectMessage(item),
|
||||||
...props
|
...props
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isMasterDetail) {
|
||||||
|
if (popToRoot) {
|
||||||
|
Navigation.navigate('DrawerNavigator');
|
||||||
|
}
|
||||||
|
return Navigation.dispatch((state: any) => {
|
||||||
|
const routesRoomView = state.routes.filter((r: any) => r.name !== 'RoomView');
|
||||||
|
return CommonActions.reset({
|
||||||
|
...state,
|
||||||
|
routes: [
|
||||||
|
...routesRoomView,
|
||||||
|
{
|
||||||
|
name: 'RoomView',
|
||||||
|
params: routeParams
|
||||||
|
}
|
||||||
|
],
|
||||||
|
index: routesRoomView.length
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (popToRoot) {
|
||||||
|
Navigation.navigate('RoomsListView');
|
||||||
|
}
|
||||||
|
return Navigation.dispatch((state: any) => {
|
||||||
|
const routesRoomsListView = state.routes.filter((r: any) => r.name === 'RoomsListView');
|
||||||
|
return CommonActions.reset({
|
||||||
|
...state,
|
||||||
|
routes: [
|
||||||
|
...routesRoomsListView,
|
||||||
|
{
|
||||||
|
name: 'RoomView',
|
||||||
|
params: routeParams
|
||||||
|
}
|
||||||
|
],
|
||||||
|
index: routesRoomsListView.length
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,13 +85,14 @@ interface IOmnichannelRoomVisitor extends IOmnichannelRoom {
|
||||||
export const goRoom = async ({
|
export const goRoom = async ({
|
||||||
item,
|
item,
|
||||||
isMasterDetail = false,
|
isMasterDetail = false,
|
||||||
|
popToRoot = false,
|
||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
item: TGoRoomItem;
|
item: TGoRoomItem;
|
||||||
isMasterDetail: boolean;
|
isMasterDetail: boolean;
|
||||||
navigationMethod?: any;
|
|
||||||
jumpToMessageId?: string;
|
jumpToMessageId?: string;
|
||||||
usedCannedResponse?: string;
|
usedCannedResponse?: string;
|
||||||
|
popToRoot?: boolean;
|
||||||
}): Promise<void> => {
|
}): Promise<void> => {
|
||||||
if (!('id' in item) && item.t === SubscriptionType.DIRECT && item?.search) {
|
if (!('id' in item) && item.t === SubscriptionType.DIRECT && item?.search) {
|
||||||
// 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
|
||||||
|
@ -72,6 +107,7 @@ export const goRoom = async ({
|
||||||
t: SubscriptionType.DIRECT
|
t: SubscriptionType.DIRECT
|
||||||
},
|
},
|
||||||
isMasterDetail,
|
isMasterDetail,
|
||||||
|
popToRoot,
|
||||||
...props
|
...props
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -80,5 +116,5 @@ export const goRoom = async ({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return navigate({ item, isMasterDetail, ...props });
|
return navigate({ item, isMasterDetail, popToRoot, ...props });
|
||||||
};
|
};
|
||||||
|
|
|
@ -125,8 +125,8 @@ export default class RoomSubscription {
|
||||||
if (ev === 'typing') {
|
if (ev === 'typing') {
|
||||||
const { user } = reduxStore.getState().login;
|
const { user } = reduxStore.getState().login;
|
||||||
const { UI_Use_Real_Name } = reduxStore.getState().settings;
|
const { UI_Use_Real_Name } = reduxStore.getState().settings;
|
||||||
const { rooms } = reduxStore.getState().room;
|
const { subscribedRoom } = reduxStore.getState().room;
|
||||||
if (rooms[0] !== _rid) {
|
if (subscribedRoom !== _rid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const [name, typing] = ddpMessage.fields.args;
|
const [name, typing] = ddpMessage.fields.args;
|
||||||
|
|
|
@ -197,8 +197,8 @@ const createOrUpdateSubscription = async (subscription: ISubscription, room: ISe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const { rooms } = store.getState().room;
|
const { subscribedRoom } = store.getState().room;
|
||||||
if (tmp.lastMessage && !rooms.includes(tmp.rid)) {
|
if (tmp.lastMessage && subscribedRoom !== tmp.rid) {
|
||||||
const lastMessage = buildMessage(tmp.lastMessage);
|
const lastMessage = buildMessage(tmp.lastMessage);
|
||||||
const messagesCollection = db.get('messages');
|
const messagesCollection = db.get('messages');
|
||||||
let messageRecord = {} as TMessageModel | null;
|
let messageRecord = {} as TMessageModel | null;
|
||||||
|
|
|
@ -21,11 +21,16 @@ function popToTop() {
|
||||||
navigationRef.current?.dispatch(StackActions.popToTop());
|
navigationRef.current?.dispatch(StackActions.popToTop());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function dispatch(params: any) {
|
||||||
|
navigationRef.current?.dispatch(params);
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
navigationRef,
|
navigationRef,
|
||||||
routeNameRef,
|
routeNameRef,
|
||||||
navigate,
|
navigate,
|
||||||
back,
|
back,
|
||||||
replace,
|
replace,
|
||||||
popToTop
|
popToTop,
|
||||||
|
dispatch
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,13 +12,13 @@ describe('test room reducer', () => {
|
||||||
it('should return modified store after subscribeRoom', () => {
|
it('should return modified store after subscribeRoom', () => {
|
||||||
mockedStore.dispatch(subscribeRoom('GENERAL'));
|
mockedStore.dispatch(subscribeRoom('GENERAL'));
|
||||||
const state = mockedStore.getState().room;
|
const state = mockedStore.getState().room;
|
||||||
expect(state.rooms).toEqual(['GENERAL']);
|
expect(state.subscribedRoom).toEqual('GENERAL');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return empty store after remove unsubscribeRoom', () => {
|
it('should return empty store after remove unsubscribeRoom', () => {
|
||||||
mockedStore.dispatch(unsubscribeRoom('GENERAL'));
|
mockedStore.dispatch(unsubscribeRoom('GENERAL'));
|
||||||
const state = mockedStore.getState().room;
|
const state = mockedStore.getState().room;
|
||||||
expect(state.rooms).toEqual([]);
|
expect(state.subscribedRoom).toEqual('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return initial state after leaveRoom', () => {
|
it('should return initial state after leaveRoom', () => {
|
||||||
|
|
|
@ -6,13 +6,13 @@ export type IRoomRecord = string[];
|
||||||
export interface IRoom {
|
export interface IRoom {
|
||||||
rid: string;
|
rid: string;
|
||||||
isDeleting: boolean;
|
isDeleting: boolean;
|
||||||
rooms: IRoomRecord;
|
subscribedRoom: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const initialState: IRoom = {
|
export const initialState: IRoom = {
|
||||||
rid: '',
|
rid: '',
|
||||||
isDeleting: false,
|
isDeleting: false,
|
||||||
rooms: []
|
subscribedRoom: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function (state = initialState, action: TActionsRoom): IRoom {
|
export default function (state = initialState, action: TActionsRoom): IRoom {
|
||||||
|
@ -20,12 +20,12 @@ export default function (state = initialState, action: TActionsRoom): IRoom {
|
||||||
case ROOM.SUBSCRIBE:
|
case ROOM.SUBSCRIBE:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
rooms: [action.rid, ...state.rooms]
|
subscribedRoom: action.rid
|
||||||
};
|
};
|
||||||
case ROOM.UNSUBSCRIBE:
|
case ROOM.UNSUBSCRIBE:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
rooms: state.rooms.filter(rid => rid !== action.rid)
|
subscribedRoom: state.subscribedRoom === action.rid ? '' : state.subscribedRoom
|
||||||
};
|
};
|
||||||
case ROOM.LEAVE:
|
case ROOM.LEAVE:
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
||||||
import { CREATE_CHANNEL, LOGIN } from '../actions/actionsTypes';
|
import { CREATE_CHANNEL, LOGIN } from '../actions/actionsTypes';
|
||||||
import { createChannelFailure, createChannelSuccess } from '../actions/createChannel';
|
import { createChannelFailure, createChannelSuccess } from '../actions/createChannel';
|
||||||
import { showErrorAlert } from '../lib/methods/helpers/info';
|
import { showErrorAlert } from '../lib/methods/helpers/info';
|
||||||
import Navigation from '../lib/navigation/appNavigation';
|
|
||||||
import database from '../lib/database';
|
import database from '../lib/database';
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
import { events, logEvent } from '../lib/methods/helpers/log';
|
import { events, logEvent } from '../lib/methods/helpers/log';
|
||||||
|
@ -78,10 +77,7 @@ const handleRequest = function* handleRequest({ data }) {
|
||||||
|
|
||||||
const handleSuccess = function* handleSuccess({ data }) {
|
const handleSuccess = function* handleSuccess({ data }) {
|
||||||
const isMasterDetail = yield select(state => state.app.isMasterDetail);
|
const isMasterDetail = yield select(state => state.app.isMasterDetail);
|
||||||
if (isMasterDetail) {
|
goRoom({ item: data, isMasterDetail, popToRoot: true });
|
||||||
Navigation.navigate('DrawerNavigator');
|
|
||||||
}
|
|
||||||
goRoom({ item: data, isMasterDetail });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFailure = function handleFailure({ err, isTeam }) {
|
const handleFailure = function handleFailure({ err, isTeam }) {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { all, delay, put, select, take, takeLatest } from 'redux-saga/effects';
|
import { all, delay, put, select, take, takeLatest } from 'redux-saga/effects';
|
||||||
|
|
||||||
import UserPreferences from '../lib/methods/userPreferences';
|
import UserPreferences from '../lib/methods/userPreferences';
|
||||||
import Navigation from '../lib/navigation/appNavigation';
|
|
||||||
import * as types from '../actions/actionsTypes';
|
import * as types from '../actions/actionsTypes';
|
||||||
import { selectServerRequest, serverInitAdd } from '../actions/server';
|
import { selectServerRequest, serverInitAdd } from '../actions/server';
|
||||||
import { inviteLinksRequest, inviteLinksSetToken } from '../actions/inviteLinks';
|
import { inviteLinksRequest, inviteLinksSetToken } from '../actions/inviteLinks';
|
||||||
|
@ -36,14 +35,6 @@ const handleInviteLink = function* handleInviteLink({ params, requireLogin = fal
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const popToRoot = function popToRoot({ isMasterDetail }) {
|
|
||||||
if (isMasterDetail) {
|
|
||||||
Navigation.navigate('DrawerNavigator');
|
|
||||||
} else {
|
|
||||||
Navigation.navigate('RoomsListView');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const navigate = function* navigate({ params }) {
|
const navigate = function* navigate({ params }) {
|
||||||
yield put(appStart({ root: RootEnum.ROOT_INSIDE }));
|
yield put(appStart({ root: RootEnum.ROOT_INSIDE }));
|
||||||
if (params.path || params.rid) {
|
if (params.path || params.rid) {
|
||||||
|
@ -65,27 +56,9 @@ const navigate = function* navigate({ params }) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const isMasterDetail = yield select(state => state.app.isMasterDetail);
|
const isMasterDetail = yield select(state => state.app.isMasterDetail);
|
||||||
const focusedRooms = yield select(state => state.room.rooms);
|
|
||||||
const jumpToMessageId = params.messageId;
|
const jumpToMessageId = params.messageId;
|
||||||
|
|
||||||
if (focusedRooms.includes(room.rid)) {
|
yield goRoom({ item, isMasterDetail, jumpToMessageId, jumpToThreadId, popToRoot: true });
|
||||||
// if there's one room on the list or last room is the one
|
|
||||||
if (focusedRooms.length === 1 || focusedRooms[0] === room.rid) {
|
|
||||||
if (jumpToThreadId) {
|
|
||||||
// With this conditional when there is a jumpToThreadId we can avoid the thread open again
|
|
||||||
// above other thread and the room could call again the thread
|
|
||||||
popToRoot({ isMasterDetail });
|
|
||||||
}
|
|
||||||
yield goRoom({ item, isMasterDetail, jumpToMessageId, jumpToThreadId });
|
|
||||||
} else {
|
|
||||||
popToRoot({ isMasterDetail });
|
|
||||||
yield goRoom({ item, isMasterDetail, jumpToMessageId, jumpToThreadId });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
popToRoot({ isMasterDetail });
|
|
||||||
yield goRoom({ item, isMasterDetail, jumpToMessageId, jumpToThreadId });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params.isCall) {
|
if (params.isCall) {
|
||||||
callJitsi(item);
|
callJitsi(item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { select, takeLatest } from 'redux-saga/effects';
|
import { select, takeLatest } from 'redux-saga/effects';
|
||||||
import { Q } from '@nozbe/watermelondb';
|
import { Q } from '@nozbe/watermelondb';
|
||||||
|
|
||||||
import Navigation from '../lib/navigation/appNavigation';
|
|
||||||
import { MESSAGES } from '../actions/actionsTypes';
|
import { MESSAGES } from '../actions/actionsTypes';
|
||||||
import database from '../lib/database';
|
import database from '../lib/database';
|
||||||
import log from '../lib/methods/helpers/log';
|
import log from '../lib/methods/helpers/log';
|
||||||
|
@ -16,18 +15,13 @@ const handleReplyBroadcast = function* handleReplyBroadcast({ message }) {
|
||||||
const subscriptions = yield subsCollection.query(Q.where('name', username)).fetch();
|
const subscriptions = yield subsCollection.query(Q.where('name', username)).fetch();
|
||||||
|
|
||||||
const isMasterDetail = yield select(state => state.app.isMasterDetail);
|
const isMasterDetail = yield select(state => state.app.isMasterDetail);
|
||||||
if (isMasterDetail) {
|
|
||||||
Navigation.navigate('DrawerNavigator');
|
|
||||||
} else {
|
|
||||||
Navigation.navigate('RoomsListView');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subscriptions.length) {
|
if (subscriptions.length) {
|
||||||
goRoom({ item: subscriptions[0], isMasterDetail, message });
|
goRoom({ item: subscriptions[0], isMasterDetail, popToRoot: true, message });
|
||||||
} else {
|
} else {
|
||||||
const result = yield Services.createDirectMessage(username);
|
const result = yield Services.createDirectMessage(username);
|
||||||
if (result?.success) {
|
if (result?.success) {
|
||||||
goRoom({ item: result?.room, isMasterDetail, message });
|
goRoom({ item: result?.room, isMasterDetail, popToRoot: true, message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -58,13 +58,13 @@ const handleRoomsRequest = function* handleRoomsRequest({ params }) {
|
||||||
const subsToCreate = subscriptions.filter(i1 => !existingSubs.find(i2 => i1._id === i2._id));
|
const subsToCreate = subscriptions.filter(i1 => !existingSubs.find(i2 => i1._id === i2._id));
|
||||||
const subsToDelete = existingSubs.filter(i1 => !subscriptions.find(i2 => i1._id === i2._id));
|
const subsToDelete = existingSubs.filter(i1 => !subscriptions.find(i2 => i1._id === i2._id));
|
||||||
|
|
||||||
const openedRooms = yield select(state => state.room.rooms);
|
const subscribedRoom = yield select(state => state.room.subscribedRoom);
|
||||||
const lastMessages = subscriptions
|
const lastMessages = subscriptions
|
||||||
/** Checks for opened rooms and filter them out.
|
/** Checks for opened rooms and filter them out.
|
||||||
* It prevents this process to try persisting the same last message on the room messages fetch.
|
* It prevents this process to try persisting the same last message on the room messages fetch.
|
||||||
* This race condition is easy to reproduce on push notification tap.
|
* This race condition is easy to reproduce on push notification tap.
|
||||||
*/
|
*/
|
||||||
.filter(sub => !openedRooms.includes(sub.rid))
|
.filter(sub => subscribedRoom !== sub.rid)
|
||||||
.map(sub => sub.lastMessage && buildMessage(sub.lastMessage))
|
.map(sub => sub.lastMessage && buildMessage(sub.lastMessage))
|
||||||
.filter(lm => lm);
|
.filter(lm => lm);
|
||||||
const lastMessagesIds = lastMessages.map(lm => lm._id).filter(lm => lm);
|
const lastMessagesIds = lastMessages.map(lm => lm._id).filter(lm => lm);
|
||||||
|
|
|
@ -17,7 +17,6 @@ import { TSupportedThemes, withTheme } from '../theme';
|
||||||
import SafeAreaView from '../containers/SafeAreaView';
|
import SafeAreaView from '../containers/SafeAreaView';
|
||||||
import { sendLoadingEvent } from '../containers/Loading';
|
import { sendLoadingEvent } from '../containers/Loading';
|
||||||
import { animateNextTransition } from '../lib/methods/helpers/layoutAnimation';
|
import { animateNextTransition } from '../lib/methods/helpers/layoutAnimation';
|
||||||
import { goRoom } from '../lib/methods/helpers/goRoom';
|
|
||||||
import { showErrorAlert } from '../lib/methods/helpers/info';
|
import { showErrorAlert } from '../lib/methods/helpers/info';
|
||||||
import { ChatsStackParamList } from '../stacks/types';
|
import { ChatsStackParamList } from '../stacks/types';
|
||||||
import { TSubscriptionModel, SubscriptionType, IApplicationState } from '../definitions';
|
import { TSubscriptionModel, SubscriptionType, IApplicationState } from '../definitions';
|
||||||
|
@ -126,7 +125,7 @@ class AddExistingChannelView extends React.Component<IAddExistingChannelViewProp
|
||||||
|
|
||||||
submit = async () => {
|
submit = async () => {
|
||||||
const { selected } = this.state;
|
const { selected } = this.state;
|
||||||
const { isMasterDetail } = this.props;
|
const { navigation } = this.props;
|
||||||
|
|
||||||
sendLoadingEvent({ visible: true });
|
sendLoadingEvent({ visible: true });
|
||||||
try {
|
try {
|
||||||
|
@ -134,9 +133,8 @@ class AddExistingChannelView extends React.Component<IAddExistingChannelViewProp
|
||||||
const result = await Services.addRoomsToTeam({ rooms: selected, teamId: this.teamId });
|
const result = await Services.addRoomsToTeam({ rooms: selected, teamId: this.teamId });
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
sendLoadingEvent({ visible: false });
|
sendLoadingEvent({ visible: false });
|
||||||
// @ts-ignore
|
// Expect that after you add an existing channel to a team, the user should move back to the team
|
||||||
// TODO: Verify goRoom interface for return of call
|
navigation.navigate('RoomView');
|
||||||
goRoom({ item: result, isMasterDetail });
|
|
||||||
}
|
}
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
logEvent(events.CT_ADD_ROOM_TO_TEAM_F);
|
logEvent(events.CT_ADD_ROOM_TO_TEAM_F);
|
||||||
|
|
|
@ -8,14 +8,12 @@ import SafeAreaView from '../containers/SafeAreaView';
|
||||||
import StatusBar from '../containers/StatusBar';
|
import StatusBar from '../containers/StatusBar';
|
||||||
import Button from '../containers/Button';
|
import Button from '../containers/Button';
|
||||||
import { TSupportedThemes, useTheme } from '../theme';
|
import { TSupportedThemes, useTheme } from '../theme';
|
||||||
import Navigation from '../lib/navigation/appNavigation';
|
|
||||||
import { goRoom } from '../lib/methods/helpers/goRoom';
|
import { goRoom } from '../lib/methods/helpers/goRoom';
|
||||||
import { themes } from '../lib/constants';
|
import { themes } from '../lib/constants';
|
||||||
import Markdown from '../containers/markdown';
|
import Markdown from '../containers/markdown';
|
||||||
import { ICannedResponse } from '../definitions/ICannedResponse';
|
import { ICannedResponse } from '../definitions/ICannedResponse';
|
||||||
import { ChatsStackParamList } from '../stacks/types';
|
import { ChatsStackParamList } from '../stacks/types';
|
||||||
import sharedStyles from './Styles';
|
import sharedStyles from './Styles';
|
||||||
import { getRoomTitle, getUidDirectMessage } from '../lib/methods/helpers';
|
|
||||||
import { useAppSelector } from '../lib/hooks';
|
import { useAppSelector } from '../lib/hooks';
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
|
@ -97,7 +95,6 @@ const CannedResponseDetail = ({ navigation, route }: ICannedResponseDetailProps)
|
||||||
const { cannedResponse } = route?.params;
|
const { cannedResponse } = route?.params;
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
const { isMasterDetail } = useAppSelector(state => state.app);
|
const { isMasterDetail } = useAppSelector(state => state.app);
|
||||||
const { rooms } = useAppSelector(state => state.room);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
|
@ -107,31 +104,9 @@ const CannedResponseDetail = ({ navigation, route }: ICannedResponseDetailProps)
|
||||||
|
|
||||||
const navigateToRoom = (item: ICannedResponse) => {
|
const navigateToRoom = (item: ICannedResponse) => {
|
||||||
const { room } = route.params;
|
const { room } = route.params;
|
||||||
const { name } = room;
|
|
||||||
const params = {
|
|
||||||
rid: room.rid,
|
|
||||||
name: getRoomTitle({
|
|
||||||
t: room.t,
|
|
||||||
fname: name
|
|
||||||
}),
|
|
||||||
t: room.t,
|
|
||||||
roomUserId: getUidDirectMessage(room),
|
|
||||||
usedCannedResponse: item.text
|
|
||||||
};
|
|
||||||
|
|
||||||
if (room.rid) {
|
if (room.rid) {
|
||||||
// if it's on master detail layout, we close the modal and replace RoomView
|
goRoom({ item: room, isMasterDetail, popToRoot: true, usedCannedResponse: item.text });
|
||||||
if (isMasterDetail) {
|
|
||||||
Navigation.navigate('DrawerNavigator');
|
|
||||||
goRoom({ item: params, isMasterDetail });
|
|
||||||
} else {
|
|
||||||
let navigate = navigation.push;
|
|
||||||
// if this is a room focused
|
|
||||||
if (rooms.includes(room.rid)) {
|
|
||||||
({ navigate } = navigation);
|
|
||||||
}
|
|
||||||
navigate('RoomView', params);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
import SearchHeader from '../../containers/SearchHeader';
|
import SearchHeader from '../../containers/SearchHeader';
|
||||||
import BackgroundContainer from '../../containers/BackgroundContainer';
|
import BackgroundContainer from '../../containers/BackgroundContainer';
|
||||||
import { useTheme } from '../../theme';
|
import { useTheme } from '../../theme';
|
||||||
import Navigation from '../../lib/navigation/appNavigation';
|
|
||||||
import { goRoom } from '../../lib/methods/helpers/goRoom';
|
import { goRoom } from '../../lib/methods/helpers/goRoom';
|
||||||
import * as HeaderButton from '../../containers/HeaderButton';
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
import * as List from '../../containers/List';
|
import * as List from '../../containers/List';
|
||||||
|
@ -24,7 +23,7 @@ import DropdownItemHeader from './Dropdown/DropdownItemHeader';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import { ICannedResponse } from '../../definitions/ICannedResponse';
|
import { ICannedResponse } from '../../definitions/ICannedResponse';
|
||||||
import { ChatsStackParamList } from '../../stacks/types';
|
import { ChatsStackParamList } from '../../stacks/types';
|
||||||
import { getRoomTitle, getUidDirectMessage, useDebounce } from '../../lib/methods/helpers';
|
import { useDebounce } from '../../lib/methods/helpers';
|
||||||
import { Services } from '../../lib/services';
|
import { Services } from '../../lib/services';
|
||||||
import { ILivechatDepartment } from '../../definitions/ILivechatDepartment';
|
import { ILivechatDepartment } from '../../definitions/ILivechatDepartment';
|
||||||
import { useAppSelector } from '../../lib/hooks';
|
import { useAppSelector } from '../../lib/hooks';
|
||||||
|
@ -73,7 +72,6 @@ const CannedResponsesListView = ({ navigation, route }: ICannedResponsesListView
|
||||||
|
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
const isMasterDetail = useAppSelector(state => state.app.isMasterDetail);
|
const isMasterDetail = useAppSelector(state => state.app.isMasterDetail);
|
||||||
const rooms = useAppSelector(state => state.room.rooms);
|
|
||||||
|
|
||||||
const getRoomFromDb = async () => {
|
const getRoomFromDb = async () => {
|
||||||
const { rid } = route.params;
|
const { rid } = route.params;
|
||||||
|
@ -107,34 +105,8 @@ const CannedResponsesListView = ({ navigation, route }: ICannedResponsesListView
|
||||||
};
|
};
|
||||||
|
|
||||||
const navigateToRoom = (item: ICannedResponse) => {
|
const navigateToRoom = (item: ICannedResponse) => {
|
||||||
if (!room) {
|
if (room?.rid) {
|
||||||
return;
|
goRoom({ item: room, isMasterDetail, popToRoot: true, usedCannedResponse: item.text });
|
||||||
}
|
|
||||||
const { name } = room;
|
|
||||||
const params = {
|
|
||||||
rid: room.rid,
|
|
||||||
name: getRoomTitle({
|
|
||||||
t: room.t,
|
|
||||||
fname: name
|
|
||||||
}),
|
|
||||||
t: room.t,
|
|
||||||
roomUserId: getUidDirectMessage(room),
|
|
||||||
usedCannedResponse: item.text
|
|
||||||
};
|
|
||||||
|
|
||||||
if (room.rid) {
|
|
||||||
// if it's on master detail layout, we close the modal and replace RoomView
|
|
||||||
if (isMasterDetail) {
|
|
||||||
Navigation.navigate('DrawerNavigator');
|
|
||||||
goRoom({ item: params, isMasterDetail });
|
|
||||||
} else {
|
|
||||||
let navigate = navigation.push;
|
|
||||||
// if this is a room focused
|
|
||||||
if (rooms.includes(room.rid)) {
|
|
||||||
({ navigate } = navigation);
|
|
||||||
}
|
|
||||||
navigate('RoomView', params);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ import StatusBar from '../../containers/StatusBar';
|
||||||
import { withTheme } from '../../theme';
|
import { withTheme } from '../../theme';
|
||||||
import { getUserSelector } from '../../selectors/login';
|
import { getUserSelector } from '../../selectors/login';
|
||||||
import { FormTextInput } from '../../containers/TextInput';
|
import { FormTextInput } from '../../containers/TextInput';
|
||||||
import Navigation from '../../lib/navigation/appNavigation';
|
|
||||||
import { createDiscussionRequest, ICreateDiscussionRequestData } from '../../actions/createDiscussion';
|
import { createDiscussionRequest, ICreateDiscussionRequestData } from '../../actions/createDiscussion';
|
||||||
import SafeAreaView from '../../containers/SafeAreaView';
|
import SafeAreaView from '../../containers/SafeAreaView';
|
||||||
import { goRoom } from '../../lib/methods/helpers/goRoom';
|
import { goRoom } from '../../lib/methods/helpers/goRoom';
|
||||||
|
@ -60,18 +59,13 @@ class CreateChannelView extends React.Component<ICreateChannelViewProps, ICreate
|
||||||
showErrorAlert(msg);
|
showErrorAlert(msg);
|
||||||
} else {
|
} else {
|
||||||
const { rid, t, prid } = result;
|
const { rid, t, prid } = result;
|
||||||
if (isMasterDetail) {
|
|
||||||
Navigation.navigate('DrawerNavigator');
|
|
||||||
} else {
|
|
||||||
Navigation.navigate('RoomsListView');
|
|
||||||
}
|
|
||||||
const item = {
|
const item = {
|
||||||
rid,
|
rid,
|
||||||
name: getRoomTitle(result),
|
name: getRoomTitle(result),
|
||||||
t,
|
t,
|
||||||
prid
|
prid
|
||||||
};
|
};
|
||||||
goRoom({ item, isMasterDetail });
|
goRoom({ item, isMasterDetail, popToRoot: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,13 +152,8 @@ class DirectoryView extends React.Component<IDirectoryViewProps, IDirectoryViewS
|
||||||
};
|
};
|
||||||
|
|
||||||
goRoom = (item: TGoRoomItem) => {
|
goRoom = (item: TGoRoomItem) => {
|
||||||
const { navigation, isMasterDetail } = this.props;
|
const { isMasterDetail } = this.props;
|
||||||
if (isMasterDetail) {
|
goRoom({ item, isMasterDetail, popToRoot: true });
|
||||||
navigation.navigate('DrawerNavigator');
|
|
||||||
} else {
|
|
||||||
navigation.navigate('RoomsListView');
|
|
||||||
}
|
|
||||||
goRoom({ item, isMasterDetail });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onPressItem = async (item: IServerRoom) => {
|
onPressItem = async (item: IServerRoom) => {
|
||||||
|
|
|
@ -74,10 +74,7 @@ const NewMessageView = () => {
|
||||||
const goRoom = useCallback(
|
const goRoom = useCallback(
|
||||||
(item: TGoRoomItem) => {
|
(item: TGoRoomItem) => {
|
||||||
logEvent(events.NEW_MSG_CHAT_WITH_USER);
|
logEvent(events.NEW_MSG_CHAT_WITH_USER);
|
||||||
|
navigation.pop();
|
||||||
if (isMasterDetail) {
|
|
||||||
navigation.pop();
|
|
||||||
}
|
|
||||||
goRoomMethod({ item, isMasterDetail });
|
goRoomMethod({ item, isMasterDetail });
|
||||||
},
|
},
|
||||||
[isMasterDetail, navigation]
|
[isMasterDetail, navigation]
|
||||||
|
|
|
@ -87,7 +87,7 @@ interface IRoomInfoViewProps {
|
||||||
StackNavigationProp<MasterDetailInsideStackParamList>
|
StackNavigationProp<MasterDetailInsideStackParamList>
|
||||||
>;
|
>;
|
||||||
route: RouteProp<ChatsStackParamList, 'RoomInfoView'>;
|
route: RouteProp<ChatsStackParamList, 'RoomInfoView'>;
|
||||||
rooms: string[];
|
subscribedRoom: string;
|
||||||
theme: TSupportedThemes;
|
theme: TSupportedThemes;
|
||||||
isMasterDetail: boolean;
|
isMasterDetail: boolean;
|
||||||
jitsiEnabled: boolean;
|
jitsiEnabled: boolean;
|
||||||
|
@ -353,7 +353,7 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat
|
||||||
goRoom = () => {
|
goRoom = () => {
|
||||||
logEvent(events.RI_GO_ROOM_USER);
|
logEvent(events.RI_GO_ROOM_USER);
|
||||||
const { room } = this.state;
|
const { room } = this.state;
|
||||||
const { rooms, navigation, isMasterDetail } = this.props;
|
const { navigation, isMasterDetail, subscribedRoom } = this.props;
|
||||||
const params = {
|
const params = {
|
||||||
rid: room.rid,
|
rid: room.rid,
|
||||||
name: getRoomTitle(room),
|
name: getRoomTitle(room),
|
||||||
|
@ -362,18 +362,14 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat
|
||||||
};
|
};
|
||||||
|
|
||||||
if (room.rid) {
|
if (room.rid) {
|
||||||
// if it's on master detail layout, we close the modal and replace RoomView
|
if (room.rid === subscribedRoom) {
|
||||||
if (isMasterDetail) {
|
if (isMasterDetail) {
|
||||||
Navigation.navigate('DrawerNavigator');
|
return Navigation.navigate('DrawerNavigator');
|
||||||
goRoom({ item: params, isMasterDetail });
|
|
||||||
} else {
|
|
||||||
let navigate = navigation.push;
|
|
||||||
// if this is a room focused
|
|
||||||
if (rooms.includes(room.rid)) {
|
|
||||||
({ navigate } = navigation);
|
|
||||||
}
|
}
|
||||||
navigate('RoomView', params);
|
return navigation.goBack();
|
||||||
}
|
}
|
||||||
|
// if it's on master detail layout, we close the modal and replace RoomView
|
||||||
|
goRoom({ item: params, isMasterDetail, popToRoot: true });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -513,7 +509,7 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = (state: IApplicationState) => ({
|
const mapStateToProps = (state: IApplicationState) => ({
|
||||||
rooms: state.room.rooms,
|
subscribedRoom: state.room.subscribedRoom,
|
||||||
isMasterDetail: state.app.isMasterDetail,
|
isMasterDetail: state.app.isMasterDetail,
|
||||||
jitsiEnabled: (state.settings.Jitsi_Enabled as boolean) || false,
|
jitsiEnabled: (state.settings.Jitsi_Enabled as boolean) || false,
|
||||||
editRoomPermission: state.permissions['edit-room'],
|
editRoomPermission: state.permissions['edit-room'],
|
||||||
|
|
|
@ -15,12 +15,7 @@ import { RoomTypes } from '../../lib/methods';
|
||||||
export type TRoomType = SubscriptionType.CHANNEL | SubscriptionType.GROUP | SubscriptionType.OMNICHANNEL;
|
export type TRoomType = SubscriptionType.CHANNEL | SubscriptionType.GROUP | SubscriptionType.OMNICHANNEL;
|
||||||
|
|
||||||
const handleGoRoom = (item: TGoRoomItem, isMasterDetail: boolean): void => {
|
const handleGoRoom = (item: TGoRoomItem, isMasterDetail: boolean): void => {
|
||||||
if (isMasterDetail) {
|
goRoom({ item, isMasterDetail, popToRoot: true });
|
||||||
appNavigation.navigate('DrawerNavigator');
|
|
||||||
} else {
|
|
||||||
appNavigation.popToTop();
|
|
||||||
}
|
|
||||||
goRoom({ item, isMasterDetail });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchRole = (role: string, selectedUser: TUserModel, roomRoles: any): boolean => {
|
export const fetchRole = (role: string, selectedUser: TUserModel, roomRoles: any): boolean => {
|
||||||
|
|
|
@ -43,7 +43,6 @@ import SafeAreaView from '../../containers/SafeAreaView';
|
||||||
import { withDimensions } from '../../dimensions';
|
import { withDimensions } from '../../dimensions';
|
||||||
import { takeInquiry, takeResume } from '../../ee/omnichannel/lib';
|
import { takeInquiry, takeResume } from '../../ee/omnichannel/lib';
|
||||||
import { sendLoadingEvent } from '../../containers/Loading';
|
import { sendLoadingEvent } from '../../containers/Loading';
|
||||||
import { goRoom, TGoRoomItem } from '../../lib/methods/helpers/goRoom';
|
|
||||||
import getThreadName from '../../lib/methods/getThreadName';
|
import getThreadName from '../../lib/methods/getThreadName';
|
||||||
import getRoomInfo from '../../lib/methods/getRoomInfo';
|
import getRoomInfo from '../../lib/methods/getRoomInfo';
|
||||||
import { ContainerTypes } from '../../containers/UIKit/interfaces';
|
import { ContainerTypes } from '../../containers/UIKit/interfaces';
|
||||||
|
@ -101,6 +100,7 @@ import {
|
||||||
} from '../../lib/methods/helpers';
|
} from '../../lib/methods/helpers';
|
||||||
import { Services } from '../../lib/services';
|
import { Services } from '../../lib/services';
|
||||||
import { withActionSheet, IActionSheetProvider } from '../../containers/ActionSheet';
|
import { withActionSheet, IActionSheetProvider } from '../../containers/ActionSheet';
|
||||||
|
import { goRoom, TGoRoomItem } from '../../lib/methods/helpers/goRoom';
|
||||||
|
|
||||||
type TStateAttrsUpdate = keyof IRoomViewState;
|
type TStateAttrsUpdate = keyof IRoomViewState;
|
||||||
|
|
||||||
|
@ -910,15 +910,15 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
||||||
|
|
||||||
onDiscussionPress = debounce(
|
onDiscussionPress = debounce(
|
||||||
async (item: TAnyMessageModel) => {
|
async (item: TAnyMessageModel) => {
|
||||||
const { navigation } = this.props;
|
const { isMasterDetail } = this.props;
|
||||||
if (!item.drid) return;
|
if (!item.drid) return;
|
||||||
const sub = await getRoomInfo(item.drid);
|
const sub = await getRoomInfo(item.drid);
|
||||||
navigation.push('RoomView', {
|
if (sub) {
|
||||||
rid: item.drid as string,
|
goRoom({
|
||||||
prid: item?.subscription?.id,
|
item: sub as TGoRoomItem,
|
||||||
name: item.msg,
|
isMasterDetail
|
||||||
t: (sub?.t as SubscriptionType) || (this.t as SubscriptionType)
|
});
|
||||||
});
|
}
|
||||||
},
|
},
|
||||||
1000,
|
1000,
|
||||||
true
|
true
|
||||||
|
@ -987,6 +987,11 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
||||||
} else {
|
} else {
|
||||||
this.navToThread(message);
|
this.navToThread(message);
|
||||||
}
|
}
|
||||||
|
} else if (!message.tmid && message.rid === this.rid && this.t === 'thread' && !message.replies) {
|
||||||
|
/**
|
||||||
|
* if the user is within a thread and the message that he is trying to jump to, is a message in the main room
|
||||||
|
*/
|
||||||
|
return this.navToRoom(message);
|
||||||
} else {
|
} else {
|
||||||
/**
|
/**
|
||||||
* if it's from server, we don't have it saved locally and so we fetch surroundings
|
* if it's from server, we don't have it saved locally and so we fetch surroundings
|
||||||
|
@ -1198,12 +1203,12 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
navToRoom = async (message: TAnyMessageModel) => {
|
navToRoom = async (message: TAnyMessageModel) => {
|
||||||
const { navigation, isMasterDetail } = this.props;
|
const { isMasterDetail } = this.props;
|
||||||
const roomInfo = await getRoomInfo(message.rid);
|
const roomInfo = await getRoomInfo(message.rid);
|
||||||
|
|
||||||
return goRoom({
|
return goRoom({
|
||||||
item: roomInfo as TGoRoomItem,
|
item: roomInfo as TGoRoomItem,
|
||||||
isMasterDetail,
|
isMasterDetail,
|
||||||
navigationMethod: navigation.push,
|
|
||||||
jumpToMessageId: message.id
|
jumpToMessageId: message.id
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,8 +6,10 @@ import Orientation from 'react-native-orientation-locker';
|
||||||
import { Q } from '@nozbe/watermelondb';
|
import { Q } from '@nozbe/watermelondb';
|
||||||
import { withSafeAreaInsets } from 'react-native-safe-area-context';
|
import { withSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { StackNavigationOptions } from '@react-navigation/stack';
|
import { StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack';
|
||||||
import { Header } from '@react-navigation/elements';
|
import { Header } from '@react-navigation/elements';
|
||||||
|
import { CompositeNavigationProp, RouteProp } from '@react-navigation/native';
|
||||||
|
import { Dispatch } from 'redux';
|
||||||
|
|
||||||
import database from '../../lib/database';
|
import database from '../../lib/database';
|
||||||
import RoomItem, { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from '../../containers/RoomItem';
|
import RoomItem, { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from '../../containers/RoomItem';
|
||||||
|
@ -20,7 +22,7 @@ import StatusBar from '../../containers/StatusBar';
|
||||||
import ActivityIndicator from '../../containers/ActivityIndicator';
|
import ActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
import { serverInitAdd } from '../../actions/server';
|
import { serverInitAdd } from '../../actions/server';
|
||||||
import { animateNextTransition } from '../../lib/methods/helpers/layoutAnimation';
|
import { animateNextTransition } from '../../lib/methods/helpers/layoutAnimation';
|
||||||
import { withTheme } from '../../theme';
|
import { TSupportedThemes, withTheme } from '../../theme';
|
||||||
import EventEmitter from '../../lib/methods/helpers/events';
|
import EventEmitter from '../../lib/methods/helpers/events';
|
||||||
import { themedHeader } from '../../lib/methods/helpers/navigation';
|
import { themedHeader } from '../../lib/methods/helpers/navigation';
|
||||||
import {
|
import {
|
||||||
|
@ -39,20 +41,12 @@ import { goRoom } from '../../lib/methods/helpers/goRoom';
|
||||||
import SafeAreaView from '../../containers/SafeAreaView';
|
import SafeAreaView from '../../containers/SafeAreaView';
|
||||||
import { withDimensions } from '../../dimensions';
|
import { withDimensions } from '../../dimensions';
|
||||||
import { getInquiryQueueSelector } from '../../ee/omnichannel/selectors/inquiry';
|
import { getInquiryQueueSelector } from '../../ee/omnichannel/selectors/inquiry';
|
||||||
import {
|
import { IApplicationState, ISubscription, IUser, RootEnum, SubscriptionType, TSubscriptionModel } from '../../definitions';
|
||||||
IApplicationState,
|
|
||||||
IBaseScreen,
|
|
||||||
ISubscription,
|
|
||||||
IUser,
|
|
||||||
RootEnum,
|
|
||||||
SubscriptionType,
|
|
||||||
TSubscriptionModel
|
|
||||||
} from '../../definitions';
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import ServerDropdown from './ServerDropdown';
|
import ServerDropdown from './ServerDropdown';
|
||||||
import ListHeader, { TEncryptionBanner } from './ListHeader';
|
import ListHeader, { TEncryptionBanner } from './ListHeader';
|
||||||
import RoomsListHeaderView from './Header';
|
import RoomsListHeaderView from './Header';
|
||||||
import { ChatsStackParamList } from '../../stacks/types';
|
import { ChatsStackParamList, DrawerParamList } from '../../stacks/types';
|
||||||
import { RoomTypes, search } from '../../lib/methods';
|
import { RoomTypes, search } from '../../lib/methods';
|
||||||
import {
|
import {
|
||||||
getRoomAvatar,
|
getRoomAvatar,
|
||||||
|
@ -67,7 +61,16 @@ import {
|
||||||
import { E2E_BANNER_TYPE, DisplayMode, SortBy, MAX_SIDEBAR_WIDTH, themes } from '../../lib/constants';
|
import { E2E_BANNER_TYPE, DisplayMode, SortBy, MAX_SIDEBAR_WIDTH, themes } from '../../lib/constants';
|
||||||
import { Services } from '../../lib/services';
|
import { Services } from '../../lib/services';
|
||||||
|
|
||||||
interface IRoomsListViewProps extends IBaseScreen<ChatsStackParamList, 'RoomsListView'> {
|
type TNavigation = CompositeNavigationProp<
|
||||||
|
StackNavigationProp<ChatsStackParamList, 'RoomsListView'>,
|
||||||
|
CompositeNavigationProp<StackNavigationProp<ChatsStackParamList>, StackNavigationProp<DrawerParamList>>
|
||||||
|
>;
|
||||||
|
|
||||||
|
interface IRoomsListViewProps {
|
||||||
|
navigation: TNavigation;
|
||||||
|
route: RouteProp<ChatsStackParamList, 'RoomsListView'>;
|
||||||
|
theme: TSupportedThemes;
|
||||||
|
dispatch: Dispatch;
|
||||||
[key: string]: IUser | string | boolean | ISubscription[] | number | object | TEncryptionBanner;
|
[key: string]: IUser | string | boolean | ISubscription[] | number | object | TEncryptionBanner;
|
||||||
user: IUser;
|
user: IUser;
|
||||||
server: string;
|
server: string;
|
||||||
|
@ -83,7 +86,7 @@ interface IRoomsListViewProps extends IBaseScreen<ChatsStackParamList, 'RoomsLis
|
||||||
StoreLastMessage: boolean;
|
StoreLastMessage: boolean;
|
||||||
useRealName: boolean;
|
useRealName: boolean;
|
||||||
isMasterDetail: boolean;
|
isMasterDetail: boolean;
|
||||||
rooms: string[];
|
subscribedRoom: string;
|
||||||
width: number;
|
width: number;
|
||||||
insets: {
|
insets: {
|
||||||
left: number;
|
left: number;
|
||||||
|
@ -304,7 +307,7 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
|
||||||
}
|
}
|
||||||
|
|
||||||
const { loading, search } = this.state;
|
const { loading, search } = this.state;
|
||||||
const { rooms, width, insets } = this.props;
|
const { width, insets, subscribedRoom } = this.props;
|
||||||
if (nextState.loading !== loading) {
|
if (nextState.loading !== loading) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -314,7 +317,7 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
|
||||||
if (!dequal(nextState.search, search)) {
|
if (!dequal(nextState.search, search)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!dequal(nextProps.rooms, rooms)) {
|
if (nextProps.subscribedRoom !== subscribedRoom) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!dequal(nextProps.insets, insets)) {
|
if (!dequal(nextProps.insets, insets)) {
|
||||||
|
@ -334,7 +337,7 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
|
||||||
groupByType,
|
groupByType,
|
||||||
showFavorites,
|
showFavorites,
|
||||||
showUnread,
|
showUnread,
|
||||||
rooms,
|
subscribedRoom,
|
||||||
isMasterDetail,
|
isMasterDetail,
|
||||||
insets,
|
insets,
|
||||||
createTeamPermission,
|
createTeamPermission,
|
||||||
|
@ -359,9 +362,9 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
|
||||||
) {
|
) {
|
||||||
this.getSubscriptions();
|
this.getSubscriptions();
|
||||||
}
|
}
|
||||||
// Update current item in case of another action triggers an update on rooms reducer
|
// Update current item in case of another action triggers an update on room subscribed reducer
|
||||||
if (isMasterDetail && rooms[0] && item?.rid !== rooms[0] && !dequal(rooms, prevProps.rooms)) {
|
if (isMasterDetail && item?.rid !== subscribedRoom && subscribedRoom !== prevProps.subscribedRoom) {
|
||||||
this.setState({ item: { rid: rooms[0] } as ISubscription });
|
this.setState({ item: { rid: subscribedRoom } as ISubscription });
|
||||||
}
|
}
|
||||||
if (insets.left !== prevProps.insets.left || insets.right !== prevProps.insets.right) {
|
if (insets.left !== prevProps.insets.left || insets.right !== prevProps.insets.right) {
|
||||||
this.setHeader();
|
this.setHeader();
|
||||||
|
@ -765,9 +768,9 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
|
||||||
goRoom = ({ item, isMasterDetail }: { item: ISubscription; isMasterDetail: boolean }) => {
|
goRoom = ({ item, isMasterDetail }: { item: ISubscription; isMasterDetail: boolean }) => {
|
||||||
logEvent(events.RL_GO_ROOM);
|
logEvent(events.RL_GO_ROOM);
|
||||||
const { item: currentItem } = this.state;
|
const { item: currentItem } = this.state;
|
||||||
const { rooms } = this.props;
|
const { subscribedRoom } = this.props;
|
||||||
// @ts-ignore
|
|
||||||
if (currentItem?.rid === item.rid || rooms?.includes(item.rid)) {
|
if (currentItem?.rid === item.rid || subscribedRoom === item.rid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Only mark room as focused when in master detail layout
|
// Only mark room as focused when in master detail layout
|
||||||
|
@ -1040,7 +1043,7 @@ const mapStateToProps = (state: IApplicationState) => ({
|
||||||
showUnread: state.sortPreferences.showUnread,
|
showUnread: state.sortPreferences.showUnread,
|
||||||
useRealName: state.settings.UI_Use_Real_Name,
|
useRealName: state.settings.UI_Use_Real_Name,
|
||||||
StoreLastMessage: state.settings.Store_Last_Message,
|
StoreLastMessage: state.settings.Store_Last_Message,
|
||||||
rooms: state.room.rooms,
|
subscribedRoom: state.room.subscribedRoom,
|
||||||
queueSize: getInquiryQueueSelector(state).length,
|
queueSize: getInquiryQueueSelector(state).length,
|
||||||
inquiryEnabled: state.inquiry.enabled,
|
inquiryEnabled: state.inquiry.enabled,
|
||||||
encryptionBanner: state.encryption.banner,
|
encryptionBanner: state.encryption.banner,
|
||||||
|
|
|
@ -322,7 +322,7 @@ class TeamChannelsView extends React.Component<ITeamChannelsViewProps, ITeamChan
|
||||||
onPressItem = debounce(
|
onPressItem = debounce(
|
||||||
async (item: IItem) => {
|
async (item: IItem) => {
|
||||||
logEvent(events.TC_GO_ROOM);
|
logEvent(events.TC_GO_ROOM);
|
||||||
const { navigation, isMasterDetail } = this.props;
|
const { isMasterDetail } = this.props;
|
||||||
try {
|
try {
|
||||||
let params = {};
|
let params = {};
|
||||||
const result = await Services.getRoomInfo(item._id);
|
const result = await Services.getRoomInfo(item._id);
|
||||||
|
@ -335,10 +335,7 @@ class TeamChannelsView extends React.Component<ITeamChannelsViewProps, ITeamChan
|
||||||
teamId: result.room.teamId
|
teamId: result.room.teamId
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (isMasterDetail) {
|
goRoom({ item: params, isMasterDetail, popToRoot: !!isMasterDetail });
|
||||||
navigation.pop();
|
|
||||||
}
|
|
||||||
goRoom({ item: params, isMasterDetail, navigationMethod: navigation.push });
|
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
if (e.data.error === 'not-allowed') {
|
if (e.data.error === 'not-allowed') {
|
||||||
showErrorAlert(I18n.t('error-not-allowed'));
|
showErrorAlert(I18n.t('error-not-allowed'));
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
import { expect } from 'detox';
|
||||||
|
|
||||||
|
import data from '../../data';
|
||||||
|
import { navigateToLogin, login, sleep, tapBack } from '../../helpers/app';
|
||||||
|
import { sendMessage, post } from '../../helpers/data_setup';
|
||||||
|
|
||||||
|
describe('InApp Notification', () => {
|
||||||
|
let dmCreatedRid: string;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||||
|
await navigateToLogin();
|
||||||
|
await login(data.users.regular.username, data.users.regular.password);
|
||||||
|
const result = await post(`im.create`, { username: data.users.alternate.username });
|
||||||
|
dmCreatedRid = result.data.room.rid;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('receive in RoomsListView', () => {
|
||||||
|
const text = 'Message in DM';
|
||||||
|
it('should have rooms list screen', async () => {
|
||||||
|
await expect(element(by.id('rooms-list-view'))).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should send direct message from user alternate to user regular', async () => {
|
||||||
|
await sleep(1000);
|
||||||
|
await sendMessage(data.users.alternate, dmCreatedRid, text);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should tap on InApp Notification', async () => {
|
||||||
|
await waitFor(element(by.id(`in-app-notification-${text}`)))
|
||||||
|
.toExist()
|
||||||
|
.withTimeout(2000);
|
||||||
|
await sleep(500);
|
||||||
|
await element(by.id(`in-app-notification-${text}`)).tap();
|
||||||
|
await sleep(500);
|
||||||
|
await expect(element(by.id('room-header'))).toExist();
|
||||||
|
await expect(element(by.id(`room-view-title-${data.users.alternate.username}`))).toExist();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('receive in another room', () => {
|
||||||
|
const text = 'Another msg';
|
||||||
|
it('should back to RoomsListView and open the channel Detox Public', async () => {
|
||||||
|
await tapBack();
|
||||||
|
await sleep(500);
|
||||||
|
await element(by.id(`rooms-list-view-item-${data.userRegularChannels.detoxpublic.name}`)).tap();
|
||||||
|
await waitFor(element(by.id('room-view')))
|
||||||
|
.toBeVisible()
|
||||||
|
.withTimeout(5000);
|
||||||
|
await expect(element(by.id(`room-view-title-${data.userRegularChannels.detoxpublic.name}`))).toExist();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should receive and tap InAppNotification in another room', async () => {
|
||||||
|
await sendMessage(data.users.alternate, dmCreatedRid, text);
|
||||||
|
await waitFor(element(by.id(`in-app-notification-${text}`)))
|
||||||
|
.toExist()
|
||||||
|
.withTimeout(2000);
|
||||||
|
await sleep(500);
|
||||||
|
await element(by.id(`in-app-notification-${text}`)).tap();
|
||||||
|
await sleep(500);
|
||||||
|
await expect(element(by.id('room-header'))).toExist();
|
||||||
|
await expect(element(by.id(`room-view-title-${data.users.alternate.username}`))).toExist();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should back to RoomsListView', async () => {
|
||||||
|
await tapBack();
|
||||||
|
await sleep(500);
|
||||||
|
await expect(element(by.id('rooms-list-view'))).toBeVisible();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -200,7 +200,7 @@ describe('Room', () => {
|
||||||
const expectThreadMessages = async (message: string) => {
|
const expectThreadMessages = async (message: string) => {
|
||||||
await waitFor(element(by.id('room-view-title-thread 1')))
|
await waitFor(element(by.id('room-view-title-thread 1')))
|
||||||
.toExist()
|
.toExist()
|
||||||
.withTimeout(5000);
|
.withTimeout(10000);
|
||||||
await waitFor(element(by[textMatcher](message)).atIndex(0))
|
await waitFor(element(by[textMatcher](message)).atIndex(0))
|
||||||
.toExist()
|
.toExist()
|
||||||
.withTimeout(10000);
|
.withTimeout(10000);
|
||||||
|
|
|
@ -199,6 +199,14 @@ describe('Team', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add existing channel to team', async () => {
|
it('should add existing channel to team', async () => {
|
||||||
|
await navigateToRoom(team);
|
||||||
|
await waitFor(element(by.id('room-view-header-team-channels')))
|
||||||
|
.toExist()
|
||||||
|
.withTimeout(5000);
|
||||||
|
await element(by.id('room-view-header-team-channels')).tap();
|
||||||
|
await waitFor(element(by.id('team-channels-view')))
|
||||||
|
.toExist()
|
||||||
|
.withTimeout(5000);
|
||||||
await element(by.id('team-channels-view-create')).tap();
|
await element(by.id('team-channels-view-create')).tap();
|
||||||
await waitFor(element(by.id('add-channel-team-view')))
|
await waitFor(element(by.id('add-channel-team-view')))
|
||||||
.toExist()
|
.toExist()
|
||||||
|
|
Loading…
Reference in New Issue