mirror of
https://github.com/5rahim/seanime
synced 2026-04-18 22:24:55 +02:00
feat: search in library
This commit is contained in:
@@ -101,7 +101,7 @@ export function EpisodeCard(props: EpisodeCardProps) {
|
||||
|
||||
const Meta = () => (
|
||||
<div data-episode-card-info-container className="relative z-[3] w-full space-y-0">
|
||||
{topTitle !== title && <p
|
||||
{(topTitle !== title || showTotalEpisodes) && <p
|
||||
data-episode-card-title
|
||||
className={cn(
|
||||
"w-[80%] line-clamp-1 text-md md:text-lg transition-colors duration-200 text-[--foreground] font-semibold",
|
||||
|
||||
@@ -11,6 +11,7 @@ import { HomeSettingsButton } from "@/app/(main)/_features/home/home-settings-bu
|
||||
import { libraryExplorer_drawerOpenAtom } from "@/app/(main)/_features/library-explorer/library-explorer.atoms"
|
||||
import { useNakamaStatus } from "@/app/(main)/_features/nakama/nakama-manager"
|
||||
import { usePlaylistEditorManager } from "@/app/(main)/_features/playlists/lib/playlist-editor-manager"
|
||||
import { useSeaCommand } from "@/app/(main)/_features/sea-command/sea-command.tsx"
|
||||
import { useServerStatus } from "@/app/(main)/_hooks/use-server-status"
|
||||
import { SeaLink } from "@/components/shared/sea-link"
|
||||
import { Button, IconButton } from "@/components/ui/button"
|
||||
@@ -24,6 +25,7 @@ import React from "react"
|
||||
import { BiCollection, BiDotsVerticalRounded, BiFolder } from "react-icons/bi"
|
||||
import { HiExclamation } from "react-icons/hi"
|
||||
import { IoHome, IoLibraryOutline, IoLibrarySharp } from "react-icons/io5"
|
||||
import { LuSearch } from "react-icons/lu"
|
||||
import { LuFolderSearch, LuFolderSync, LuFolderTree } from "react-icons/lu"
|
||||
import { MdOutlineConnectWithoutContact, MdOutlineVideoLibrary } from "react-icons/md"
|
||||
import { TbFileSad, TbReportSearch } from "react-icons/tb"
|
||||
@@ -73,6 +75,8 @@ export function HomeToolbar(props: HomeToolbarProps) {
|
||||
|
||||
const { mutate: openInExplorer } = useOpenInExplorer()
|
||||
|
||||
const { setSeaCommandInput, setSeaCommandOpen } = useSeaCommand()
|
||||
|
||||
const hasLibraryPath = !!status?.settings?.library?.libraryPath
|
||||
|
||||
return (
|
||||
@@ -197,6 +201,23 @@ export function HomeToolbar(props: HomeToolbarProps) {
|
||||
{/* <span>Library explorer</span>*/}
|
||||
{/*</DropdownMenuItem>*/}
|
||||
|
||||
<DropdownMenuItem
|
||||
data-home-toolbar-search-library
|
||||
disabled={!hasLibraryPath}
|
||||
className={cn("cursor-pointer", { "!text-[--muted]": !hasLibraryPath })}
|
||||
onClick={() => {
|
||||
setSeaCommandOpen(true)
|
||||
React.startTransition(() => {
|
||||
setTimeout(() => {
|
||||
setSeaCommandInput("/library ")
|
||||
}, 300)
|
||||
})
|
||||
}}
|
||||
>
|
||||
<LuSearch />
|
||||
<span>Search in library</span>
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuItem
|
||||
data-home-toolbar-open-directory-button
|
||||
disabled={!hasLibraryPath}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useGetAnimeCollection } from "@/api/hooks/anilist.hooks"
|
||||
import { useGetMangaCollection } from "@/api/hooks/manga.hooks"
|
||||
import { useLibraryCollection } from "@/app/(main)/_hooks/anime-library-collection-loader.ts"
|
||||
import { useServerStatus } from "@/app/(main)/_hooks/use-server-status"
|
||||
import { CommandGroup, CommandItem, CommandShortcut } from "@/components/ui/command"
|
||||
import { useRouter } from "@/lib/navigation"
|
||||
@@ -15,6 +16,7 @@ export function SeaCommandUserMediaNavigation() {
|
||||
const { input, select, command: { isCommand, command, args }, scrollToTop } = useSeaCommandContext()
|
||||
const { data: animeCollection, isLoading: isAnimeLoading } = useGetAnimeCollection() // should be available instantly
|
||||
const { data: mangaCollection, isLoading: isMangaLoading } = useGetMangaCollection()
|
||||
const animeLibraryCollection = useLibraryCollection()
|
||||
|
||||
const anime = animeCollection?.MediaListCollection?.lists?.flatMap(n => n?.entries)?.filter(Boolean)?.map(n => n.media)?.filter(Boolean) ?? []
|
||||
const manga = mangaCollection?.lists?.flatMap(n => n?.entries)?.filter(Boolean)?.map(n => n.media)?.filter(Boolean) ?? []
|
||||
@@ -24,6 +26,10 @@ export function SeaCommandUserMediaNavigation() {
|
||||
const query = args.join(" ")
|
||||
const filteredAnime = (command === "anime" && query.length > 0) ? anime.filter(n => seaCommand_compareMediaTitles(n.title, query)) : []
|
||||
const filteredManga = (command === "manga" && query.length > 0) ? manga.filter(n => seaCommand_compareMediaTitles(n.title, query)) : []
|
||||
const filteredAnimeLibrary = (command === "library" && query.length > 0) ? animeLibraryCollection?.lists?.flatMap(l => l.entries)
|
||||
?.filter(n => seaCommand_compareMediaTitles(n?.media?.title, query))
|
||||
?.map(n => n?.media)
|
||||
?.filter(Boolean) ?? [] : []
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -63,6 +69,23 @@ export function SeaCommandUserMediaNavigation() {
|
||||
))}
|
||||
</CommandGroup>
|
||||
)}
|
||||
|
||||
{command === "library" && filteredAnimeLibrary.length > 0 && (
|
||||
<CommandGroup heading="Library anime">
|
||||
{filteredAnimeLibrary.map(n => (
|
||||
<CommandItem
|
||||
key={n.id}
|
||||
onSelect={() => {
|
||||
select(() => {
|
||||
router.push(`/entry?id=${n.id}`)
|
||||
})
|
||||
}}
|
||||
>
|
||||
<CommandItemMedia media={n} type="anime" />
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
)}
|
||||
{command === "manga" && filteredManga.length > 0 && (
|
||||
<CommandGroup heading="My manga">
|
||||
{filteredManga.map(n => (
|
||||
|
||||
@@ -181,7 +181,7 @@ export function SeaCommand() {
|
||||
shouldShow={ctx => (
|
||||
ctx.command.command === "anime"
|
||||
|| ctx.command.command === "manga"
|
||||
// || ctx.command.command === "library"
|
||||
|| ctx.command.command === "library"
|
||||
)}
|
||||
render={() => <SeaCommandUserMediaNavigation />}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user