'use client'; import { useState, useEffect } from 'react'; import { PageControls } from '../shared/page-controls'; import { PageWrapper } from '../shared/page-wrapper'; import { SettingsCard } from '../shared/settings-card'; import { Select } from '../ui/select'; import { useUserData } from '@/context/userData'; import { IconButton } from '../ui/button'; import { Combobox } from '../ui/combobox'; import { SORT_CRITERIA, SORT_CRITERIA_DETAILS, SORT_DIRECTIONS, } from '../../../../core/src/utils/constants'; import { DndContext, useSensors, useSensor, PointerSensor, TouchSensor, } from '@dnd-kit/core'; import { SortableContext, useSortable, arrayMove, verticalListSortingStrategy, } from '@dnd-kit/sortable'; import { restrictToVerticalAxis } from '@dnd-kit/modifiers'; import { CSS } from '@dnd-kit/utilities'; import { ArrowDownAZ, ArrowUpAZ } from 'lucide-react'; import { Accordion, AccordionTrigger, AccordionContent, AccordionItem, } from '../ui/accordion'; export function SortingMenu() { return ( <> ); } function SortableItem({ id, name, description, direction, onDirectionChange, }: { id: string; name: string; description: string; direction: (typeof SORT_DIRECTIONS)[number]; onDirectionChange: () => void; }) { const { attributes, listeners, setNodeRef, transform, transition, isDragging, } = useSortable({ id }); const style = { transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.5 : 1, }; return (
{name} {description}
: } intent="primary-subtle" onClick={onDirectionChange} />
); } function Content() { const [currentSortType, setCurrentSortType] = useState('global'); const { userData, setUserData } = useUserData(); const [isDragging, setIsDragging] = useState(false); type SortCriteriaItem = { key: (typeof SORT_CRITERIA)[number]; direction: (typeof SORT_DIRECTIONS)[number]; }; type SortCriteriaType = { global: SortCriteriaItem[]; series: SortCriteriaItem[]; movies: SortCriteriaItem[]; cached: SortCriteriaItem[]; uncached: SortCriteriaItem[]; }; // Initialize sortCriteria if it doesn't exist useEffect(() => { if (!userData.sortCriteria) { setUserData((prev) => ({ ...prev, sortCriteria: { global: [], series: [], movies: [], cached: [], uncached: [], cachedMovies: [], uncachedMovies: [], cachedSeries: [], uncachedSeries: [], }, })); } }, []); const currentSortCriteria = (userData.sortCriteria?.[ currentSortType as keyof SortCriteriaType ] || []) as SortCriteriaItem[]; const getSortCriteriaDetails = (key: (typeof SORT_CRITERIA)[number]) => { return SORT_CRITERIA_DETAILS[key]; }; const sensors = useSensors( useSensor(PointerSensor), useSensor(TouchSensor, { activationConstraint: { delay: 150, tolerance: 8, }, }) ); function handleDragEnd(event: any) { const { active, over } = event; if (!over) return; if (active.id !== over.id) { const oldIndex = currentSortCriteria.findIndex( (item) => `${item.key}-${item.direction}` === active.id ); const newIndex = currentSortCriteria.findIndex( (item) => `${item.key}-${item.direction}` === over.id ); const newSortCriteria = arrayMove( currentSortCriteria, oldIndex, newIndex ); setUserData((prev) => ({ ...prev, sortCriteria: { ...(prev.sortCriteria || {}), [currentSortType]: newSortCriteria, }, })); } setIsDragging(false); } function handleDragStart() { setIsDragging(true); } useEffect(() => { function preventTouchMove(e: TouchEvent) { if (isDragging) { e.preventDefault(); } } if (isDragging) { document.body.addEventListener('touchmove', preventTouchMove, { passive: false, }); } else { document.body.removeEventListener('touchmove', preventTouchMove); } return () => { document.body.removeEventListener('touchmove', preventTouchMove); }; }, [isDragging]); return ( <>

Sorting

Configure how your content is sorted and organized.

How Sorting Works

The sorting system uses a hierarchical approach to determine how content is sorted:

  1. Primary Sorts: Define the main sorting order for different content types:
    • Global: Used as a fallback when no specific type sort is defined (You most likely just want to define this and ignore everything else.)
    • Movies: Specific sorting for movies
    • Series: Specific sorting for TV series
    • Anime: Specific sorting for anime content
  2. Cached/Uncached Sorting: {' '} If your primary sort has "cached" at the top:
    • Content is split into cached and uncached groups
    • Each group is sorted separately using its specific sort criteria
    • Groups are then combined based on the cached sort direction
    • Type-specific cached/uncached sorts (e.g., "Cached Movies") take priority over global cached/uncached sorts

Note: The system will use the most specific sort criteria available for the content type and cache status.