mirror of https://github.com/vector-im/riot-web
				
				
				
			Handle local events for voice broadcasts (#9561)
							parent
							
								
									848adfdc10
								
							
						
					
					
						commit
						7fbdd8bb5d
					
				| 
						 | 
				
			
			@ -129,12 +129,8 @@ export class VoiceBroadcastPlayback
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    private addChunkEvent = async (event: MatrixEvent): Promise<boolean> => {
 | 
			
		||||
        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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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", () => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue