diff --git a/src/components/views/rooms/VoiceRecordComposerTile.tsx b/src/components/views/rooms/VoiceRecordComposerTile.tsx index 782cda9f4c..c3fe0762c7 100644 --- a/src/components/views/rooms/VoiceRecordComposerTile.tsx +++ b/src/components/views/rooms/VoiceRecordComposerTile.tsx @@ -16,7 +16,6 @@ limitations under the License. import React, { ReactNode } from "react"; import { Room } from "matrix-js-sdk/src/models/room"; -import { MsgType } from "matrix-js-sdk/src/@types/event"; import { logger } from "matrix-js-sdk/src/logger"; import { Optional } from "matrix-events-sdk"; import { IEventRelation, MatrixEvent } from "matrix-js-sdk/src/models/event"; @@ -45,6 +44,7 @@ import { addReplyToMessageContent } from "../../../utils/Reply"; import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks"; import RoomContext from "../../../contexts/RoomContext"; import { IUpload, VoiceMessageRecording } from "../../../audio/VoiceMessageRecording"; +import { createVoiceMessageContent } from "../../../utils/createVoiceMessageContent"; interface IProps { room: Room; @@ -122,36 +122,14 @@ export default class VoiceRecordComposerTile extends React.PureComponent Math.round(v * 1024)), - }, - "org.matrix.msc3245.voice": {}, // No content, this is a rendering hint - }; + const content = createVoiceMessageContent( + upload.mxc, + this.state.recorder.contentType, + Math.round(this.state.recorder.durationSeconds * 1000), + this.state.recorder.contentLength, + upload.encrypted, + this.state.recorder.getPlayback().thumbnailWaveform.map(v => Math.round(v * 1024)), + ); attachRelation(content, relation); if (replyToEvent) { diff --git a/src/utils/createVoiceMessageContent.ts b/src/utils/createVoiceMessageContent.ts new file mode 100644 index 0000000000..f406304c8c --- /dev/null +++ b/src/utils/createVoiceMessageContent.ts @@ -0,0 +1,64 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { IEncryptedFile, MsgType } from "matrix-js-sdk/src/matrix"; + +/** + * @param {string} mxc MXC URL of the file + * @param {string} mimetype + * @param {number} duration Duration in milliseconds + * @param {number} size + * @param {number[]} [waveform] + * @param {IEncryptedFile} [file] Encrypted file + */ +export const createVoiceMessageContent = ( + mxc: string, + mimetype: string, + duration: number, + size: number, + file?: IEncryptedFile, + waveform?: number[], +) => { + return { + "body": "Voice message", + //"msgtype": "org.matrix.msc2516.voice", + "msgtype": MsgType.Audio, + "url": mxc, + "file": file, + "info": { + duration, + mimetype, + size, + }, + + // MSC1767 + Ideals of MSC2516 as MSC3245 + // https://github.com/matrix-org/matrix-doc/pull/3245 + "org.matrix.msc1767.text": "Voice message", + "org.matrix.msc1767.file": { + url: mxc, + file, + name: "Voice message.ogg", + mimetype, + size, + }, + "org.matrix.msc1767.audio": { + duration, + // https://github.com/matrix-org/matrix-doc/pull/3246 + waveform, + }, + "org.matrix.msc3245.voice": {}, // No content, this is a rendering hint + }; +}; diff --git a/test/components/views/rooms/VoiceRecordComposerTile-test.tsx b/test/components/views/rooms/VoiceRecordComposerTile-test.tsx index 77df519a8d..fa4363adb8 100644 --- a/test/components/views/rooms/VoiceRecordComposerTile-test.tsx +++ b/test/components/views/rooms/VoiceRecordComposerTile-test.tsx @@ -57,7 +57,7 @@ describe("", () => { durationSeconds: 1337, contentType: "audio/ogg", getPlayback: () => ({ - thumbnailWaveform: [], + thumbnailWaveform: [1.4, 2.5, 3.6], }), } as unknown as VoiceRecording; voiceRecordComposerTile = mount(); @@ -88,7 +88,11 @@ describe("", () => { "msgtype": MsgType.Audio, "org.matrix.msc1767.audio": { "duration": 1337000, - "waveform": [], + "waveform": [ + 1434, + 2560, + 3686, + ], }, "org.matrix.msc1767.file": { "file": undefined, diff --git a/test/utils/__snapshots__/createVoiceMessageContent-test.ts.snap b/test/utils/__snapshots__/createVoiceMessageContent-test.ts.snap new file mode 100644 index 0000000000..bf1c949456 --- /dev/null +++ b/test/utils/__snapshots__/createVoiceMessageContent-test.ts.snap @@ -0,0 +1,32 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`createVoiceMessageContent should create a voice message content 1`] = ` +Object { + "body": "Voice message", + "file": Object {}, + "info": Object { + "duration": 23000, + "mimetype": "ogg/opus", + "size": 42000, + }, + "msgtype": "m.audio", + "org.matrix.msc1767.audio": Object { + "duration": 23000, + "waveform": Array [ + 1, + 2, + 3, + ], + }, + "org.matrix.msc1767.file": Object { + "file": Object {}, + "mimetype": "ogg/opus", + "name": "Voice message.ogg", + "size": 42000, + "url": "mxc://example.com/file", + }, + "org.matrix.msc1767.text": "Voice message", + "org.matrix.msc3245.voice": Object {}, + "url": "mxc://example.com/file", +} +`; diff --git a/test/utils/createVoiceMessageContent-test.ts b/test/utils/createVoiceMessageContent-test.ts new file mode 100644 index 0000000000..0043cf292a --- /dev/null +++ b/test/utils/createVoiceMessageContent-test.ts @@ -0,0 +1,32 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { IEncryptedFile } from "matrix-js-sdk/src/matrix"; + +import { createVoiceMessageContent } from "../../src/utils/createVoiceMessageContent"; + +describe("createVoiceMessageContent", () => { + it("should create a voice message content", () => { + expect(createVoiceMessageContent( + "mxc://example.com/file", + "ogg/opus", + 23000, + 42000, + {} as unknown as IEncryptedFile, + [1, 2, 3], + )).toMatchSnapshot(); + }); +});