MM-52949 - Calls: Blank screen after ending a call and exiting its thread (#7380)

* remove thread and call screen

* simplify how we remove the call screen

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
Christopher Poile 2023-06-12 08:55:48 -04:00 committed by GitHub
parent 61a83cf423
commit dbd943ab8d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 26 additions and 39 deletions

View file

@ -89,6 +89,13 @@ jest.mock('@queries/servers/thread', () => ({
}));
jest.mock('@calls/alerts');
jest.mock('react-native-navigation', () => ({
Navigation: {
pop: jest.fn(() => Promise.resolve({
catch: jest.fn(),
})),
},
}));
const addFakeCall = (serverUrl: string, channelId: string) => {
const call = {

View file

@ -3,7 +3,6 @@
import {Alert} from 'react-native';
import InCallManager from 'react-native-incall-manager';
import {Navigation} from 'react-native-navigation';
import {forceLogoutIfNecessary} from '@actions/remote/session';
import {updateThreadFollowing} from '@actions/remote/thread';
@ -24,7 +23,7 @@ import {
getCurrentCall,
getChannelsWithCalls,
} from '@calls/state';
import {General, Preferences, Screens} from '@constants';
import {General, Preferences} from '@constants';
import Calls from '@constants/calls';
import DatabaseManager from '@database/manager';
import {getTeammateNameDisplaySetting} from '@helpers/api/preference';
@ -34,8 +33,6 @@ import {queryDisplayNamePreferences} from '@queries/servers/preference';
import {getConfig, getLicense} from '@queries/servers/system';
import {getThreadById} from '@queries/servers/thread';
import {getCurrentUser, getUserById} from '@queries/servers/user';
import {dismissAllModalsAndPopToScreen} from '@screens/navigation';
import NavigationStore from '@store/navigation_store';
import {getFullErrorMessage} from '@utils/errors';
import {logDebug} from '@utils/log';
import {displayUsername, getUserIdFromChannelName, isSystemAdmin} from '@utils/user';
@ -271,16 +268,6 @@ export const leaveCall = () => {
}
};
export const leaveCallPopCallScreen = async () => {
leaveCall();
// Need to pop the call screen, if it's somewhere in the stack.
if (NavigationStore.getScreensInStack().includes(Screens.CALL)) {
await dismissAllModalsAndPopToScreen(Screens.CALL, 'Call');
Navigation.pop(Screens.CALL).catch(() => null);
}
};
export const muteMyself = () => {
if (connection) {
connection.mute();
@ -459,7 +446,7 @@ export const handleCallsSlashCommand = async (value: string, serverUrl: string,
return {handled: true};
case 'leave':
if (getCurrentCall()?.channelId === channelId) {
await leaveCallPopCallScreen();
await leaveCall();
return {handled: true};
}
return {

View file

@ -3,8 +3,7 @@
import {Alert} from 'react-native';
import {hasMicrophonePermission, joinCall, unmuteMyself} from '@calls/actions';
import {leaveCallPopCallScreen} from '@calls/actions/calls';
import {hasMicrophonePermission, joinCall, leaveCall, unmuteMyself} from '@calls/actions';
import {hasBluetoothPermission} from '@calls/actions/permissions';
import {
getCallsConfig,
@ -265,7 +264,7 @@ export const recordingAlert = (isHost: boolean, intl: IntlShape) => {
defaultMessage: 'Leave',
}),
onPress: async () => {
await leaveCallPopCallScreen();
await leaveCall();
},
style: 'destructive',
},

View file

@ -4,7 +4,6 @@
import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {useIntl} from 'react-intl';
import {
DeviceEventEmitter,
Keyboard,
type LayoutChangeEvent,
type LayoutRectangle,
@ -40,7 +39,7 @@ import {getHandsRaised, makeCallsTheme, sortParticipants} from '@calls/utils';
import CompassIcon from '@components/compass_icon';
import FormattedText from '@components/formatted_text';
import SlideUpPanelItem, {ITEM_HEIGHT} from '@components/slide_up_panel_item';
import {Calls, Preferences, Screens, WebsocketEvents} from '@constants';
import {Calls, Preferences, Screens} from '@constants';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import DatabaseManager from '@database/manager';
@ -56,7 +55,6 @@ import {
popTopScreen,
setScreensOrientation,
} from '@screens/navigation';
import NavigationStore from '@store/navigation_store';
import {freezeOtherScreens} from '@utils/gallery';
import {bottomSheetSnapPoint} from '@utils/helpers';
import {mergeNavigationOptions} from '@utils/navigation';
@ -504,16 +502,6 @@ const CallScreen = ({
popTopScreen(componentId);
});
useEffect(() => {
const listener = DeviceEventEmitter.addListener(WebsocketEvents.CALLS_CALL_END, ({channelId}) => {
if (channelId === currentCall?.channelId && NavigationStore.getVisibleScreen() === componentId) {
Navigation.pop(componentId);
}
});
return () => listener.remove();
}, []);
useEffect(() => {
const didDismissListener = Navigation.events().registerComponentDidDisappearListener(async ({componentId: screen}) => {
if (componentId === screen) {
@ -550,13 +538,6 @@ const CallScreen = ({
}, []);
if (!currentCall || !myParticipant) {
// Note: this happens because the screen is "rendered", even after the screen has been popped, and the
// currentCall will have already been set to null when those extra renders run. We probably don't ever need
// to pop, but just in case.
if (NavigationStore.getVisibleScreen() === componentId) {
// ignore the error because the call screen has likely already been popped async
Navigation.pop(componentId).catch(() => null);
}
return null;
}

View file

@ -75,6 +75,14 @@ jest.mock('@queries/servers/thread', () => ({
})),
}));
jest.mock('react-native-navigation', () => ({
Navigation: {
pop: jest.fn(() => Promise.resolve({
catch: jest.fn(),
})),
},
}));
const call1: Call = {
participants: {
'user-1': {id: 'user-1', muted: false, raisedHand: 0},

View file

@ -2,6 +2,7 @@
// See LICENSE.txt for license information.
import {mosThreshold} from '@mattermost/calls/lib/rtc_monitor';
import {Navigation} from 'react-native-navigation';
import {updateThreadFollowing} from '@actions/remote/thread';
import {needsRecordingAlert} from '@calls/alerts';
@ -27,7 +28,7 @@ import {
DefaultCurrentCall,
type ReactionStreamEmoji,
} from '@calls/types/calls';
import {Calls} from '@constants';
import {Calls, Screens} from '@constants';
import DatabaseManager from '@database/manager';
import {getChannelById} from '@queries/servers/channel';
import {getThreadById} from '@queries/servers/thread';
@ -217,6 +218,10 @@ export const newCurrentCall = (serverUrl: string, channelId: string, myUserId: s
export const myselfLeftCall = () => {
setCurrentCall(null);
// Remove the call screen, and in some situations it needs to be removed twice before actually being removed.
Navigation.pop(Screens.CALL).catch(() => null);
Navigation.pop(Screens.CALL).catch(() => null);
};
export const callStarted = async (serverUrl: string, call: Call) => {