Files
ViGent2/frontend/src/features/home/model/useTitleSubtitleStyles.ts
Kevin Wong 1a291a03b8 更新
2026-02-08 10:46:08 +08:00

104 lines
3.0 KiB
TypeScript

import { useCallback, useEffect, useState } from "react";
import api from "@/shared/api/axios";
import { ApiResponse, unwrap } from "@/shared/api/types";
export interface SubtitleStyleOption {
id: string;
label: string;
font_family?: string;
font_file?: string;
font_size?: number;
highlight_color?: string;
normal_color?: string;
stroke_color?: string;
stroke_size?: number;
letter_spacing?: number;
bottom_margin?: number;
is_default?: boolean;
}
export interface TitleStyleOption {
id: string;
label: string;
font_family?: string;
font_file?: string;
font_size?: number;
color?: string;
stroke_color?: string;
stroke_size?: number;
letter_spacing?: number;
font_weight?: number;
top_margin?: number;
is_default?: boolean;
}
interface UseTitleSubtitleStylesOptions {
isAuthLoading: boolean;
setSelectedSubtitleStyleId: React.Dispatch<React.SetStateAction<string>>;
setSelectedTitleStyleId: React.Dispatch<React.SetStateAction<string>>;
}
export const useTitleSubtitleStyles = ({
isAuthLoading,
setSelectedSubtitleStyleId,
setSelectedTitleStyleId,
}: UseTitleSubtitleStylesOptions) => {
const [subtitleStyles, setSubtitleStyles] = useState<SubtitleStyleOption[]>([]);
const [titleStyles, setTitleStyles] = useState<TitleStyleOption[]>([]);
const refreshSubtitleStyles = useCallback(async () => {
try {
const { data: res } = await api.get<ApiResponse<{ styles: SubtitleStyleOption[] }>>(
'/api/assets/subtitle-styles'
);
const payload = unwrap(res);
const styles: SubtitleStyleOption[] = payload.styles || [];
setSubtitleStyles(styles);
setSelectedSubtitleStyleId((prev) => {
if (prev && styles.some((s) => s.id === prev)) return prev;
const defaultStyle = styles.find((s) => s.is_default) || styles[0];
return defaultStyle?.id || "";
});
} catch (error) {
console.error("获取字幕样式失败:", error);
}
}, [setSelectedSubtitleStyleId]);
const refreshTitleStyles = useCallback(async () => {
try {
const { data: res } = await api.get<ApiResponse<{ styles: TitleStyleOption[] }>>(
'/api/assets/title-styles'
);
const payload = unwrap(res);
const styles: TitleStyleOption[] = payload.styles || [];
setTitleStyles(styles);
setSelectedTitleStyleId((prev) => {
if (prev && styles.some((s) => s.id === prev)) return prev;
const defaultStyle = styles.find((s) => s.is_default) || styles[0];
return defaultStyle?.id || "";
});
} catch (error) {
console.error("获取标题样式失败:", error);
}
}, [setSelectedTitleStyleId]);
useEffect(() => {
if (isAuthLoading) return;
// eslint-disable-next-line react-hooks/set-state-in-effect
refreshSubtitleStyles();
// eslint-disable-next-line react-hooks/set-state-in-effect
refreshTitleStyles();
}, [isAuthLoading, refreshSubtitleStyles, refreshTitleStyles]);
return {
subtitleStyles,
titleStyles,
refreshSubtitleStyles,
refreshTitleStyles,
};
};