39948-vm/frontend/src/hooks/usePageBackground.ts

177 lines
4.7 KiB
TypeScript

/**
* usePageBackground Hook
*
* Consolidates 8 separate useState hooks for page background management into
* a single state object with convenient update functions.
*
* Replaces:
* - backgroundImageUrl, setBackgroundImageUrl
* - backgroundVideoUrl, setBackgroundVideoUrl
* - backgroundAudioUrl, setBackgroundAudioUrl
* - backgroundVideoAutoplay, setBackgroundVideoAutoplay
* - backgroundVideoLoop, setBackgroundVideoLoop
* - backgroundVideoMuted, setBackgroundVideoMuted
* - backgroundVideoStartTime, setBackgroundVideoStartTime
* - backgroundVideoEndTime, setBackgroundVideoEndTime
*/
import { useState, useCallback } from 'react';
import type {
PageBackgroundState,
PageBackgroundVideoSettings,
} from '../types/constructor';
import {
DEFAULT_PAGE_BACKGROUND,
createPageBackgroundFromPage,
} from '../types/constructor';
interface TourPageData {
background_image_url?: string;
background_video_url?: string;
background_audio_url?: string;
background_video_autoplay?: boolean;
background_video_loop?: boolean;
background_video_muted?: boolean;
background_video_start_time?: number | null;
background_video_end_time?: number | null;
}
export interface UsePageBackgroundOptions {
/** Initial page to derive background state from */
initialPage?: TourPageData | null;
}
export interface UsePageBackgroundResult {
/** Current background state */
background: PageBackgroundState;
/** Set entire background state */
setBackground: React.Dispatch<React.SetStateAction<PageBackgroundState>>;
/** Update background from page data */
updateFromPage: (page: TourPageData | null) => void;
/** Update individual URL */
setImageUrl: (url: string) => void;
setVideoUrl: (url: string) => void;
setAudioUrl: (url: string) => void;
/** Update video settings */
setVideoSettings: (settings: Partial<PageBackgroundVideoSettings>) => void;
/** Reset to default state */
reset: () => void;
// Legacy compatibility: individual values for backward compatibility
// These allow gradual migration of components
backgroundImageUrl: string;
backgroundVideoUrl: string;
backgroundAudioUrl: string;
backgroundVideoAutoplay: boolean;
backgroundVideoLoop: boolean;
backgroundVideoMuted: boolean;
backgroundVideoStartTime: number | null;
backgroundVideoEndTime: number | null;
}
/**
* Hook for managing consolidated page background state.
*
* @example
* ```typescript
* const {
* background,
* updateFromPage,
* setImageUrl,
* setVideoSettings,
* // Legacy compatibility
* backgroundImageUrl,
* backgroundVideoAutoplay,
* } = usePageBackground();
*
* // Update from page data
* updateFromPage(activePage);
*
* // Update individual values
* setImageUrl('path/to/image.jpg');
* setVideoSettings({ autoplay: false, loop: true });
* ```
*/
export function usePageBackground(
options: UsePageBackgroundOptions = {},
): UsePageBackgroundResult {
const { initialPage } = options;
const [background, setBackground] = useState<PageBackgroundState>(() =>
initialPage
? createPageBackgroundFromPage(initialPage)
: { ...DEFAULT_PAGE_BACKGROUND },
);
const updateFromPage = useCallback((page: TourPageData | null) => {
setBackground(createPageBackgroundFromPage(page));
}, []);
const setImageUrl = useCallback((url: string) => {
setBackground((prev) => ({
...prev,
imageUrl: url,
}));
}, []);
const setVideoUrl = useCallback((url: string) => {
setBackground((prev) => ({
...prev,
videoUrl: url,
}));
}, []);
const setAudioUrl = useCallback((url: string) => {
setBackground((prev) => ({
...prev,
audioUrl: url,
}));
}, []);
const setVideoSettings = useCallback(
(settings: Partial<PageBackgroundVideoSettings>) => {
setBackground((prev) => ({
...prev,
videoSettings: {
...prev.videoSettings,
...settings,
},
}));
},
[],
);
const reset = useCallback(() => {
setBackground({ ...DEFAULT_PAGE_BACKGROUND });
}, []);
return {
// New consolidated state
background,
setBackground,
updateFromPage,
setImageUrl,
setVideoUrl,
setAudioUrl,
setVideoSettings,
reset,
// Legacy compatibility: flat values for gradual migration
backgroundImageUrl: background.imageUrl,
backgroundVideoUrl: background.videoUrl,
backgroundAudioUrl: background.audioUrl,
backgroundVideoAutoplay: background.videoSettings.autoplay,
backgroundVideoLoop: background.videoSettings.loop,
backgroundVideoMuted: background.videoSettings.muted,
backgroundVideoStartTime: background.videoSettings.startTime,
backgroundVideoEndTime: background.videoSettings.endTime,
};
}
export default usePageBackground;