import { useMemo } from "react" import { useTranslation } from "react-i18next" import { useBrowserState } from "@/features/browser/services/browser-state-provider" import { PREVIEW_SIZES } from "@/features/media/utils/preview-sizes" import { cn } from "@/lib/utils" import type { ListItem, UniversalListProps } from "../types/list" import { filterItems, groupItems, sortItems } from "../utils" import { ContentGroup } from "./content-group" import { NoFiles } from "./no-files" /** * Универсальный компонент списка для отображения любого типа контента * Использует адаптер для получения данных и их обработки */ export function UniversalList({ adapter, onItemSelect, onItemDragStart, className, }: UniversalListProps) { const { t } = useTranslation() // Получаем данные через адаптер const { items, loading, error } = adapter.useData() // Получаем настройки из состояния браузера const { currentTabSettings } = useBrowserState() const { searchQuery, showFavoritesOnly, viewMode, sortBy, filterType, groupBy, sortOrder, previewSizeIndex } = currentTabSettings // Получаем текущий размер превью const currentPreviewSize = PREVIEW_SIZES[previewSizeIndex] // Фильтрация и сортировка const processedItems = useMemo(() => { // Фильтрация const filtered = filterItems( items, { searchQuery, showFavoritesOnly, filterType }, adapter.getSearchableText, adapter.matchesFilter, adapter.isFavorite, ) // Сортировка const sorted = sortItems(filtered, sortBy, sortOrder, adapter.getSortValue) return sorted }, [ items, searchQuery, showFavoritesOnly, filterType, sortBy, sortOrder, adapter.getSearchableText, adapter.getSortValue, adapter.matchesFilter, adapter.isFavorite, ]) // Группировка const groupedItems = useMemo(() => { return groupItems(processedItems, groupBy, adapter.getGroupValue, sortOrder) }, [processedItems, groupBy, sortOrder, adapter.getGroupValue]) // Обработка состояний загрузки и ошибок if (loading) { return (
{t("common.loading")}
) } if (error) { return (
{t("common.error")}: {error.message}
) } // Если нет элементов if (items.length === 0) { // Получаем тип из адаптера для NoFiles компонента const mediaType = adapter.favoriteType === "media" ? "media" : adapter.favoriteType === "music" ? "music" : adapter.favoriteType === "effect" ? "effects" : adapter.favoriteType === "filter" ? "filters" : adapter.favoriteType === "transition" ? "transitions" : adapter.favoriteType === "template" ? "templates" : adapter.favoriteType === "styleTemplate" ? "style-templates" : adapter.favoriteType === "subtitle" ? "subtitles" : "media" return } // Если после фильтрации нет элементов if (processedItems.length === 0) { // Получаем тип из адаптера для NoFiles компонента const mediaType = adapter.favoriteType === "media" ? "media" : adapter.favoriteType === "music" ? "music" : adapter.favoriteType === "effect" ? "effects" : adapter.favoriteType === "filter" ? "filters" : adapter.favoriteType === "transition" ? "transitions" : adapter.favoriteType === "template" ? "templates" : adapter.favoriteType === "styleTemplate" ? "style-templates" : adapter.favoriteType === "subtitle" ? "subtitles" : "media" return (
) } // Рендерим группы return (
{groupedItems.map((group, index) => ( key={`${group.title}-${index}`} title={group.title} items={group.items} viewMode={viewMode} getItemKey={(item) => item.id} renderItem={(item) => ( {}} /> )} /> ))}
{/* StatusBar is only needed for media tab, skip it for other tabs */}
) }