summaryrefslogtreecommitdiff
path: root/apps/web/src/stores/playback-store.ts
diff options
context:
space:
mode:
Diffstat (limited to 'apps/web/src/stores/playback-store.ts')
-rw-r--r--apps/web/src/stores/playback-store.ts206
1 files changed, 103 insertions, 103 deletions
diff --git a/apps/web/src/stores/playback-store.ts b/apps/web/src/stores/playback-store.ts
index 3ef1d95c..543865f9 100644
--- a/apps/web/src/stores/playback-store.ts
+++ b/apps/web/src/stores/playback-store.ts
@@ -2,133 +2,133 @@ import { create } from "zustand";
import type { PlaybackState, PlaybackControls } from "@/types/playback";
interface PlaybackStore extends PlaybackState, PlaybackControls {
- setDuration: (duration: number) => void;
- setCurrentTime: (time: number) => void;
+ setDuration: (duration: number) => void;
+ setCurrentTime: (time: number) => void;
}
let playbackTimer: number | null = null;
const startTimer = (store: () => PlaybackStore) => {
- if (playbackTimer) cancelAnimationFrame(playbackTimer);
+ if (playbackTimer) cancelAnimationFrame(playbackTimer);
- // Use requestAnimationFrame for smoother updates
- const updateTime = () => {
- const state = store();
- if (state.isPlaying && state.currentTime < state.duration) {
- const now = performance.now();
- const delta = (now - lastUpdate) / 1000; // Convert to seconds
- lastUpdate = now;
+ // Use requestAnimationFrame for smoother updates
+ const updateTime = () => {
+ const state = store();
+ if (state.isPlaying && state.currentTime < state.duration) {
+ const now = performance.now();
+ const delta = (now - lastUpdate) / 1000; // Convert to seconds
+ lastUpdate = now;
- const newTime = state.currentTime + delta * state.speed;
- if (newTime >= state.duration) {
- // When video completes, pause and reset playhead to start
- state.pause();
- state.setCurrentTime(0);
- // Notify video elements to sync with reset
- window.dispatchEvent(
- new CustomEvent("playback-seek", { detail: { time: 0 } }),
- );
- } else {
- state.setCurrentTime(newTime);
- // Notify video elements to sync
- window.dispatchEvent(
- new CustomEvent("playback-update", { detail: { time: newTime } }),
- );
- }
- }
- playbackTimer = requestAnimationFrame(updateTime);
- };
+ const newTime = state.currentTime + delta * state.speed;
+ if (newTime >= state.duration) {
+ // When video completes, pause and reset playhead to start
+ state.pause();
+ state.setCurrentTime(0);
+ // Notify video elements to sync with reset
+ window.dispatchEvent(
+ new CustomEvent("playback-seek", { detail: { time: 0 } })
+ );
+ } else {
+ state.setCurrentTime(newTime);
+ // Notify video elements to sync
+ window.dispatchEvent(
+ new CustomEvent("playback-update", { detail: { time: newTime } })
+ );
+ }
+ }
+ playbackTimer = requestAnimationFrame(updateTime);
+ };
- let lastUpdate = performance.now();
- playbackTimer = requestAnimationFrame(updateTime);
+ let lastUpdate = performance.now();
+ playbackTimer = requestAnimationFrame(updateTime);
};
const stopTimer = () => {
- if (playbackTimer) {
- cancelAnimationFrame(playbackTimer);
- playbackTimer = null;
- }
+ if (playbackTimer) {
+ cancelAnimationFrame(playbackTimer);
+ playbackTimer = null;
+ }
};
export const usePlaybackStore = create<PlaybackStore>((set, get) => ({
- isPlaying: false,
- currentTime: 0,
- duration: 0,
- volume: 1,
- muted: false,
- previousVolume: 1,
- speed: 1.0,
+ isPlaying: false,
+ currentTime: 0,
+ duration: 0,
+ volume: 1,
+ muted: false,
+ previousVolume: 1,
+ speed: 1.0,
- play: () => {
- set({ isPlaying: true });
- startTimer(get);
- },
+ play: () => {
+ set({ isPlaying: true });
+ startTimer(get);
+ },
- pause: () => {
- set({ isPlaying: false });
- stopTimer();
- },
+ pause: () => {
+ set({ isPlaying: false });
+ stopTimer();
+ },
- toggle: () => {
- const { isPlaying } = get();
- if (isPlaying) {
- get().pause();
- } else {
- get().play();
- }
- },
+ toggle: () => {
+ const { isPlaying } = get();
+ if (isPlaying) {
+ get().pause();
+ } else {
+ get().play();
+ }
+ },
- seek: (time: number) => {
- const { duration } = get();
- const clampedTime = Math.max(0, Math.min(duration, time));
- set({ currentTime: clampedTime });
+ seek: (time: number) => {
+ const { duration } = get();
+ const clampedTime = Math.max(0, Math.min(duration, time));
+ set({ currentTime: clampedTime });
- const event = new CustomEvent("playback-seek", {
- detail: { time: clampedTime },
- });
- window.dispatchEvent(event);
- },
+ const event = new CustomEvent("playback-seek", {
+ detail: { time: clampedTime },
+ });
+ window.dispatchEvent(event);
+ },
- setVolume: (volume: number) =>
- set((state) => ({
- volume: Math.max(0, Math.min(1, volume)),
- muted: volume === 0,
- previousVolume: volume > 0 ? volume : state.previousVolume,
- })),
+ setVolume: (volume: number) =>
+ set((state) => ({
+ volume: Math.max(0, Math.min(1, volume)),
+ muted: volume === 0,
+ previousVolume: volume > 0 ? volume : state.previousVolume,
+ })),
- setSpeed: (speed: number) => {
- const newSpeed = Math.max(0.1, Math.min(2.0, speed));
- set({ speed: newSpeed });
+ setSpeed: (speed: number) => {
+ const newSpeed = Math.max(0.1, Math.min(2.0, speed));
+ set({ speed: newSpeed });
- const event = new CustomEvent("playback-speed", {
- detail: { speed: newSpeed },
- });
- window.dispatchEvent(event);
- },
+ const event = new CustomEvent("playback-speed", {
+ detail: { speed: newSpeed },
+ });
+ window.dispatchEvent(event);
+ },
- setDuration: (duration: number) => set({ duration }),
- setCurrentTime: (time: number) => set({ currentTime: time }),
+ setDuration: (duration: number) => set({ duration }),
+ setCurrentTime: (time: number) => set({ currentTime: time }),
- mute: () => {
- const { volume, previousVolume } = get();
- set({
- muted: true,
- previousVolume: volume > 0 ? volume : previousVolume,
- volume: 0,
- });
- },
+ mute: () => {
+ const { volume, previousVolume } = get();
+ set({
+ muted: true,
+ previousVolume: volume > 0 ? volume : previousVolume,
+ volume: 0,
+ });
+ },
- unmute: () => {
- const { previousVolume } = get();
- set({ muted: false, volume: previousVolume ?? 1 });
- },
+ unmute: () => {
+ const { previousVolume } = get();
+ set({ muted: false, volume: previousVolume ?? 1 });
+ },
- toggleMute: () => {
- const { muted } = get();
- if (muted) {
- get().unmute();
- } else {
- get().mute();
- }
- },
+ toggleMute: () => {
+ const { muted } = get();
+ if (muted) {
+ get().unmute();
+ } else {
+ get().mute();
+ }
+ },
}));