MM-54323 - Calls: Incoming call from different server (#7646)
* refactor; tried to clarify more_messages; new design * adjust more_messages text spacing * small fix for height with incoming call on current channel * move calls-specific code in the calls product behind a hook * show servername for notifications from other servers * if >1 active servers, always show server name, otherwise don't * add height of notification bar in measurements --------- Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
parent
94a910303b
commit
f0334d8c0e
3 changed files with 68 additions and 12 deletions
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useCallback, useEffect} from 'react';
|
||||
import React, {useCallback, useEffect, useState} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {Pressable, Text, View} from 'react-native';
|
||||
|
||||
|
|
@ -18,11 +18,14 @@ import {useServerUrl} from '@context/server';
|
|||
import {useTheme} from '@context/theme';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import WebsocketManager from '@managers/websocket_manager';
|
||||
import {getServerDisplayName} from '@queries/app/servers';
|
||||
import ChannelMembershipModel from '@typings/database/models/servers/channel_membership';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {typography} from '@utils/typography';
|
||||
import {displayUsername} from '@utils/user';
|
||||
|
||||
import type ServersModel from '@typings/database/models/app/servers';
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
||||
outerContainer: {
|
||||
borderRadius: 8,
|
||||
|
|
@ -39,6 +42,9 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
|||
shadowRadius: 4,
|
||||
elevation: 4,
|
||||
},
|
||||
outerContainerServerName: {
|
||||
height: CALL_NOTIFICATION_BAR_HEIGHT + 8,
|
||||
},
|
||||
innerContainer: {
|
||||
flexDirection: 'row',
|
||||
width: '100%',
|
||||
|
|
@ -71,6 +77,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
|||
},
|
||||
textContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
marginLeft: 8,
|
||||
},
|
||||
text: {
|
||||
|
|
@ -81,6 +88,11 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
|||
...typography('Body', 100, 'SemiBold'),
|
||||
lineHeight: 20,
|
||||
},
|
||||
textServerName: {
|
||||
...typography('Heading', 25),
|
||||
color: changeOpacity(theme.buttonColor, 0.72),
|
||||
textTransform: 'uppercase',
|
||||
},
|
||||
dismissContainer: {
|
||||
alignItems: 'center',
|
||||
width: 32,
|
||||
|
|
@ -93,6 +105,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
|||
}));
|
||||
|
||||
type Props = {
|
||||
servers: ServersModel[];
|
||||
incomingCall: IncomingCallNotification;
|
||||
currentUserId: string;
|
||||
teammateNameDisplay: string;
|
||||
|
|
@ -101,6 +114,7 @@ type Props = {
|
|||
}
|
||||
|
||||
export const CallNotification = ({
|
||||
servers,
|
||||
incomingCall,
|
||||
currentUserId,
|
||||
teammateNameDisplay,
|
||||
|
|
@ -111,6 +125,8 @@ export const CallNotification = ({
|
|||
const serverUrl = useServerUrl();
|
||||
const theme = useTheme();
|
||||
const style = getStyleSheet(theme);
|
||||
const [serverName, setServerName] = useState('');
|
||||
const moreThanOneServer = servers.length > 1;
|
||||
|
||||
useEffect(() => {
|
||||
const channelMembers = members?.filter((m) => m.userId !== currentUserId);
|
||||
|
|
@ -119,13 +135,24 @@ export const CallNotification = ({
|
|||
}
|
||||
}, []);
|
||||
|
||||
// We only need to getServerDisplayName once
|
||||
useEffect(() => {
|
||||
async function getName() {
|
||||
setServerName(await getServerDisplayName(incomingCall.serverUrl));
|
||||
}
|
||||
|
||||
if (moreThanOneServer) {
|
||||
getName();
|
||||
}
|
||||
}, [moreThanOneServer, incomingCall.serverUrl]);
|
||||
|
||||
const onContainerPress = useCallback(async () => {
|
||||
if (serverUrl !== incomingCall.serverUrl) {
|
||||
if (incomingCall.serverUrl !== serverUrl) {
|
||||
await DatabaseManager.setActiveServerDatabase(incomingCall.serverUrl);
|
||||
await WebsocketManager.initializeClient(incomingCall.serverUrl);
|
||||
}
|
||||
switchToChannelById(incomingCall.serverUrl, incomingCall.channelID);
|
||||
}, [serverUrl, incomingCall]);
|
||||
}, [incomingCall, serverUrl]);
|
||||
|
||||
const onDismissPress = useCallback(() => {
|
||||
removeIncomingCall(serverUrl, incomingCall.callID, incomingCall.channelID);
|
||||
|
|
@ -143,7 +170,7 @@ export const CallNotification = ({
|
|||
name: displayUsername(incomingCall.callerModel, intl.locale, teammateNameDisplay),
|
||||
}}
|
||||
style={style.text}
|
||||
numberOfLines={2}
|
||||
numberOfLines={1}
|
||||
ellipsizeMode={'tail'}
|
||||
/>
|
||||
);
|
||||
|
|
@ -158,14 +185,14 @@ export const CallNotification = ({
|
|||
num: (members?.length || 2) - 1,
|
||||
}}
|
||||
style={style.text}
|
||||
numberOfLines={2}
|
||||
numberOfLines={1}
|
||||
ellipsizeMode={'tail'}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={[style.outerContainer]}>
|
||||
<View style={[style.outerContainer, moreThanOneServer && style.outerContainerServerName]}>
|
||||
<Pressable
|
||||
style={[style.innerContainer, onCallsScreen && style.innerOnCallsScreen]}
|
||||
onPress={onContainerPress}
|
||||
|
|
@ -180,6 +207,11 @@ export const CallNotification = ({
|
|||
</View>
|
||||
<View style={style.textContainer}>
|
||||
{message}
|
||||
{moreThanOneServer &&
|
||||
<Text style={style.textServerName}>
|
||||
{serverName}
|
||||
</Text>
|
||||
}
|
||||
</View>
|
||||
<Pressable onPress={onDismissPress}>
|
||||
<View style={style.dismissContainer}>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import withObservables from '@nozbe/with-observables';
|
|||
import {of as of$} from 'rxjs';
|
||||
import {distinctUntilChanged, switchMap} from 'rxjs/operators';
|
||||
|
||||
import {observeAllActiveServers} from '@app/queries/app/servers';
|
||||
import {CallNotification} from '@calls/components/call_notification/call_notification';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {observeChannelMembers} from '@queries/servers/channel';
|
||||
|
|
@ -33,6 +34,7 @@ const enhanced = withObservables(['incomingCall'], ({incomingCall}: OwnProps) =>
|
|||
);
|
||||
|
||||
return {
|
||||
servers: observeAllActiveServers(),
|
||||
currentUserId,
|
||||
teammateNameDisplay,
|
||||
members,
|
||||
|
|
|
|||
|
|
@ -8,13 +8,26 @@ import {useIntl} from 'react-intl';
|
|||
import {Alert, Platform} from 'react-native';
|
||||
import Permissions from 'react-native-permissions';
|
||||
|
||||
import {CALL_ERROR_BAR_HEIGHT, CALL_NOTIFICATION_BAR_HEIGHT, CURRENT_CALL_BAR_HEIGHT, JOIN_CALL_BAR_HEIGHT} from '@app/constants/view';
|
||||
import {
|
||||
CALL_ERROR_BAR_HEIGHT,
|
||||
CALL_NOTIFICATION_BAR_HEIGHT,
|
||||
CURRENT_CALL_BAR_HEIGHT,
|
||||
JOIN_CALL_BAR_HEIGHT,
|
||||
} from '@app/constants/view';
|
||||
import {initializeVoiceTrack} from '@calls/actions/calls';
|
||||
import {setMicPermissionsGranted, useCallsState, useChannelsWithCalls, useCurrentCall, useGlobalCallsState, useIncomingCalls} from '@calls/state';
|
||||
import {
|
||||
setMicPermissionsGranted,
|
||||
useCallsState,
|
||||
useChannelsWithCalls,
|
||||
useCurrentCall,
|
||||
useGlobalCallsState,
|
||||
useIncomingCalls,
|
||||
} from '@calls/state';
|
||||
import {errorAlert} from '@calls/utils';
|
||||
import {useServerUrl} from '@context/server';
|
||||
import {useAppState} from '@hooks/device';
|
||||
import NetworkManager from '@managers/network_manager';
|
||||
import {queryAllActiveServers} from '@queries/app/servers';
|
||||
import {getFullErrorMessage} from '@utils/errors';
|
||||
|
||||
import type {Client} from '@client/rest';
|
||||
|
|
@ -110,26 +123,35 @@ export const usePermissionsChecker = (micPermissionsGranted: boolean) => {
|
|||
}, [appState]);
|
||||
};
|
||||
|
||||
export const useCallsAdjustment = (serverUrl: string, channelId: string) => {
|
||||
export const useCallsAdjustment = (serverUrl: string, channelId: string): number => {
|
||||
const incomingCalls = useIncomingCalls().incomingCalls;
|
||||
const channelsWithCalls = useChannelsWithCalls(serverUrl);
|
||||
const callsState = useCallsState(serverUrl);
|
||||
const globalCallsState = useGlobalCallsState();
|
||||
const currentCall = useCurrentCall();
|
||||
const [numServers, setNumServers] = useState(1);
|
||||
const dismissed = Boolean(callsState.calls[channelId]?.dismissed[callsState.myUserId]);
|
||||
const inCurrentCall = currentCall?.id === channelId;
|
||||
const joinCallBannerVisible = Boolean(channelsWithCalls[channelId]) && !dismissed && !inCurrentCall;
|
||||
|
||||
useEffect(() => {
|
||||
const getNumServers = async () => {
|
||||
const query = await queryAllActiveServers()?.fetch();
|
||||
setNumServers(query?.length || 0);
|
||||
};
|
||||
getNumServers();
|
||||
}, []);
|
||||
|
||||
// Do we have calls banners?
|
||||
const currentCallBarVisible = Boolean(currentCall);
|
||||
const micPermissionsError = !globalCallsState.micPermissionsGranted && (currentCall && !currentCall.micPermissionsErrorDismissed);
|
||||
const callQualityAlert = Boolean(currentCall?.callQualityAlert);
|
||||
const incomingCallsShowing = incomingCalls.filter((ic) => ic.channelID !== channelId);
|
||||
const callsIncomingAdjustment = (incomingCallsShowing.length * CALL_NOTIFICATION_BAR_HEIGHT) + (incomingCallsShowing.length * 8);
|
||||
const callsAdjustment = (currentCallBarVisible ? CURRENT_CALL_BAR_HEIGHT + 8 : 0) +
|
||||
const notificationBarHeight = CALL_NOTIFICATION_BAR_HEIGHT + (numServers > 1 ? 8 : 0);
|
||||
const callsIncomingAdjustment = (incomingCallsShowing.length * notificationBarHeight) + (incomingCallsShowing.length * 8);
|
||||
return (currentCallBarVisible ? CURRENT_CALL_BAR_HEIGHT + 8 : 0) +
|
||||
(micPermissionsError ? CALL_ERROR_BAR_HEIGHT + 8 : 0) +
|
||||
(callQualityAlert ? CALL_ERROR_BAR_HEIGHT + 8 : 0) +
|
||||
(joinCallBannerVisible ? JOIN_CALL_BAR_HEIGHT + 8 : 0) +
|
||||
callsIncomingAdjustment;
|
||||
return callsAdjustment;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue