import { Bookmark, CheckSquare, ChevronLeft, ChevronRight, Download, Filter, Folder, PlayCircle, Plus, RefreshCw, Search, StickyNote, X, } from "lucide-react" import React, { useMemo, useState } from "react" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { Input } from "@/components/ui/input" import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover" import { useTimeline } from "../../hooks/use-timeline" import { useTimelineMarkers } from "../../hooks/use-timeline-markers" import type { MarkerFilter, MarkerType } from "../../types/markers" import { MarkerColors } from "../../types/markers" const markerTypeOptions: { value: MarkerType; label: string; icon: React.ReactNode }[] = [ { value: "chapter", label: "Chapter", icon: }, { value: "section", label: "Section", icon: }, { value: "note", label: "Note", icon: }, { value: "export", label: "Export", icon: }, { value: "todo", label: "Todo", icon: }, { value: "sync", label: "Sync", icon: }, { value: "cue", label: "Cue", icon: }, ] export function MarkerControls() { const { currentTime, seek } = useTimeline() const { markers, addMarker } = useTimelineMarkers() // State variables const [isFilterOpen, setIsFilterOpen] = useState(false) const [searchQuery, setSearchQuery] = useState("") const [selectedTypes, setSelectedTypes] = useState([]) const [newMarkerName, setNewMarkerName] = useState("") const [newMarkerType, setNewMarkerType] = useState("note") // Локальная логика для фильтрации и навигации const filteredMarkers = useMemo(() => { let filtered = markers if (searchQuery) { filtered = filtered.filter((marker) => marker.name.toLowerCase().includes(searchQuery.toLowerCase())) } if (selectedTypes.length > 0) { filtered = filtered.filter((marker) => selectedTypes.includes(marker.type!)) } return filtered }, [markers, searchQuery, selectedTypes]) const goToNextMarker = () => { const sortedMarkers = [...markers].sort((a, b) => a.time - b.time) const nextMarker = sortedMarkers.find((marker) => marker.time > currentTime) if (nextMarker) { void seek(nextMarker.time) } } const goToPreviousMarker = () => { const sortedMarkers = [...markers].sort((a, b) => b.time - a.time) const prevMarker = sortedMarkers.find((marker) => marker.time < currentTime) if (prevMarker) { void seek(prevMarker.time) } } const setFilter = (filter: { query?: string; types?: MarkerType[] }) => { if (filter.query !== undefined) setSearchQuery(filter.query) if (filter.types !== undefined) setSelectedTypes(filter.types) } const clearFilter = () => { setSearchQuery("") setSelectedTypes([]) } const handleAddMarker = () => { if (!newMarkerName.trim()) return addMarker({ time: currentTime, name: newMarkerName, type: newMarkerType, color: MarkerColors[newMarkerType], }) setNewMarkerName("") } const handleTypeToggle = (type: MarkerType) => { const newTypes = selectedTypes.includes(type) ? selectedTypes.filter((t) => t !== type) : [...selectedTypes, type] setSelectedTypes(newTypes) updateFilter({ types: newTypes.length > 0 ? newTypes : undefined }) } const handleSearch = (query: string) => { setSearchQuery(query) updateFilter({ search: query || undefined }) } const updateFilter = (updates: Partial) => { const filter: MarkerFilter = {} if (selectedTypes.length > 0) { filter.types = selectedTypes } if (searchQuery) { filter.search = searchQuery } setFilter({ ...filter, ...updates }) } const handleClearFilter = () => { setSelectedTypes([]) setSearchQuery("") clearFilter() setIsFilterOpen(false) } const activeFilterCount = selectedTypes.length + (searchQuery ? 1 : 0) return ( {/* Add marker */} Add Marker Add Marker Create a marker at current time setNewMarkerName(e.target.value)} placeholder="Marker name" onKeyDown={(e) => { if (e.key === "Enter") { handleAddMarker() } }} /> {markerTypeOptions.find((t) => t.value === newMarkerType)?.icon} {markerTypeOptions.find((t) => t.value === newMarkerType)?.label} {markerTypeOptions.map((type) => ( setNewMarkerType(type.value)}> {type.icon} {type.label} ))} Add Marker {/* Navigation */} {filteredMarkers.length} / {markers.length} {/* Filter */} Filter {activeFilterCount > 0 && ( {activeFilterCount} )} Filter Markers {activeFilterCount > 0 && ( Clear all )} {/* Search */} handleSearch(e.target.value)} placeholder="Search markers..." className="pl-8" /> {searchQuery && ( handleSearch("")} > )} {/* Type filter */} Marker Types {markerTypeOptions.map((type) => ( handleTypeToggle(type.value)} className="rounded" /> {type.icon} {type.label} ))} ) }
Create a marker at current time