stream-chat-react-native-core
Version:
The official React Native and Expo components for Stream Chat, a service for building chat applications
96 lines (77 loc) • 2.23 kB
text/typescript
import { StateStore } from 'stream-chat';
import { AudioPlayer, AudioPlayerOptions } from './audio-player';
export type AudioPlayerPoolOptions = {
allowConcurrentAudioPlayback: boolean;
};
export type AudioPlayerPoolState = {
activeAudioPlayer: AudioPlayer | null;
};
export class AudioPlayerPool {
pool: Map<string, AudioPlayer>;
allowConcurrentAudioPlayback: boolean;
state: StateStore<AudioPlayerPoolState> = new StateStore<AudioPlayerPoolState>({
activeAudioPlayer: null,
});
constructor({ allowConcurrentAudioPlayback }: AudioPlayerPoolOptions) {
this.pool = new Map<string, AudioPlayer>();
this.allowConcurrentAudioPlayback = allowConcurrentAudioPlayback ?? false;
}
get players() {
return Array.from(this.pool.values());
}
getOrAddPlayer(params: AudioPlayerOptions) {
const player = this.pool.get(params.id);
if (player) {
player.setOnError(params.onError);
return player;
}
const newPlayer = new AudioPlayer(params);
newPlayer.pool = this;
this.pool.set(params.id, newPlayer);
return newPlayer;
}
setActivePlayer(activeAudioPlayer: AudioPlayer | null) {
this.state.partialNext({
activeAudioPlayer,
});
}
getActivePlayer() {
return this.state.getLatestValue().activeAudioPlayer;
}
removePlayer(id: string) {
const player = this.pool.get(id);
if (!player) return;
player.onRemove();
this.pool.delete(id);
if (this.getActivePlayer()?.id === id) {
this.setActivePlayer(null);
}
}
deregister(id: string) {
if (this.pool.has(id)) {
this.pool.delete(id);
}
}
clear() {
for (const player of this.pool.values()) {
this.removePlayer(player.id);
}
this.setActivePlayer(null);
}
requestPlay(id: string) {
if (this.allowConcurrentAudioPlayback) return;
if (this.getActivePlayer()?.id !== id) {
const currentPlayer = this.getActivePlayer();
if (currentPlayer && currentPlayer.isPlaying) {
currentPlayer.pause();
}
}
const activePlayer = this.pool.get(id);
if (activePlayer) {
this.setActivePlayer(activePlayer);
}
}
notifyPaused() {
this.setActivePlayer(null);
}
}