When start listening to a broadcast, pause the others (#9489)
This commit is contained in:
parent
daf097e123
commit
d702f4a291
4 changed files with 186 additions and 61 deletions
|
@ -47,7 +47,10 @@ export enum VoiceBroadcastPlaybackEvent {
|
|||
|
||||
interface EventMap {
|
||||
[VoiceBroadcastPlaybackEvent.LengthChanged]: (length: number) => void;
|
||||
[VoiceBroadcastPlaybackEvent.StateChanged]: (state: VoiceBroadcastPlaybackState) => void;
|
||||
[VoiceBroadcastPlaybackEvent.StateChanged]: (
|
||||
state: VoiceBroadcastPlaybackState,
|
||||
playback: VoiceBroadcastPlayback
|
||||
) => void;
|
||||
[VoiceBroadcastPlaybackEvent.InfoStateChanged]: (state: VoiceBroadcastInfoState) => void;
|
||||
}
|
||||
|
||||
|
@ -217,14 +220,20 @@ export class VoiceBroadcastPlayback
|
|||
}
|
||||
|
||||
public pause(): void {
|
||||
if (!this.currentlyPlaying) return;
|
||||
// stopped voice broadcasts cannot be paused
|
||||
if (this.getState() === VoiceBroadcastPlaybackState.Stopped) return;
|
||||
|
||||
this.setState(VoiceBroadcastPlaybackState.Paused);
|
||||
if (!this.currentlyPlaying) return;
|
||||
this.currentlyPlaying.pause();
|
||||
}
|
||||
|
||||
public resume(): void {
|
||||
if (!this.currentlyPlaying) return;
|
||||
if (!this.currentlyPlaying) {
|
||||
// no playback to resume, start from the beginning
|
||||
this.start();
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState(VoiceBroadcastPlaybackState.Playing);
|
||||
this.currentlyPlaying.play();
|
||||
|
@ -260,7 +269,7 @@ export class VoiceBroadcastPlayback
|
|||
}
|
||||
|
||||
this.state = state;
|
||||
this.emit(VoiceBroadcastPlaybackEvent.StateChanged, state);
|
||||
this.emit(VoiceBroadcastPlaybackEvent.StateChanged, state, this);
|
||||
}
|
||||
|
||||
public getInfoState(): VoiceBroadcastInfoState {
|
||||
|
|
|
@ -17,7 +17,8 @@ limitations under the License.
|
|||
import { MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { TypedEventEmitter } from "matrix-js-sdk/src/models/typed-event-emitter";
|
||||
|
||||
import { VoiceBroadcastPlayback } from "..";
|
||||
import { VoiceBroadcastPlayback, VoiceBroadcastPlaybackEvent, VoiceBroadcastPlaybackState } from "..";
|
||||
import { IDestroyable } from "../../utils/IDestroyable";
|
||||
|
||||
export enum VoiceBroadcastPlaybacksStoreEvent {
|
||||
CurrentChanged = "current_changed",
|
||||
|
@ -28,10 +29,16 @@ interface EventMap {
|
|||
}
|
||||
|
||||
/**
|
||||
* This store provides access to the current and specific Voice Broadcast playbacks.
|
||||
* This store manages VoiceBroadcastPlaybacks:
|
||||
* - access the currently playing voice broadcast
|
||||
* - ensures that only once broadcast is playing at a time
|
||||
*/
|
||||
export class VoiceBroadcastPlaybacksStore extends TypedEventEmitter<VoiceBroadcastPlaybacksStoreEvent, EventMap> {
|
||||
export class VoiceBroadcastPlaybacksStore
|
||||
extends TypedEventEmitter<VoiceBroadcastPlaybacksStoreEvent, EventMap>
|
||||
implements IDestroyable {
|
||||
private current: VoiceBroadcastPlayback | null;
|
||||
|
||||
/** Playbacks indexed by their info event id. */
|
||||
private playbacks = new Map<string, VoiceBroadcastPlayback>();
|
||||
|
||||
public constructor() {
|
||||
|
@ -42,7 +49,7 @@ export class VoiceBroadcastPlaybacksStore extends TypedEventEmitter<VoiceBroadca
|
|||
if (this.current === current) return;
|
||||
|
||||
this.current = current;
|
||||
this.playbacks.set(current.infoEvent.getId(), current);
|
||||
this.addPlayback(current);
|
||||
this.emit(VoiceBroadcastPlaybacksStoreEvent.CurrentChanged, current);
|
||||
}
|
||||
|
||||
|
@ -54,12 +61,51 @@ export class VoiceBroadcastPlaybacksStore extends TypedEventEmitter<VoiceBroadca
|
|||
const infoEventId = infoEvent.getId();
|
||||
|
||||
if (!this.playbacks.has(infoEventId)) {
|
||||
this.playbacks.set(infoEventId, new VoiceBroadcastPlayback(infoEvent, client));
|
||||
this.addPlayback(new VoiceBroadcastPlayback(infoEvent, client));
|
||||
}
|
||||
|
||||
return this.playbacks.get(infoEventId);
|
||||
}
|
||||
|
||||
private addPlayback(playback: VoiceBroadcastPlayback): void {
|
||||
const infoEventId = playback.infoEvent.getId();
|
||||
|
||||
if (this.playbacks.has(infoEventId)) return;
|
||||
|
||||
this.playbacks.set(infoEventId, playback);
|
||||
playback.on(VoiceBroadcastPlaybackEvent.StateChanged, this.onPlaybackStateChanged);
|
||||
}
|
||||
|
||||
private onPlaybackStateChanged = (
|
||||
state: VoiceBroadcastPlaybackState,
|
||||
playback: VoiceBroadcastPlayback,
|
||||
): void => {
|
||||
if ([
|
||||
VoiceBroadcastPlaybackState.Buffering,
|
||||
VoiceBroadcastPlaybackState.Playing,
|
||||
].includes(state)) {
|
||||
this.pauseExcept(playback);
|
||||
}
|
||||
};
|
||||
|
||||
private pauseExcept(playbackNotToPause: VoiceBroadcastPlayback): void {
|
||||
for (const playback of this.playbacks.values()) {
|
||||
if (playback !== playbackNotToPause) {
|
||||
playback.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
this.removeAllListeners();
|
||||
|
||||
for (const playback of this.playbacks.values()) {
|
||||
playback.off(VoiceBroadcastPlaybackEvent.StateChanged, this.onPlaybackStateChanged);
|
||||
}
|
||||
|
||||
this.playbacks = new Map();
|
||||
}
|
||||
|
||||
public static readonly _instance = new VoiceBroadcastPlaybacksStore();
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue