[MM-58561] Calls: Add stop recording confirmation; update call screen (#8007)
* add rec confirmation; update call screen * add EnableTranscriptions to dep array * remove unneeded asyncs * properly center title; fix horizontal spacing for title buttons * cleanup
This commit is contained in:
parent
b8c088cc70
commit
53b011068e
6 changed files with 112 additions and 47 deletions
|
|
@ -336,6 +336,54 @@ export const recordingAlert = (isHost: boolean, transcriptionsEnabled: boolean,
|
|||
);
|
||||
};
|
||||
|
||||
export const stopRecordingConfirmationAlert = (intl: IntlShape, enableTranscriptions: boolean) => {
|
||||
const {formatMessage} = intl;
|
||||
|
||||
const asyncAlert = async () => new Promise((resolve) => {
|
||||
let title = formatMessage({
|
||||
id: 'mobile.calls_host_rec_stop_title',
|
||||
defaultMessage: 'Stop recording',
|
||||
});
|
||||
let body = formatMessage({
|
||||
id: 'mobile.calls_host_rec_stop_body',
|
||||
defaultMessage: 'The call recording will be processed and posted in the call thread. Are you sure you want to stop the recording?',
|
||||
});
|
||||
|
||||
if (enableTranscriptions) {
|
||||
title = formatMessage({
|
||||
id: 'mobile.calls_host_rec_trans_stop_title',
|
||||
defaultMessage: 'Stop recording and transcription',
|
||||
});
|
||||
body = formatMessage({
|
||||
id: 'mobile.calls_host_rec_trans_stop_body',
|
||||
defaultMessage: 'The call recording and transcription files will be processed and posted in the call thread. Are you sure you want to stop the recording and transcription?',
|
||||
});
|
||||
}
|
||||
|
||||
Alert.alert(
|
||||
title,
|
||||
body,
|
||||
[{
|
||||
text: formatMessage({
|
||||
id: 'mobile.calls_cancel',
|
||||
defaultMessage: 'Cancel',
|
||||
}),
|
||||
onPress: () => resolve(false),
|
||||
style: 'cancel',
|
||||
}, {
|
||||
text: formatMessage({
|
||||
id: 'mobile.calls_host_rec_stop_confirm',
|
||||
defaultMessage: 'Stop recording',
|
||||
}),
|
||||
onPress: () => resolve(true),
|
||||
style: 'destructive',
|
||||
}],
|
||||
);
|
||||
});
|
||||
|
||||
return asyncAlert();
|
||||
};
|
||||
|
||||
export const needsRecordingWillBePostedAlert = () => {
|
||||
recordingWillBePostedLock = false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,10 +10,11 @@ import {toMilliseconds} from '@utils/datetime';
|
|||
type CallDurationProps = {
|
||||
style: StyleProp<TextStyle>;
|
||||
value: number;
|
||||
truncateWhenLong?: boolean;
|
||||
updateIntervalInSeconds?: number;
|
||||
}
|
||||
|
||||
const CallDuration = ({value, style, updateIntervalInSeconds}: CallDurationProps) => {
|
||||
const CallDuration = ({value, style, truncateWhenLong, updateIntervalInSeconds}: CallDurationProps) => {
|
||||
const getCallDuration = () => {
|
||||
const now = moment();
|
||||
const startTime = moment(value);
|
||||
|
|
@ -27,6 +28,9 @@ const CallDuration = ({value, style, updateIntervalInSeconds}: CallDurationProps
|
|||
const minutes = totalMinutes % 60;
|
||||
const hours = Math.floor(totalMinutes / 60);
|
||||
|
||||
if (hours > 0 && truncateWhenLong) {
|
||||
return `${hours}:${minutes < 10 ? '0' + minutes : minutes}`;
|
||||
}
|
||||
if (hours > 0) {
|
||||
return `${hours}:${minutes < 10 ? '0' + minutes : minutes}:${seconds < 10 ? '0' + seconds : seconds}`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,19 +18,13 @@ const styles = StyleSheet.create({
|
|||
borderRadius: 4,
|
||||
},
|
||||
loading: {
|
||||
paddingLeft: 8,
|
||||
paddingRight: 8,
|
||||
marginRight: 8,
|
||||
padding: 6,
|
||||
color: 'white',
|
||||
height: 34,
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.16)',
|
||||
},
|
||||
recording: {
|
||||
paddingLeft: 8,
|
||||
paddingRight: 8,
|
||||
marginRight: 8,
|
||||
padding: 6,
|
||||
color: 'white',
|
||||
height: 34,
|
||||
backgroundColor: '#D24B4E',
|
||||
},
|
||||
text: {
|
||||
|
|
@ -69,19 +63,13 @@ const CallsBadge = ({type}: Props) => {
|
|||
const isRec = type === CallsBadgeType.Rec;
|
||||
const isParticipant = !(isLoading || isRec);
|
||||
|
||||
const text = isLoading || isRec ? (
|
||||
<FormattedText
|
||||
id={'mobile.calls_rec'}
|
||||
defaultMessage={'rec'}
|
||||
style={[styles.text, styles.recordingText]}
|
||||
/>
|
||||
) : (
|
||||
const text = isParticipant ? (
|
||||
<FormattedText
|
||||
id={'mobile.calls_host'}
|
||||
defaultMessage={'host'}
|
||||
style={[styles.text, styles.recordingText]}
|
||||
/>
|
||||
);
|
||||
) : null;
|
||||
|
||||
const containerStyles = [
|
||||
styles.container,
|
||||
|
|
@ -92,13 +80,13 @@ const CallsBadge = ({type}: Props) => {
|
|||
return (
|
||||
<View style={containerStyles}>
|
||||
{
|
||||
isLoading && <Loading/>
|
||||
isLoading && <Loading size={16}/>
|
||||
}
|
||||
{
|
||||
isRec &&
|
||||
<CompassIcon
|
||||
name={'record-circle-outline'}
|
||||
size={12}
|
||||
size={16}
|
||||
color={styles.text.color}
|
||||
/>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,12 @@ import {RTCView} from 'react-native-webrtc';
|
|||
|
||||
import {muteMyself, unmuteMyself} from '@calls/actions';
|
||||
import {leaveCallConfirmation, startCallRecording, stopCallRecording} from '@calls/actions/calls';
|
||||
import {recordingAlert, recordingWillBePostedAlert, recordingErrorAlert} from '@calls/alerts';
|
||||
import {
|
||||
recordingAlert,
|
||||
recordingWillBePostedAlert,
|
||||
recordingErrorAlert,
|
||||
stopRecordingConfirmationAlert,
|
||||
} from '@calls/alerts';
|
||||
import {AudioDeviceButton} from '@calls/components/audio_device_button';
|
||||
import CallDuration from '@calls/components/call_duration';
|
||||
import CallNotification from '@calls/components/call_notification';
|
||||
|
|
@ -123,8 +128,24 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: CallsTheme) => ({
|
|||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
height: 56,
|
||||
height: 52,
|
||||
gap: 8,
|
||||
paddingHorizontal: 24,
|
||||
},
|
||||
headerLeft: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'center',
|
||||
width: 93,
|
||||
gap: 8,
|
||||
},
|
||||
headerLeftRightRecOff: {
|
||||
width: 57,
|
||||
},
|
||||
time: {
|
||||
color: theme.buttonColor,
|
||||
...typography('Heading', 200),
|
||||
width: 56,
|
||||
},
|
||||
headerPortraitSpacer: {
|
||||
height: 12,
|
||||
|
|
@ -139,22 +160,11 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: CallsTheme) => ({
|
|||
headerLandscapeNoControls: {
|
||||
top: -1000,
|
||||
},
|
||||
time: {
|
||||
color: theme.buttonColor,
|
||||
...typography('Heading', 200),
|
||||
width: 56,
|
||||
marginLeft: 24,
|
||||
marginRight: 8,
|
||||
marginVertical: 2,
|
||||
},
|
||||
collapseIconContainer: {
|
||||
display: 'flex',
|
||||
headerRight: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: 48,
|
||||
height: 48,
|
||||
marginLeft: 24,
|
||||
marginRight: 8,
|
||||
justifyContent: 'flex-end',
|
||||
width: 93,
|
||||
},
|
||||
collapseIcon: {
|
||||
color: changeOpacity(theme.buttonColor, 0.56),
|
||||
|
|
@ -416,6 +426,12 @@ const CallScreen = ({
|
|||
}, [currentCall?.channelId, currentCall?.serverUrl]);
|
||||
|
||||
const stopRecording = useCallback(async () => {
|
||||
const stop = await stopRecordingConfirmationAlert(intl, EnableTranscriptions);
|
||||
|
||||
if (!stop) {
|
||||
return;
|
||||
}
|
||||
|
||||
Keyboard.dismiss();
|
||||
await dismissBottomSheet();
|
||||
if (!currentCall) {
|
||||
|
|
@ -423,7 +439,7 @@ const CallScreen = ({
|
|||
}
|
||||
|
||||
await stopCallRecording(currentCall.serverUrl, currentCall.channelId);
|
||||
}, [currentCall?.channelId, currentCall?.serverUrl]);
|
||||
}, [currentCall?.channelId, currentCall?.serverUrl, EnableTranscriptions]);
|
||||
|
||||
const toggleCC = useCallback(async () => {
|
||||
Keyboard.dismiss();
|
||||
|
|
@ -506,6 +522,7 @@ const CallScreen = ({
|
|||
showStopRecording &&
|
||||
<SlideUpPanelItem
|
||||
leftIcon={'record-square-outline'}
|
||||
leftIconStyles={style.denimDND}
|
||||
onPress={stopRecording}
|
||||
text={stopRecordingOptionTitle}
|
||||
textStyles={style.denimDND}
|
||||
|
|
@ -690,13 +707,16 @@ const CallScreen = ({
|
|||
isLandscape && !showControlsInLandscape && style.headerLandscapeNoControls,
|
||||
]}
|
||||
>
|
||||
{waitingForRecording && <CallsBadge type={CallsBadgeType.Waiting}/>}
|
||||
{recording && <CallsBadge type={CallsBadgeType.Rec}/>}
|
||||
<CallDuration
|
||||
style={style.time}
|
||||
value={currentCall.startTime}
|
||||
updateIntervalInSeconds={1}
|
||||
/>
|
||||
<View style={[style.headerLeft, !(waitingForRecording || recording) && style.headerLeftRightRecOff]}>
|
||||
{waitingForRecording && <CallsBadge type={CallsBadgeType.Waiting}/>}
|
||||
{recording && <CallsBadge type={CallsBadgeType.Rec}/>}
|
||||
<CallDuration
|
||||
style={style.time}
|
||||
value={currentCall.startTime}
|
||||
updateIntervalInSeconds={1}
|
||||
truncateWhenLong={true}
|
||||
/>
|
||||
</View>
|
||||
<HeaderCenter
|
||||
raisedHands={raisedHands}
|
||||
sessionId={currentCall.mySessionId}
|
||||
|
|
@ -706,7 +726,7 @@ const CallScreen = ({
|
|||
/>
|
||||
<Pressable
|
||||
onPress={collapse}
|
||||
style={style.collapseIconContainer}
|
||||
style={[style.headerRight, !(waitingForRecording || recording) && style.headerLeftRightRecOff]}
|
||||
>
|
||||
<CompassIcon
|
||||
name='arrow-collapse'
|
||||
|
|
@ -920,7 +940,7 @@ const CallScreen = ({
|
|||
<CompassIcon
|
||||
name='record-square-outline'
|
||||
size={32}
|
||||
style={[style.buttonIcon, isLandscape && style.buttonIconLandscape]}
|
||||
style={[style.buttonIcon, style.hangUpIcon, isLandscape && style.buttonIconLandscape]}
|
||||
/>
|
||||
<Text style={style.buttonText}>{stopRecordingOptionTitle}</Text>
|
||||
</Pressable>
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: CallsTheme) => ({
|
|||
flexDirection: 'row',
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
raisedHandBanner: {
|
||||
flexDirection: 'row',
|
||||
|
|
|
|||
|
|
@ -470,9 +470,14 @@
|
|||
"mobile.calls_host_rec": "You are recording this meeting. Consider letting everyone know that this meeting is being recorded.",
|
||||
"mobile.calls_host_rec_error": "Please try to record again. You can also contact your system admin for troubleshooting help.",
|
||||
"mobile.calls_host_rec_error_title": "Something went wrong with the recording",
|
||||
"mobile.calls_host_rec_stop_body": "The call recording will be processed and posted in the call thread. Are you sure you want to stop the recording?",
|
||||
"mobile.calls_host_rec_stop_confirm": "Stop recording",
|
||||
"mobile.calls_host_rec_stop_title": "Stop recording",
|
||||
"mobile.calls_host_rec_stopped": "You can find the recording in this call's chat thread once it's finished processing.",
|
||||
"mobile.calls_host_rec_stopped_title": "Recording has stopped. Processing...",
|
||||
"mobile.calls_host_rec_title": "You are recording",
|
||||
"mobile.calls_host_rec_trans_stop_body": "The call recording and transcription files will be processed and posted in the call thread. Are you sure you want to stop the recording and transcription?",
|
||||
"mobile.calls_host_rec_trans_stop_title": "Stop recording and transcription",
|
||||
"mobile.calls_host_transcription": "Consider letting everyone know that this meeting is being recorded and transcribed.",
|
||||
"mobile.calls_host_transcription_title": "Recording and transcription has started",
|
||||
"mobile.calls_incoming_dm": "<b>{name}</b> is inviting you to a call",
|
||||
|
|
@ -514,7 +519,6 @@
|
|||
"mobile.calls_raise_hand": "Raise hand",
|
||||
"mobile.calls_raised_hand": "<bold>{name} {num, plural, =0 {} other {+# more }}</bold>raised a hand",
|
||||
"mobile.calls_react": "React",
|
||||
"mobile.calls_rec": "rec",
|
||||
"mobile.calls_record": "Record",
|
||||
"mobile.calls_recording_start_in_progress": "A recording is already in progress.",
|
||||
"mobile.calls_recording_start_no_permissions": "You don't have permissions to start a recording. Please ask the call host to start a recording.",
|
||||
|
|
|
|||
Loading…
Reference in a new issue