From 7fbdd8bb5d8b0efcb951c1bb1d4b9e8c7ca53492 Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Wed, 9 Nov 2022 12:17:54 +0100 Subject: [PATCH] Handle local events for voice broadcasts (#9561) --- .../models/VoiceBroadcastPlayback.ts | 8 ++------ .../utils/VoiceBroadcastChunkEvents.ts | 12 +++++++++-- .../models/VoiceBroadcastPlayback-test.ts | 19 ++++++++++++++++++ .../utils/VoiceBroadcastChunkEvents-test.ts | 20 +++++++++++++++++++ 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/voice-broadcast/models/VoiceBroadcastPlayback.ts b/src/voice-broadcast/models/VoiceBroadcastPlayback.ts index 38a65caf7a..634e21dd88 100644 --- a/src/voice-broadcast/models/VoiceBroadcastPlayback.ts +++ b/src/voice-broadcast/models/VoiceBroadcastPlayback.ts @@ -129,12 +129,8 @@ export class VoiceBroadcastPlayback } private addChunkEvent = async (event: MatrixEvent): Promise => { - const eventId = event.getId(); - - if (!eventId - || eventId.startsWith("~!") // don't add local events - || event.getContent()?.msgtype !== MsgType.Audio // don't add non-audio event - ) { + if (event.getContent()?.msgtype !== MsgType.Audio) { + // skip non-audio event return false; } diff --git a/src/voice-broadcast/utils/VoiceBroadcastChunkEvents.ts b/src/voice-broadcast/utils/VoiceBroadcastChunkEvents.ts index 1912f2f610..ad0a109513 100644 --- a/src/voice-broadcast/utils/VoiceBroadcastChunkEvents.ts +++ b/src/voice-broadcast/utils/VoiceBroadcastChunkEvents.ts @@ -50,9 +50,12 @@ export class VoiceBroadcastChunkEvents { } public includes(event: MatrixEvent): boolean { - return !!this.events.find(e => e.getId() === event.getId()); + return !!this.events.find(e => this.equalByTxnIdOrId(event, e)); } + /** + * @returns {number} Length in milliseconds + */ public getLength(): number { return this.events.reduce((length: number, event: MatrixEvent) => { return length + this.calculateChunkLength(event); @@ -93,11 +96,16 @@ export class VoiceBroadcastChunkEvents { } private addOrReplaceEvent = (event: MatrixEvent): boolean => { - this.events = this.events.filter(e => e.getId() !== event.getId()); + this.events = this.events.filter(e => !this.equalByTxnIdOrId(event, e)); this.events.push(event); return true; }; + private equalByTxnIdOrId(eventA: MatrixEvent, eventB: MatrixEvent): boolean { + return eventA.getTxnId() && eventB.getTxnId() && eventA.getTxnId() === eventB.getTxnId() + || eventA.getId() === eventB.getId(); + } + /** * Sort by sequence, if available for all events. * Else fall back to timestamp. diff --git a/test/voice-broadcast/models/VoiceBroadcastPlayback-test.ts b/test/voice-broadcast/models/VoiceBroadcastPlayback-test.ts index 4113595c2d..7c12f0a330 100644 --- a/test/voice-broadcast/models/VoiceBroadcastPlayback-test.ts +++ b/test/voice-broadcast/models/VoiceBroadcastPlayback-test.ts @@ -49,6 +49,7 @@ describe("VoiceBroadcastPlayback", () => { let onStateChanged: (state: VoiceBroadcastPlaybackState) => void; let chunk1Event: MatrixEvent; let chunk2Event: MatrixEvent; + let chunk2BEvent: MatrixEvent; let chunk3Event: MatrixEvent; const chunk1Length = 2300; const chunk2Length = 4200; @@ -135,6 +136,9 @@ describe("VoiceBroadcastPlayback", () => { chunk1Event = mkVoiceBroadcastChunkEvent(userId, roomId, chunk1Length, 1); chunk2Event = mkVoiceBroadcastChunkEvent(userId, roomId, chunk2Length, 2); + chunk2Event.setTxnId("tx-id-1"); + chunk2BEvent = mkVoiceBroadcastChunkEvent(userId, roomId, chunk2Length, 2); + chunk2BEvent.setTxnId("tx-id-1"); chunk3Event = mkVoiceBroadcastChunkEvent(userId, roomId, chunk3Length, 3); chunk1Helper = mkChunkHelper(chunk1Data); @@ -240,6 +244,21 @@ describe("VoiceBroadcastPlayback", () => { playback = await mkPlayback(); }); + it("durationSeconds should have the length of the known chunks", () => { + expect(playback.durationSeconds).toEqual(6.5); + }); + + describe("and an event with the same transaction Id occurs", () => { + beforeEach(() => { + // @ts-ignore + playback.chunkRelationHelper.emit(RelationsHelperEvent.Add, chunk2BEvent); + }); + + it("durationSeconds should not change", () => { + expect(playback.durationSeconds).toEqual(6.5); + }); + }); + describe("and calling start", () => { startPlayback(); diff --git a/test/voice-broadcast/utils/VoiceBroadcastChunkEvents-test.ts b/test/voice-broadcast/utils/VoiceBroadcastChunkEvents-test.ts index 2e3739360a..26fcbc4258 100644 --- a/test/voice-broadcast/utils/VoiceBroadcastChunkEvents-test.ts +++ b/test/voice-broadcast/utils/VoiceBroadcastChunkEvents-test.ts @@ -22,9 +22,11 @@ import { mkVoiceBroadcastChunkEvent } from "./test-utils"; describe("VoiceBroadcastChunkEvents", () => { const userId = "@user:example.com"; const roomId = "!room:example.com"; + const txnId = "txn-id"; let eventSeq1Time1: MatrixEvent; let eventSeq2Time4: MatrixEvent; let eventSeq3Time2: MatrixEvent; + let eventSeq3Time2T: MatrixEvent; let eventSeq4Time1: MatrixEvent; let eventSeqUTime3: MatrixEvent; let eventSeq2Time4Dup: MatrixEvent; @@ -36,6 +38,9 @@ describe("VoiceBroadcastChunkEvents", () => { eventSeq2Time4Dup = mkVoiceBroadcastChunkEvent(userId, roomId, 3141, 2, 4); jest.spyOn(eventSeq2Time4Dup, "getId").mockReturnValue(eventSeq2Time4.getId()); eventSeq3Time2 = mkVoiceBroadcastChunkEvent(userId, roomId, 42, 3, 2); + eventSeq3Time2.setTxnId(txnId); + eventSeq3Time2T = mkVoiceBroadcastChunkEvent(userId, roomId, 42, 3, 2); + eventSeq3Time2T.setTxnId(txnId); eventSeq4Time1 = mkVoiceBroadcastChunkEvent(userId, roomId, 69, 4, 1); eventSeqUTime3 = mkVoiceBroadcastChunkEvent(userId, roomId, 314, undefined, 3); chunkEvents = new VoiceBroadcastChunkEvents(); @@ -96,6 +101,21 @@ describe("VoiceBroadcastChunkEvents", () => { it("findByTime(entire duration) should return the last chunk", () => { expect(chunkEvents.findByTime(7 + 3141 + 42 + 69)).toBe(eventSeq4Time1); }); + + describe("and adding an event with a known transaction Id", () => { + beforeEach(() => { + chunkEvents.addEvent(eventSeq3Time2T); + }); + + it("should replace the previous event", () => { + expect(chunkEvents.getEvents()).toEqual([ + eventSeq1Time1, + eventSeq2Time4Dup, + eventSeq3Time2T, + eventSeq4Time1, + ]); + }); + }); }); describe("when adding events where at least one does not have a sequence", () => {