First working POC
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* 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);
|
||||
Reference in New Issue
Block a user