import { useMemo } from "react" import { useTranslation } from "react-i18next" import { ApplyButton } from "@/features/browser" import { useResources } from "@/features/resources" import { SubtitleResource } from "@/features/resources/types" import { AddMediaButton } from "../../browser/components/layout/add-media-button" import { FavoriteButton } from "../../browser/components/layout/favorite-button" import { SubtitleStyleTemplate } from "../types/subtitles" import { subtitleStyleToCSS } from "../utils/css-styles" /** * Интерфейс пропсов для компонента SubtitlePreview */ interface SubtitlePreviewProps { style: SubtitleStyleTemplate onClick: () => void size: number previewWidth?: number previewHeight?: number } /** * Компонент для отображения превью стиля субтитров * Показывает текст с применённым стилем и позволяет добавить стиль в проект * * @param {SubtitlePreviewProps} props - Пропсы компонента * @returns {JSX.Element} Компонент превью стиля субтитров */ export function SubtitlePreview({ style, onClick, size, previewWidth, previewHeight }: SubtitlePreviewProps) { const { t } = useTranslation() // Хук для интернационализации const { addSubtitle, isSubtitleAdded, removeResource, subtitleResources } = useResources() // Получаем методы для работы с ресурсами // Проверяем, добавлен ли стиль уже в хранилище ресурсов // Мемоизируем результат для оптимизации const isAdded = useMemo(() => { return isSubtitleAdded(style) }, [isSubtitleAdded, style]) // Мемоизируем CSS стили для превью const cssStyle = useMemo(() => { return subtitleStyleToCSS(style) }, [style]) // Мемоизируем функции для индикаторов const getComplexityColor = useMemo(() => { return (complexity: string) => { switch (complexity) { case "basic": return "bg-green-500" case "intermediate": return "bg-yellow-500" case "advanced": return "bg-red-500" default: return "bg-gray-500" } } }, []) const getCategoryAbbreviation = useMemo(() => { return (category: string) => { switch (category) { case "basic": return "BAS" case "cinematic": return "CIN" case "stylized": return "STY" case "minimal": return "MIN" case "animated": return "ANI" case "modern": return "MOD" default: return "SUB" } } }, []) // Мемоизируем стили для текста const textStyle = useMemo(() => { return { ...cssStyle, // Адаптируем размер шрифта под размер превью fontSize: cssStyle.fontSize ? `${Math.min(Number.parseInt(cssStyle.fontSize.toString()) * ((previewWidth ?? size) / 200), Number.parseInt(cssStyle.fontSize.toString()))}px` : `${Math.max(12, (previewWidth ?? size) / 10)}px`, } }, [cssStyle, previewWidth]) // Мемоизируем объекты для кнопок const fileObject = useMemo( () => ({ id: style.id, type: "subtitle", name: style.name, }), [style.id, style.name], ) return (
{/* Контейнер превью стиля субтитров */}
{/* Текст для демонстрации стиля */}
Timeline Studio
{/* Индикатор сложности слева */} {/*
*/} {/* Индикатор категории справа */}
{getCategoryAbbreviation(style.category)}
{/* Кнопка добавления в избранное */} {/* Кнопка удаления стиля из проекта */} {/* Кнопка добавления стиля в проект */}
{/* Индикатор анимации (если есть) */} {style.style.animation && (
ANI
)}
{/* Название стиля */}
{style.labels?.ru || style.name}
) }