diff --git a/src/renderer/features/search/components/collapsible-command-group.module.css b/src/renderer/features/search/components/collapsible-command-group.module.css index aacecb7bc..f795cd276 100644 --- a/src/renderer/features/search/components/collapsible-command-group.module.css +++ b/src/renderer/features/search/components/collapsible-command-group.module.css @@ -1,8 +1,6 @@ .root { display: flex; flex-direction: column; - - } @@ -32,6 +30,11 @@ opacity: 0.9; } +.subtitle { + display: flex; + align-items: center; +} + .items { display: flex; flex-direction: column; diff --git a/src/renderer/features/search/components/collapsible-command-group.tsx b/src/renderer/features/search/components/collapsible-command-group.tsx index 320bc39e7..8f9e13175 100644 --- a/src/renderer/features/search/components/collapsible-command-group.tsx +++ b/src/renderer/features/search/components/collapsible-command-group.tsx @@ -12,7 +12,7 @@ interface CollapsibleCommandGroupProps { expanded?: boolean; heading: string; onToggle?: () => void; - subtitle?: string; + subtitle?: ReactNode; } export function CollapsibleCommandGroup({ @@ -48,7 +48,7 @@ export function CollapsibleCommandGroup({ return (
- +
{ + navigate( + { + pathname: AppRoute.LIBRARY_ALBUM_ARTISTS, + search: createSearchParams({ + [FILTER_KEYS.SHARED.SEARCH_TERM]: debouncedQuery || query, + }).toString(), + }, + { state: { navigationId: nanoid() } }, + ); + onSelectResult(); + }, [debouncedQuery, navigate, onSelectResult, query]); + if (!showSection) return null; return ( + {query ? ( + + ) : null} + + ) : undefined + } > {isLoading ? ( diff --git a/src/renderer/features/search/components/search-albums-section.tsx b/src/renderer/features/search/components/search-albums-section.tsx index a22cb1262..90a31b82f 100644 --- a/src/renderer/features/search/components/search-albums-section.tsx +++ b/src/renderer/features/search/components/search-albums-section.tsx @@ -1,14 +1,18 @@ import { useInfiniteQuery } from '@tanstack/react-query'; +import { nanoid } from 'nanoid/non-secure'; +import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -import { generatePath, useNavigate } from 'react-router'; +import { createSearchParams, generatePath, useNavigate } from 'react-router'; import { searchQueries } from '/@/renderer/features/search/api/search-api'; import { CollapsibleCommandGroup } from '/@/renderer/features/search/components/collapsible-command-group'; import { CommandItemSelectable } from '/@/renderer/features/search/components/command-item-selectable'; import { LibraryCommandItem } from '/@/renderer/features/search/components/library-command-item'; +import { FILTER_KEYS } from '/@/renderer/features/shared/utils'; import { AppRoute } from '/@/renderer/router/routes'; import { useCurrentServer } from '/@/renderer/store'; import { Box } from '/@/shared/components/box/box'; +import { Button } from '/@/shared/components/button/button'; import { Spinner } from '/@/shared/components/spinner/spinner'; import { Text } from '/@/shared/components/text/text'; import { LibraryItem } from '/@/shared/types/domain-types'; @@ -47,14 +51,50 @@ export function SearchAlbumsSection({ const showSection = isHome; const numberOfResults = hasNextPage ? `${albums.length}+` : albums.length; + const handleGoToPage = useCallback(() => { + navigate( + { + pathname: AppRoute.LIBRARY_ALBUMS, + search: createSearchParams({ + [FILTER_KEYS.SHARED.SEARCH_TERM]: debouncedQuery || query, + }).toString(), + }, + { state: { navigationId: nanoid() } }, + ); + onSelectResult(); + }, [debouncedQuery, navigate, onSelectResult, query]); + if (!showSection) return null; return ( + {query ? ( + + ) : null} + + ) : undefined + } > {isLoading ? ( diff --git a/src/renderer/features/search/components/search-songs-section.tsx b/src/renderer/features/search/components/search-songs-section.tsx index fdd671e64..e505128e3 100644 --- a/src/renderer/features/search/components/search-songs-section.tsx +++ b/src/renderer/features/search/components/search-songs-section.tsx @@ -1,14 +1,18 @@ import { useInfiniteQuery } from '@tanstack/react-query'; +import { nanoid } from 'nanoid/non-secure'; +import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -import { generatePath, useNavigate } from 'react-router'; +import { createSearchParams, generatePath, useNavigate } from 'react-router'; import { searchQueries } from '/@/renderer/features/search/api/search-api'; import { CollapsibleCommandGroup } from '/@/renderer/features/search/components/collapsible-command-group'; import { CommandItemSelectable } from '/@/renderer/features/search/components/command-item-selectable'; import { LibraryCommandItem } from '/@/renderer/features/search/components/library-command-item'; +import { FILTER_KEYS } from '/@/renderer/features/shared/utils'; import { AppRoute } from '/@/renderer/router/routes'; import { useCurrentServer } from '/@/renderer/store'; import { Box } from '/@/shared/components/box/box'; +import { Button } from '/@/shared/components/button/button'; import { Spinner } from '/@/shared/components/spinner/spinner'; import { Text } from '/@/shared/components/text/text'; import { LibraryItem } from '/@/shared/types/domain-types'; @@ -47,14 +51,50 @@ export function SearchSongsSection({ const showSection = isHome; const numberOfResults = hasNextPage ? `${songs.length}+` : songs.length; + const handleGoToPage = useCallback(() => { + navigate( + { + pathname: AppRoute.LIBRARY_SONGS, + search: createSearchParams({ + [FILTER_KEYS.SHARED.SEARCH_TERM]: debouncedQuery || query, + }).toString(), + }, + { state: { navigationId: nanoid() } }, + ); + onSelectResult(); + }, [debouncedQuery, navigate, onSelectResult, query]); + if (!showSection) return null; return ( + {query ? ( + + ) : null} + + ) : undefined + } > {isLoading ? ( diff --git a/src/renderer/features/shared/components/list-search-input.tsx b/src/renderer/features/shared/components/list-search-input.tsx index f055a69cc..b4a64a0d0 100644 --- a/src/renderer/features/shared/components/list-search-input.tsx +++ b/src/renderer/features/shared/components/list-search-input.tsx @@ -1,12 +1,25 @@ +import { useLocation } from 'react-router'; + import { SearchInput } from '/@/renderer/features/shared/components/search-input'; import { useSearchTermFilter } from '/@/renderer/features/shared/hooks/use-search-term-filter'; +function navigationIdFromState(state: unknown): string | undefined { + if (state && typeof state === 'object' && 'navigationId' in state) { + const id = (state as { navigationId: unknown }).navigationId; + return typeof id === 'string' ? id : undefined; + } + return undefined; +} + export const ListSearchInput = () => { const { searchTerm, setSearchTerm } = useSearchTermFilter(); + const { state } = useLocation(); + const navigationId = navigationIdFromState(state); return ( setSearchTerm(e.target.value || null)} /> );