[FIX] Preserve voice message if recording is interrupted (#3397)

* 7c25909671

* Minor changes

Co-authored-by: Marco Jakobs <mj@jacotec.de>
This commit is contained in:
Diego Mello 2021-09-23 09:16:23 -03:00 committed by GitHub
parent a52199a49c
commit 30aab71db1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 10 deletions

View File

@ -63,20 +63,24 @@ export default class RecordAudio extends React.PureComponent<IMessageBoxRecordAu
private recording: any; private recording: any;
private LastDuration: number;
constructor(props: IMessageBoxRecordAudioProps) { constructor(props: IMessageBoxRecordAudioProps) {
super(props); super(props);
this.isRecorderBusy = false; this.isRecorderBusy = false;
this.LastDuration = 0;
this.state = { this.state = {
isRecording: false, isRecording: false,
isRecorderActive: false,
recordingDurationMillis: 0 recordingDurationMillis: 0
}; };
} }
componentDidUpdate() { componentDidUpdate() {
const { recordingCallback } = this.props; const { recordingCallback } = this.props;
const { isRecording } = this.state; const { isRecorderActive } = this.state;
recordingCallback(isRecording); recordingCallback(isRecorderActive);
} }
componentWillUnmount() { componentWillUnmount() {
@ -90,6 +94,10 @@ export default class RecordAudio extends React.PureComponent<IMessageBoxRecordAu
return formatTime(Math.floor(recordingDurationMillis / 1000)); return formatTime(Math.floor(recordingDurationMillis / 1000));
} }
get GetLastDuration() {
return formatTime(Math.floor(this.LastDuration / 1000));
}
isRecordingPermissionGranted = async () => { isRecordingPermissionGranted = async () => {
try { try {
const permission = await Audio.getPermissionsAsync(); const permission = await Audio.getPermissionsAsync();
@ -108,17 +116,20 @@ export default class RecordAudio extends React.PureComponent<IMessageBoxRecordAu
isRecording: status.isRecording, isRecording: status.isRecording,
recordingDurationMillis: status.durationMillis recordingDurationMillis: status.durationMillis
}); });
this.LastDuration = status.durationMillis;
}; };
startRecordingAudio = async () => { startRecordingAudio = async () => {
logEvent(events.ROOM_AUDIO_RECORD); logEvent(events.ROOM_AUDIO_RECORD);
if (!this.isRecorderBusy) { if (!this.isRecorderBusy) {
this.isRecorderBusy = true; this.isRecorderBusy = true;
this.LastDuration = 0;
try { try {
const canRecord = await this.isRecordingPermissionGranted(); const canRecord = await this.isRecordingPermissionGranted();
if (canRecord) { if (canRecord) {
await Audio.setAudioModeAsync(RECORDING_MODE); await Audio.setAudioModeAsync(RECORDING_MODE);
this.setState({ isRecorderActive: true });
this.recording = new Audio.Recording(); this.recording = new Audio.Recording();
await this.recording.prepareToRecordAsync(RECORDING_SETTINGS); await this.recording.prepareToRecordAsync(RECORDING_SETTINGS);
this.recording.setOnRecordingStatusUpdate(this.onRecordingStatusUpdate); this.recording.setOnRecordingStatusUpdate(this.onRecordingStatusUpdate);
@ -159,7 +170,7 @@ export default class RecordAudio extends React.PureComponent<IMessageBoxRecordAu
} catch (error) { } catch (error) {
logEvent(events.ROOM_AUDIO_FINISH_F); logEvent(events.ROOM_AUDIO_FINISH_F);
} }
this.setState({ isRecording: false, recordingDurationMillis: 0 }); this.setState({ isRecording: false, isRecorderActive: false, recordingDurationMillis: 0 });
deactivateKeepAwake(); deactivateKeepAwake();
this.isRecorderBusy = false; this.isRecorderBusy = false;
} }
@ -174,7 +185,7 @@ export default class RecordAudio extends React.PureComponent<IMessageBoxRecordAu
} catch (error) { } catch (error) {
logEvent(events.ROOM_AUDIO_CANCEL_F); logEvent(events.ROOM_AUDIO_CANCEL_F);
} }
this.setState({ isRecording: false, recordingDurationMillis: 0 }); this.setState({ isRecording: false, isRecorderActive: false, recordingDurationMillis: 0 });
deactivateKeepAwake(); deactivateKeepAwake();
this.isRecorderBusy = false; this.isRecorderBusy = false;
} }
@ -182,9 +193,9 @@ export default class RecordAudio extends React.PureComponent<IMessageBoxRecordAu
render() { render() {
const { theme } = this.props; const { theme } = this.props;
const { isRecording } = this.state; const { isRecording, isRecorderActive } = this.state;
if (!isRecording) { if (!isRecording && !isRecorderActive) {
return ( return (
<BorderlessButton <BorderlessButton
onPress={this.startRecordingAudio} onPress={this.startRecordingAudio}
@ -198,6 +209,32 @@ export default class RecordAudio extends React.PureComponent<IMessageBoxRecordAu
); );
} }
if (!isRecording && isRecorderActive) {
return (
<View style={styles.recordingContent}>
<View style={styles.textArea}>
<BorderlessButton
onPress={this.cancelRecordingAudio}
// @ts-ignore
accessibilityLabel={I18n.t('Cancel_recording')}
accessibilityTraits='button'
style={styles.actionButton}>
<CustomIcon size={24} color={themes[theme].dangerColor} name='delete' />
</BorderlessButton>
<Text style={[styles.recordingDurationText, { color: themes[theme].titleText }]}>{this.GetLastDuration}</Text>
</View>
<BorderlessButton
onPress={this.finishRecordingAudio}
// @ts-ignore
accessibilityLabel={I18n.t('Finish_recording')}
accessibilityTraits='button'
style={styles.actionButton}>
<CustomIcon size={24} color={themes[theme].tintColor} name='send-filled' />
</BorderlessButton>
</View>
);
}
return ( return (
<View style={styles.recordingContent}> <View style={styles.recordingContent}>
<View style={styles.textArea}> <View style={styles.textArea}>
@ -207,9 +244,10 @@ export default class RecordAudio extends React.PureComponent<IMessageBoxRecordAu
accessibilityLabel={I18n.t('Cancel_recording')} accessibilityLabel={I18n.t('Cancel_recording')}
accessibilityTraits='button' accessibilityTraits='button'
style={styles.actionButton}> style={styles.actionButton}>
<CustomIcon size={24} color={themes[theme].dangerColor} name='close' /> <CustomIcon size={24} color={themes[theme].dangerColor} name='delete' />
</BorderlessButton> </BorderlessButton>
<Text style={[styles.recordingCancelText, { color: themes[theme].titleText }]}>{this.duration}</Text> <Text style={[styles.recordingDurationText, { color: themes[theme].titleText }]}>{this.duration}</Text>
<CustomIcon size={24} color={themes[theme].dangerColor} name='record' />
</View> </View>
<BorderlessButton <BorderlessButton
onPress={this.finishRecordingAudio} onPress={this.finishRecordingAudio}
@ -217,7 +255,7 @@ export default class RecordAudio extends React.PureComponent<IMessageBoxRecordAu
accessibilityLabel={I18n.t('Finish_recording')} accessibilityLabel={I18n.t('Finish_recording')}
accessibilityTraits='button' accessibilityTraits='button'
style={styles.actionButton}> style={styles.actionButton}>
<CustomIcon size={24} color={themes[theme].successColor} name='check' /> <CustomIcon size={24} color={themes[theme].tintColor} name='send-filled' />
</BorderlessButton> </BorderlessButton>
</View> </View>
); );

View File

@ -139,7 +139,8 @@ export default StyleSheet.create({
flex: 1, flex: 1,
justifyContent: 'space-between' justifyContent: 'space-between'
}, },
recordingCancelText: { recordingDurationText: {
width: 60,
fontSize: 16, fontSize: 16,
...sharedStyles.textRegular ...sharedStyles.textRegular
}, },