Ctrl K
ComunidadGuías…

src/renderer/store/playback-owner.store.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import {
    createIdlePlaybackSession,
    createPlaybackSession,
    type PlaybackEngine,
    type PlaybackSession,
    type PlaybackSource,
} from '@samo/core/playback';
import { create } from 'zustand';
import { subscribeWithSelector } from 'zustand/middleware';

import { stopAllAudioElements } from '/@/renderer/features/player/audio-player/audio-element-registry';

export type { PlaybackEngine, PlaybackSession, PlaybackSource } from '@samo/core/playback';

interface PlaybackClaimOptions {
    engine?: PlaybackEngine;
    mediaKey?: null | string;
    replace?: boolean;
}

interface PlaybackOwnerState {
    claim: (source: PlaybackSource, options?: PlaybackClaimOptions) => PlaybackSession;
    release: (source: PlaybackSource) => void;
    session: PlaybackSession;
    source: null | PlaybackSource;
}

let playbackSessionSequence = 0;

export const usePlaybackOwnerStore = create<PlaybackOwnerState>()(
    subscribeWithSelector((set, get) => ({
        claim: (source, options = {}) => {
            const currentSession = get().session;
            const nextMediaKey = options.mediaKey ?? null;
            const isSourceChange = get().source !== source;
            const isRadioClaim = source === 'radio';
            const isExplicitReplacement = Boolean(options.replace);
            const isMediaKeyReplacement =
                options.mediaKey !== undefined &&
                currentSession.source === source &&
                currentSession.mediaKey !== nextMediaKey;

            // Stop any Web audio that belongs to the outgoing owner/session.
            // Mounted elements stay registered so reused DOM nodes remain
            // inspectable and controllable after a URL or session switch.
            if (isSourceChange || isRadioClaim || isExplicitReplacement || isMediaKeyReplacement) {
                stopAllAudioElements();
            }
            const session = createPlaybackSession({
                engine: options.engine ?? 'none',
                mediaKey: nextMediaKey,
                sequence: ++playbackSessionSequence,
                source,
            });
            set({ session, source });
            return session;
        },
        release: (source) => {
            if (get().source === source) {
                stopAllAudioElements();
                set({ session: createIdlePlaybackSession(), source: null });
            }
        },
        session: createIdlePlaybackSession(),
        source: null,
    })),
);

export const usePlaybackSession = () => usePlaybackOwnerStore((state) => state.session);
export const usePlaybackSource = () => usePlaybackOwnerStore((state) => state.source);