107 lines
2.7 KiB
TypeScript
107 lines
2.7 KiB
TypeScript
/**
|
|
* Next Episode Store (Display Only - Backend-First Architecture)
|
|
*
|
|
* This store reflects next episode popup state from the backend.
|
|
* The backend handles all countdown logic and decisions.
|
|
*
|
|
* The backend emits ShowNextEpisodePopup and CountdownTick events to update this store.
|
|
*/
|
|
|
|
import { writable, derived } from "svelte/store";
|
|
import type { MediaItem } from "$lib/api/types";
|
|
|
|
export interface NextEpisodeState {
|
|
// Popup visibility
|
|
isVisible: boolean;
|
|
|
|
// Episode data
|
|
nextEpisode: MediaItem | null;
|
|
currentEpisode: MediaItem | null;
|
|
|
|
// Countdown state (managed by backend)
|
|
countdownSeconds: number;
|
|
initialCountdownSeconds: number;
|
|
|
|
// Settings
|
|
autoPlayEnabled: boolean;
|
|
}
|
|
|
|
function createNextEpisodeStore() {
|
|
const initialState: NextEpisodeState = {
|
|
isVisible: false,
|
|
nextEpisode: null,
|
|
currentEpisode: null,
|
|
countdownSeconds: 10,
|
|
initialCountdownSeconds: 10,
|
|
autoPlayEnabled: true,
|
|
};
|
|
|
|
const { subscribe, set, update } = writable<NextEpisodeState>(initialState);
|
|
|
|
/**
|
|
* Show the next episode popup (called by playerEvents when backend emits event)
|
|
*/
|
|
function showPopup(
|
|
currentEpisode: MediaItem,
|
|
nextEpisode: MediaItem,
|
|
countdownSeconds: number,
|
|
autoPlayEnabled: boolean
|
|
): void {
|
|
update((s) => ({
|
|
...s,
|
|
isVisible: true,
|
|
currentEpisode,
|
|
nextEpisode,
|
|
countdownSeconds,
|
|
initialCountdownSeconds: countdownSeconds,
|
|
autoPlayEnabled,
|
|
}));
|
|
}
|
|
|
|
/**
|
|
* Update countdown value (called by playerEvents on CountdownTick event)
|
|
*/
|
|
function updateCountdown(remainingSeconds: number): void {
|
|
update((s) => ({
|
|
...s,
|
|
countdownSeconds: remainingSeconds,
|
|
}));
|
|
}
|
|
|
|
/**
|
|
* Hide the popup
|
|
*/
|
|
function hidePopup(): void {
|
|
update((s) => ({
|
|
...s,
|
|
isVisible: false,
|
|
}));
|
|
}
|
|
|
|
/**
|
|
* Reset store to initial state
|
|
*/
|
|
function reset(): void {
|
|
set(initialState);
|
|
}
|
|
|
|
return {
|
|
subscribe,
|
|
showPopup,
|
|
updateCountdown,
|
|
hidePopup,
|
|
reset,
|
|
};
|
|
}
|
|
|
|
export const nextEpisode = createNextEpisodeStore();
|
|
|
|
// Derived stores for convenient access
|
|
export const isNextEpisodePopupVisible = derived(nextEpisode, ($ne) => $ne.isVisible);
|
|
export const nextEpisodeItem = derived(nextEpisode, ($ne) => $ne.nextEpisode);
|
|
export const currentEpisodeItem = derived(nextEpisode, ($ne) => $ne.currentEpisode);
|
|
export const countdownSeconds = derived(nextEpisode, ($ne) => $ne.countdownSeconds);
|
|
export const initialCountdownSeconds = derived(nextEpisode, ($ne) => $ne.initialCountdownSeconds);
|
|
export const isAutoPlayEnabled = derived(nextEpisode, ($ne) => $ne.autoPlayEnabled);
|
|
export const isCountdownActive = derived(nextEpisode, ($ne) => $ne.isVisible && $ne.countdownSeconds > 0);
|