diff --git a/app/products/calls/alerts.ts b/app/products/calls/alerts.ts index 0811f7c309d..20007e4fa9c 100644 --- a/app/products/calls/alerts.ts +++ b/app/products/calls/alerts.ts @@ -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; }; diff --git a/app/products/calls/components/call_duration.tsx b/app/products/calls/components/call_duration.tsx index b68cc3b494e..6fc8dfeda2d 100644 --- a/app/products/calls/components/call_duration.tsx +++ b/app/products/calls/components/call_duration.tsx @@ -10,10 +10,11 @@ import {toMilliseconds} from '@utils/datetime'; type CallDurationProps = { style: StyleProp; 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}`; } diff --git a/app/products/calls/components/calls_badge.tsx b/app/products/calls/components/calls_badge.tsx index 21d1970efe9..33bd0bdde4d 100644 --- a/app/products/calls/components/calls_badge.tsx +++ b/app/products/calls/components/calls_badge.tsx @@ -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 ? ( - - ) : ( + const text = isParticipant ? ( - ); + ) : null; const containerStyles = [ styles.container, @@ -92,13 +80,13 @@ const CallsBadge = ({type}: Props) => { return ( { - isLoading && + isLoading && } { isRec && } diff --git a/app/products/calls/screens/call_screen/call_screen.tsx b/app/products/calls/screens/call_screen/call_screen.tsx index fa9b0fd8550..d2c6ed99813 100644 --- a/app/products/calls/screens/call_screen/call_screen.tsx +++ b/app/products/calls/screens/call_screen/call_screen.tsx @@ -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 && - {waitingForRecording && } - {recording && } - + + {waitingForRecording && } + {recording && } + + {stopRecordingOptionTitle} diff --git a/app/products/calls/screens/call_screen/header_center.tsx b/app/products/calls/screens/call_screen/header_center.tsx index 732d443cbbe..a648d12d661 100644 --- a/app/products/calls/screens/call_screen/header_center.tsx +++ b/app/products/calls/screens/call_screen/header_center.tsx @@ -28,6 +28,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: CallsTheme) => ({ flexDirection: 'row', flex: 1, justifyContent: 'center', + alignItems: 'center', }, raisedHandBanner: { flexDirection: 'row', diff --git a/assets/base/i18n/en.json b/assets/base/i18n/en.json index a0e1baafcbf..d9449493f8f 100644 --- a/assets/base/i18n/en.json +++ b/assets/base/i18n/en.json @@ -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": "{name} is inviting you to a call", @@ -514,7 +519,6 @@ "mobile.calls_raise_hand": "Raise hand", "mobile.calls_raised_hand": "{name} {num, plural, =0 {} other {+# more }}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.",