254 lines
8.4 KiB
TypeScript
254 lines
8.4 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
|
|
const TITLE_MAX_LENGTH = 15;
|
|
const clampTitle = (value: string) => value.slice(0, TITLE_MAX_LENGTH);
|
|
|
|
interface RefAudio {
|
|
id: string;
|
|
name: string;
|
|
path: string;
|
|
ref_text: string;
|
|
duration_sec: number;
|
|
created_at: number;
|
|
}
|
|
|
|
interface UseHomePersistenceOptions {
|
|
isAuthLoading: boolean;
|
|
storageKey: string;
|
|
text: string;
|
|
setText: React.Dispatch<React.SetStateAction<string>>;
|
|
videoTitle: string;
|
|
setVideoTitle: React.Dispatch<React.SetStateAction<string>>;
|
|
enableSubtitles: boolean;
|
|
setEnableSubtitles: React.Dispatch<React.SetStateAction<boolean>>;
|
|
ttsMode: 'edgetts' | 'voiceclone';
|
|
setTtsMode: React.Dispatch<React.SetStateAction<'edgetts' | 'voiceclone'>>;
|
|
voice: string;
|
|
setVoice: React.Dispatch<React.SetStateAction<string>>;
|
|
selectedMaterial: string;
|
|
setSelectedMaterial: React.Dispatch<React.SetStateAction<string>>;
|
|
selectedSubtitleStyleId: string;
|
|
setSelectedSubtitleStyleId: React.Dispatch<React.SetStateAction<string>>;
|
|
selectedTitleStyleId: string;
|
|
setSelectedTitleStyleId: React.Dispatch<React.SetStateAction<string>>;
|
|
subtitleFontSize: number;
|
|
setSubtitleFontSize: React.Dispatch<React.SetStateAction<number>>;
|
|
titleFontSize: number;
|
|
setTitleFontSize: React.Dispatch<React.SetStateAction<number>>;
|
|
setSubtitleSizeLocked: React.Dispatch<React.SetStateAction<boolean>>;
|
|
setTitleSizeLocked: React.Dispatch<React.SetStateAction<boolean>>;
|
|
selectedBgmId: string;
|
|
setSelectedBgmId: React.Dispatch<React.SetStateAction<string>>;
|
|
bgmVolume: number;
|
|
setBgmVolume: React.Dispatch<React.SetStateAction<number>>;
|
|
enableBgm: boolean;
|
|
setEnableBgm: React.Dispatch<React.SetStateAction<boolean>>;
|
|
selectedVideoId: string | null;
|
|
setSelectedVideoId: React.Dispatch<React.SetStateAction<string | null>>;
|
|
selectedRefAudio: RefAudio | null;
|
|
}
|
|
|
|
export const useHomePersistence = ({
|
|
isAuthLoading,
|
|
storageKey,
|
|
text,
|
|
setText,
|
|
videoTitle,
|
|
setVideoTitle,
|
|
enableSubtitles,
|
|
setEnableSubtitles,
|
|
ttsMode,
|
|
setTtsMode,
|
|
voice,
|
|
setVoice,
|
|
selectedMaterial,
|
|
setSelectedMaterial,
|
|
selectedSubtitleStyleId,
|
|
setSelectedSubtitleStyleId,
|
|
selectedTitleStyleId,
|
|
setSelectedTitleStyleId,
|
|
subtitleFontSize,
|
|
setSubtitleFontSize,
|
|
titleFontSize,
|
|
setTitleFontSize,
|
|
setSubtitleSizeLocked,
|
|
setTitleSizeLocked,
|
|
selectedBgmId,
|
|
setSelectedBgmId,
|
|
bgmVolume,
|
|
setBgmVolume,
|
|
enableBgm,
|
|
setEnableBgm,
|
|
selectedVideoId,
|
|
setSelectedVideoId,
|
|
selectedRefAudio,
|
|
}: UseHomePersistenceOptions) => {
|
|
const [isRestored, setIsRestored] = useState(false);
|
|
|
|
useEffect(() => {
|
|
if (isAuthLoading) return;
|
|
|
|
const savedText = localStorage.getItem(`vigent_${storageKey}_text`);
|
|
const savedTitle = localStorage.getItem(`vigent_${storageKey}_title`);
|
|
const savedSubtitles = localStorage.getItem(`vigent_${storageKey}_subtitles`);
|
|
const savedTtsMode = localStorage.getItem(`vigent_${storageKey}_ttsMode`);
|
|
const savedVoice = localStorage.getItem(`vigent_${storageKey}_voice`);
|
|
const savedMaterial = localStorage.getItem(`vigent_${storageKey}_material`);
|
|
const savedSubtitleStyle = localStorage.getItem(`vigent_${storageKey}_subtitleStyle`);
|
|
const savedTitleStyle = localStorage.getItem(`vigent_${storageKey}_titleStyle`);
|
|
const savedSubtitleFontSize = localStorage.getItem(`vigent_${storageKey}_subtitleFontSize`);
|
|
const savedTitleFontSize = localStorage.getItem(`vigent_${storageKey}_titleFontSize`);
|
|
const savedBgmId = localStorage.getItem(`vigent_${storageKey}_bgmId`);
|
|
const savedSelectedVideoId = localStorage.getItem(`vigent_${storageKey}_selectedVideoId`);
|
|
const savedBgmVolume = localStorage.getItem(`vigent_${storageKey}_bgmVolume`);
|
|
const savedEnableBgm = localStorage.getItem(`vigent_${storageKey}_enableBgm`);
|
|
|
|
setText(savedText || "大家好,欢迎来到我的频道,今天给大家分享一些有趣的内容。");
|
|
setVideoTitle(savedTitle ? clampTitle(savedTitle) : "");
|
|
setEnableSubtitles(savedSubtitles !== null ? savedSubtitles === 'true' : true);
|
|
setTtsMode((savedTtsMode as 'edgetts' | 'voiceclone') || 'edgetts');
|
|
setVoice(savedVoice || "zh-CN-YunxiNeural");
|
|
|
|
if (savedMaterial) setSelectedMaterial(savedMaterial);
|
|
if (savedSubtitleStyle) setSelectedSubtitleStyleId(savedSubtitleStyle);
|
|
if (savedTitleStyle) setSelectedTitleStyleId(savedTitleStyle);
|
|
|
|
if (savedSubtitleFontSize) {
|
|
const parsed = parseInt(savedSubtitleFontSize, 10);
|
|
if (!Number.isNaN(parsed)) {
|
|
setSubtitleFontSize(parsed);
|
|
setSubtitleSizeLocked(true);
|
|
}
|
|
}
|
|
|
|
if (savedTitleFontSize) {
|
|
const parsed = parseInt(savedTitleFontSize, 10);
|
|
if (!Number.isNaN(parsed)) {
|
|
setTitleFontSize(parsed);
|
|
setTitleSizeLocked(true);
|
|
}
|
|
}
|
|
|
|
if (savedBgmId) setSelectedBgmId(savedBgmId);
|
|
if (savedBgmVolume) setBgmVolume(parseFloat(savedBgmVolume));
|
|
if (savedEnableBgm !== null) setEnableBgm(savedEnableBgm === 'true');
|
|
if (savedSelectedVideoId) setSelectedVideoId(savedSelectedVideoId);
|
|
|
|
setIsRestored(true);
|
|
}, [
|
|
isAuthLoading,
|
|
setBgmVolume,
|
|
setEnableBgm,
|
|
setEnableSubtitles,
|
|
setSelectedBgmId,
|
|
setSelectedMaterial,
|
|
setSelectedSubtitleStyleId,
|
|
setSelectedTitleStyleId,
|
|
setSelectedVideoId,
|
|
setSubtitleFontSize,
|
|
setSubtitleSizeLocked,
|
|
setText,
|
|
setTitleFontSize,
|
|
setTitleSizeLocked,
|
|
setTtsMode,
|
|
setVideoTitle,
|
|
setVoice,
|
|
storageKey,
|
|
]);
|
|
|
|
useEffect(() => {
|
|
if (!isRestored) return;
|
|
const timeout = setTimeout(() => {
|
|
localStorage.setItem(`vigent_${storageKey}_text`, text);
|
|
}, 300);
|
|
return () => clearTimeout(timeout);
|
|
}, [text, storageKey, isRestored]);
|
|
|
|
useEffect(() => {
|
|
if (!isRestored) return;
|
|
const timeout = setTimeout(() => {
|
|
localStorage.setItem(`vigent_${storageKey}_title`, videoTitle);
|
|
}, 300);
|
|
return () => clearTimeout(timeout);
|
|
}, [videoTitle, storageKey, isRestored]);
|
|
|
|
useEffect(() => {
|
|
if (isRestored) localStorage.setItem(`vigent_${storageKey}_subtitles`, String(enableSubtitles));
|
|
}, [enableSubtitles, storageKey, isRestored]);
|
|
|
|
useEffect(() => {
|
|
if (isRestored) localStorage.setItem(`vigent_${storageKey}_ttsMode`, ttsMode);
|
|
}, [ttsMode, storageKey, isRestored]);
|
|
|
|
useEffect(() => {
|
|
if (isRestored) localStorage.setItem(`vigent_${storageKey}_voice`, voice);
|
|
}, [voice, storageKey, isRestored]);
|
|
|
|
useEffect(() => {
|
|
if (isRestored && selectedMaterial) {
|
|
localStorage.setItem(`vigent_${storageKey}_material`, selectedMaterial);
|
|
}
|
|
}, [selectedMaterial, storageKey, isRestored]);
|
|
|
|
useEffect(() => {
|
|
if (isRestored && selectedSubtitleStyleId) {
|
|
localStorage.setItem(`vigent_${storageKey}_subtitleStyle`, selectedSubtitleStyleId);
|
|
}
|
|
}, [selectedSubtitleStyleId, storageKey, isRestored]);
|
|
|
|
useEffect(() => {
|
|
if (isRestored && selectedTitleStyleId) {
|
|
localStorage.setItem(`vigent_${storageKey}_titleStyle`, selectedTitleStyleId);
|
|
}
|
|
}, [selectedTitleStyleId, storageKey, isRestored]);
|
|
|
|
useEffect(() => {
|
|
if (isRestored) {
|
|
localStorage.setItem(`vigent_${storageKey}_subtitleFontSize`, String(subtitleFontSize));
|
|
}
|
|
}, [subtitleFontSize, storageKey, isRestored]);
|
|
|
|
useEffect(() => {
|
|
if (isRestored) {
|
|
localStorage.setItem(`vigent_${storageKey}_titleFontSize`, String(titleFontSize));
|
|
}
|
|
}, [titleFontSize, storageKey, isRestored]);
|
|
|
|
useEffect(() => {
|
|
if (isRestored) {
|
|
localStorage.setItem(`vigent_${storageKey}_bgmId`, selectedBgmId);
|
|
}
|
|
}, [selectedBgmId, storageKey, isRestored]);
|
|
|
|
useEffect(() => {
|
|
if (!isRestored) return;
|
|
const timeout = setTimeout(() => {
|
|
localStorage.setItem(`vigent_${storageKey}_bgmVolume`, String(bgmVolume));
|
|
}, 300);
|
|
return () => clearTimeout(timeout);
|
|
}, [bgmVolume, storageKey, isRestored]);
|
|
|
|
useEffect(() => {
|
|
if (isRestored) {
|
|
localStorage.setItem(`vigent_${storageKey}_enableBgm`, String(enableBgm));
|
|
}
|
|
}, [enableBgm, storageKey, isRestored]);
|
|
|
|
useEffect(() => {
|
|
if (!isRestored) return;
|
|
if (selectedVideoId) {
|
|
localStorage.setItem(`vigent_${storageKey}_selectedVideoId`, selectedVideoId);
|
|
} else {
|
|
localStorage.removeItem(`vigent_${storageKey}_selectedVideoId`);
|
|
}
|
|
}, [selectedVideoId, storageKey, isRestored]);
|
|
|
|
useEffect(() => {
|
|
if (isRestored && selectedRefAudio) {
|
|
localStorage.setItem(`vigent_${storageKey}_refAudioId`, selectedRefAudio.id);
|
|
}
|
|
}, [selectedRefAudio, storageKey, isRestored]);
|
|
|
|
return { isRestored };
|
|
};
|