import React from "react" import { useFavorites } from "@/features/app-state" import { useFiltersAdapter as useUnifiedFiltersAdapter } from "@/features/browser/hooks/use-resources" import { useDraggable } from "@/features/drag-drop" import { FilterPreview } from "@/features/filters/components/filter-preview" import { VideoFilter } from "@/features/filters/types/filters" import type { ListAdapter, PreviewComponentProps } from "../types/list" /** * Компонент превью для фильтров */ const FilterPreviewWrapper: React.FC> = ({ item: filter, size, viewMode, onClick, }) => { const handleClick = () => { onClick?.(filter) } // Используем DragDropManager для перетаскивания const dragProps = useDraggable( "filter", () => filter, () => ({ url: `/filters/${filter.name}.png`, // Preview URL if available width: 120, height: 80, }), ) // Для фильтров FilterPreview ожидает другие пропсы const previewSize = typeof size === "number" ? size : size.width const previewWidth = typeof size === "number" ? size : size.width const previewHeight = typeof size === "number" ? size : size.height if (viewMode === "list") { return (
{/* Filter preview thumbnail */}
{/* Filter Info */}
{filter.labels?.ru || filter.name}
{filter.description?.en || ""}
{/* Category */}
{filter.category}
{/* Complexity */}
{filter.complexity}
) } // Thumbnails mode - use the original FilterPreview component return (
) } /** * Функция для получения CSS-фильтра для превью */ function getFilterPreviewStyle(filter: VideoFilter): string { if (!filter.params) return "" const { brightness, contrast, saturation, hue, temperature, tint } = filter.params const filters = [] if (brightness !== undefined) filters.push(`brightness(${Math.max(0, 1 + brightness)})`) if (contrast !== undefined) filters.push(`contrast(${Math.max(0, contrast)})`) if (saturation !== undefined) filters.push(`saturate(${Math.max(0, saturation)})`) if (hue !== undefined) filters.push(`hue-rotate(${hue}deg)`) // Простая эмуляция температуры if (temperature !== undefined) { const tempValue = Math.abs(temperature) * 0.01 if (temperature > 0) { filters.push(`sepia(${Math.min(1, tempValue)})`) } else { filters.push(`hue-rotate(${temperature * 2}deg)`) } } if (tint !== undefined) filters.push(`hue-rotate(${tint}deg)`) return filters.join(" ") } /** * Хук для создания адаптера фильтров * Мигрирован на унифицированную систему browser-хуков */ export function useFiltersAdapter(): ListAdapter { const { isItemFavorite } = useFavorites() // Используем унифицированный адаптер с конфигурацией для фильтров const { items, loading, error, stats, ...restAdapter } = useUnifiedFiltersAdapter({ PreviewComponent: FilterPreviewWrapper, customHandlers: { getSortValue: (filter: VideoFilter, sortBy: string) => { switch (sortBy) { case "name": return filter.name.toLowerCase() case "category": return filter.category.toLowerCase() case "complexity": // Определяем порядок сложности: basic < intermediate < advanced const complexityOrder: Record = { basic: 0, intermediate: 1, advanced: 2 } return complexityOrder[filter.complexity || "basic"] default: return filter.name.toLowerCase() } }, getSearchableText: (filter: VideoFilter) => { const texts = [ filter.name, filter.labels?.ru || "", filter.labels?.en || "", filter.description?.en || "", filter.category, ...(filter.tags || []), ] return texts.filter(Boolean) }, getGroupValue: (filter: VideoFilter, groupBy: string) => { switch (groupBy) { case "category": return filter.category || "other" case "complexity": return filter.complexity || "basic" case "tags": // Группируем по первому тегу или "untagged" return filter.tags && filter.tags.length > 0 ? filter.tags[0] : "untagged" default: return "" } }, matchesFilter: (filter: VideoFilter, filterType: string) => { if (filterType === "all") return true // Фильтрация по сложности if (["basic", "intermediate", "advanced"].includes(filterType)) { return (filter.complexity || "basic") === filterType } // Фильтрация по категории if (["color-correction", "creative", "cinematic", "vintage", "technical", "artistic"].includes(filterType)) { return filter.category === filterType } return true }, }, }) return { ...restAdapter, // Данные с правильной типизацией useData: () => ({ items: items as VideoFilter[], loading, error: error ? new Error(error) : null, }), // Компонент превью PreviewComponent: FilterPreviewWrapper, // Проверка избранного (переопределяем) isFavorite: (filter: VideoFilter) => isItemFavorite(filter, "filter"), } }