diff options
| author | enkei64 <imenkei64@gmail.com> | 2025-08-15 10:11:21 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-15 02:11:21 +0200 |
| commit | c3f3345d7b1ac820b411a5adbca3172378642953 (patch) | |
| tree | 6d80ca38eb908574ab97a2b1e1d30166a72b8b76 /apps/web/src/components/editor/media-panel/views/sounds.tsx | |
| parent | defff2fc46978072f2ead822cf8bbd34f7629192 (diff) | |
| download | opencut-c3f3345d7b1ac820b411a5adbca3172378642953.tar.gz | |
feat: stickers panel (#539)
* Stickers panel base complete
* Improve dark mode stickers background for visibility
* Prevent stickers from being too small or too big
* Improve UI, added credit for Iconify API
* Allow manually loading more collections
* Add a maximum width of 200px so stickers aren't too big
* cleanup
* style: hover state of button
* refactor: input component
* fix: mark input component as client
* so much stuff
---------
Co-authored-by: Maze Winther <mazewinther@gmail.com>
Diffstat (limited to 'apps/web/src/components/editor/media-panel/views/sounds.tsx')
| -rw-r--r-- | apps/web/src/components/editor/media-panel/views/sounds.tsx | 32 |
1 files changed, 14 insertions, 18 deletions
diff --git a/apps/web/src/components/editor/media-panel/views/sounds.tsx b/apps/web/src/components/editor/media-panel/views/sounds.tsx index ed0db8ab..303eb858 100644 --- a/apps/web/src/components/editor/media-panel/views/sounds.tsx +++ b/apps/web/src/components/editor/media-panel/views/sounds.tsx @@ -1,7 +1,7 @@ "use client"; import { Input } from "@/components/ui/input"; -import { useState, useMemo, useRef, useEffect } from "react"; +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"; @@ -32,6 +32,7 @@ import { DialogTrigger, } from "@/components/ui/dialog"; import { cn } from "@/lib/utils"; +import { useInfiniteScroll } from "@/hooks/use-infinite-scroll"; export function SoundsView() { return ( @@ -96,35 +97,30 @@ function SoundEffectsView() { null ); - // Scroll position persistence - const scrollAreaRef = useRef<HTMLDivElement>(null); + const { scrollAreaRef, handleScroll } = useInfiniteScroll({ + onLoadMore: loadMore, + hasMore: hasNextPage, + isLoading: isLoadingMore || isSearching, + }); - // Load saved sounds and restore scroll position when component mounts useEffect(() => { loadSavedSounds(); if (scrollAreaRef.current && scrollPosition > 0) { const timeoutId = setTimeout(() => { scrollAreaRef.current?.scrollTo({ top: scrollPosition }); - }, 100); // Small delay to ensure content is rendered + }, 100); return () => clearTimeout(timeoutId); } - }, []); // Only run on mount + }, []); - // Track scroll position changes and handle infinite scroll - const handleScroll = (event: React.UIEvent<HTMLDivElement>) => { - const { scrollTop, scrollHeight, clientHeight } = event.currentTarget; + const handleScrollWithPosition = (event: React.UIEvent<HTMLDivElement>) => { + const { scrollTop } = event.currentTarget; setScrollPosition(scrollTop); - - // Trigger loadMore when scrolled to within 200px of bottom - const nearBottom = scrollTop + clientHeight >= scrollHeight - 200; - if (nearBottom && hasNextPage && !isLoadingMore && !isSearching) { - loadMore(); - } + handleScroll(event); }; - - // Use your existing design, just swap the data source + const displayedSounds = useMemo(() => { const sounds = searchQuery ? searchResults : topSoundEffects; return sounds; @@ -199,7 +195,7 @@ function SoundEffectsView() { <ScrollArea className="flex-1 h-full" ref={scrollAreaRef} - onScrollCapture={handleScroll} + onScrollCapture={handleScrollWithPosition} > <div className="flex flex-col gap-4"> {isLoading && !searchQuery && ( |
