"use client"; import { Input } from "@/components/ui/input"; import { useState, useMemo, useEffect } from "react"; import { Separator } from "@/components/ui/separator"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { PlayIcon, PauseIcon, HeartIcon, PlusIcon, ListFilter, } from "lucide-react"; import { useSoundsStore } from "@/stores/sounds-store"; import { useSoundSearch } from "@/hooks/use-sound-search"; import type { SoundEffect, SavedSound } from "@/types/sounds"; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuCheckboxItem, } from "@/components/ui/dropdown-menu"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { cn } from "@/lib/utils"; import { useInfiniteScroll } from "@/hooks/use-infinite-scroll"; export function SoundsView() { return (
Sound effects Songs Saved
); } function SoundEffectsView() { const { topSoundEffects, isLoading, searchQuery, setSearchQuery, scrollPosition, setScrollPosition, loadSavedSounds, isSoundSaved, toggleSavedSound, showCommercialOnly, toggleCommercialFilter, } = useSoundsStore(); const { results: searchResults, isLoading: isSearching, loadMore, hasNextPage, isLoadingMore, } = useSoundSearch(searchQuery, showCommercialOnly); // Audio playback state const [playingId, setPlayingId] = useState(null); const [audioElement, setAudioElement] = useState( null ); const { scrollAreaRef, handleScroll } = useInfiniteScroll({ onLoadMore: loadMore, hasMore: hasNextPage, isLoading: isLoadingMore || isSearching, }); useEffect(() => { loadSavedSounds(); if (scrollAreaRef.current && scrollPosition > 0) { const timeoutId = setTimeout(() => { scrollAreaRef.current?.scrollTo({ top: scrollPosition }); }, 100); return () => clearTimeout(timeoutId); } }, []); const handleScrollWithPosition = (event: React.UIEvent) => { const { scrollTop } = event.currentTarget; setScrollPosition(scrollTop); handleScroll(event); }; const displayedSounds = useMemo(() => { const sounds = searchQuery ? searchResults : topSoundEffects; return sounds; }, [searchQuery, searchResults, topSoundEffects]); const playSound = (sound: SoundEffect) => { if (playingId === sound.id) { audioElement?.pause(); setPlayingId(null); return; } // Stop previous sound audioElement?.pause(); if (sound.previewUrl) { const audio = new Audio(sound.previewUrl); audio.addEventListener("ended", () => { setPlayingId(null); }); audio.addEventListener("error", (e) => { setPlayingId(null); }); audio.play().catch((error) => { setPlayingId(null); }); setAudioElement(audio); setPlayingId(sound.id); } }; return (
setSearchQuery(e.target.value)} showClearIcon onClear={() => setSearchQuery("")} /> Show only commercially licensed
{showCommercialOnly ? "Only showing sounds licensed for commercial use" : "Showing all sounds regardless of license"}
{isLoading && !searchQuery && (
Loading sounds...
)} {isSearching && searchQuery && (
Searching...
)} {displayedSounds.map((sound) => ( playSound(sound)} isSaved={isSoundSaved(sound.id)} onToggleSaved={() => toggleSavedSound(sound)} /> ))} {!isLoading && !isSearching && displayedSounds.length === 0 && (
{searchQuery ? "No sounds found" : "No sounds available"}
)} {isLoadingMore && (
Loading more sounds...
)}
); } function SavedSoundsView() { const { savedSounds, isLoadingSavedSounds, savedSoundsError, loadSavedSounds, isSoundSaved, toggleSavedSound, clearSavedSounds, } = useSoundsStore(); // Audio playback state const [playingId, setPlayingId] = useState(null); const [audioElement, setAudioElement] = useState( null ); // Clear confirmation dialog state const [showClearDialog, setShowClearDialog] = useState(false); // Load saved sounds when tab becomes active useEffect(() => { loadSavedSounds(); }, [loadSavedSounds]); const playSound = (sound: SavedSound) => { if (playingId === sound.id) { audioElement?.pause(); setPlayingId(null); return; } // Stop previous sound audioElement?.pause(); if (sound.previewUrl) { const audio = new Audio(sound.previewUrl); audio.addEventListener("ended", () => { setPlayingId(null); }); audio.addEventListener("error", (e) => { setPlayingId(null); }); audio.play().catch((error) => { setPlayingId(null); }); setAudioElement(audio); setPlayingId(sound.id); } }; // Convert SavedSound to SoundEffect for compatibility with AudioItem const convertToSoundEffect = (savedSound: SavedSound): SoundEffect => ({ id: savedSound.id, name: savedSound.name, description: "", url: "", previewUrl: savedSound.previewUrl, downloadUrl: savedSound.downloadUrl, duration: savedSound.duration, filesize: 0, type: "audio", channels: 0, bitrate: 0, bitdepth: 0, samplerate: 0, username: savedSound.username, tags: savedSound.tags, license: savedSound.license, created: savedSound.savedAt, downloads: 0, rating: 0, ratingCount: 0, }); if (isLoadingSavedSounds) { return (
Loading saved sounds...
); } if (savedSoundsError) { return (
Error: {savedSoundsError}
); } if (savedSounds.length === 0) { return (

No saved sounds

Click the heart icon on any sound to save it here

); } return (

{savedSounds.length} saved{" "} {savedSounds.length === 1 ? "sound" : "sounds"}

Clear all saved sounds? This will permanently remove all {savedSounds.length} saved sounds from your collection. This action cannot be undone.
{savedSounds.map((sound) => ( playSound(sound)} isSaved={isSoundSaved(sound.id)} onToggleSaved={() => toggleSavedSound(convertToSoundEffect(sound)) } /> ))}
); } function SongsView() { return
Songs
; } interface AudioItemProps { sound: SoundEffect; isPlaying: boolean; onPlay: () => void; isSaved: boolean; onToggleSaved: () => void; } function AudioItem({ sound, isPlaying, onPlay, isSaved, onToggleSaved, }: AudioItemProps) { const { addSoundToTimeline } = useSoundsStore(); const handleClick = () => { onPlay(); }; const handleSaveClick = (e: React.MouseEvent) => { e.stopPropagation(); onToggleSaved(); }; const handleAddToTimeline = async (e: React.MouseEvent) => { e.stopPropagation(); await addSoundToTimeline(sound); }; return (
{isPlaying ? ( ) : ( )}

{sound.name}

{sound.username}
); }