mirror of https://github.com/vector-im/riot-web
Wire up the send button for voice messages
This fixes a bug where we couldn't upload voice messages because the audio buffer was being read, therefore changing the position of the cursor. When this happened, the upload function would claim that the buffer was empty and could not be read.pull/21833/head
parent
c1bb0bb0b8
commit
5e646f861c
|
@ -198,6 +198,7 @@ interface IState {
|
|||
export default class MessageComposer extends React.Component<IProps, IState> {
|
||||
private dispatcherRef: string;
|
||||
private messageComposerInput: SendMessageComposer;
|
||||
private voiceRecordingButton: VoiceRecordComposerTile;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -322,7 +323,15 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
|||
});
|
||||
}
|
||||
|
||||
sendMessage = () => {
|
||||
sendMessage = async () => {
|
||||
if (this.state.haveRecording && this.voiceRecordingButton) {
|
||||
// There shouldn't be any text message to send when a voice recording is active, so
|
||||
// just send out the voice recording.
|
||||
await this.voiceRecordingButton.send();
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX: Private function access
|
||||
this.messageComposerInput._sendMessage();
|
||||
}
|
||||
|
||||
|
@ -387,6 +396,7 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
|||
if (SettingsStore.getValue("feature_voice_messages")) {
|
||||
controls.push(<VoiceRecordComposerTile
|
||||
key="controls_voice_record"
|
||||
ref={c => this.voiceRecordingButton = c}
|
||||
room={this.props.room} />);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
private recorderStream: MediaStream;
|
||||
private recorderFFT: AnalyserNode;
|
||||
private recorderWorklet: AudioWorkletNode;
|
||||
private buffer = new Uint8Array(0);
|
||||
private buffer = new Uint8Array(0); // use this.audioBuffer to access
|
||||
private mxc: string;
|
||||
private recording = false;
|
||||
private observable: SimpleObservable<IRecordingUpdate>;
|
||||
|
@ -166,6 +166,12 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
};
|
||||
}
|
||||
|
||||
private get audioBuffer(): Uint8Array {
|
||||
// We need a clone of the buffer to avoid accidentally changing the position
|
||||
// on the real thing.
|
||||
return this.buffer.slice(0);
|
||||
}
|
||||
|
||||
public get liveData(): SimpleObservable<IRecordingUpdate> {
|
||||
if (!this.recording) throw new Error("No observable when not recording");
|
||||
return this.observable;
|
||||
|
@ -267,13 +273,13 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
await this.recorder.close();
|
||||
this.emit(RecordingState.Ended);
|
||||
|
||||
return this.buffer;
|
||||
return this.audioBuffer;
|
||||
});
|
||||
}
|
||||
|
||||
public getPlayback(): Promise<Playback> {
|
||||
return Singleflight.for(this, "playback").do(async () => {
|
||||
const playback = new Playback(this.buffer.buffer); // cast to ArrayBuffer proper
|
||||
const playback = new Playback(this.audioBuffer.buffer); // cast to ArrayBuffer proper
|
||||
await playback.prepare();
|
||||
return playback;
|
||||
});
|
||||
|
@ -294,7 +300,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
if (this.mxc) return this.mxc;
|
||||
|
||||
this.emit(RecordingState.Uploading);
|
||||
this.mxc = await this.client.uploadContent(new Blob([this.buffer], {
|
||||
this.mxc = await this.client.uploadContent(new Blob([this.audioBuffer], {
|
||||
type: this.contentType,
|
||||
}), {
|
||||
onlyContentUri: false, // to stop the warnings in the console
|
||||
|
|
Loading…
Reference in New Issue