[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:
parent
a52199a49c
commit
30aab71db1
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue