diff --git a/interface/app/$libraryId/favorites.tsx b/interface/app/$libraryId/favorites.tsx index c83f066b2..69e237cdd 100644 --- a/interface/app/$libraryId/favorites.tsx +++ b/interface/app/$libraryId/favorites.tsx @@ -26,7 +26,7 @@ export function Component() { orderingKeys: objectOrderingKeysSchema }); - const search = useSearchFromSearchParams(); + const search = useSearchFromSearchParams({ defaultTarget: 'objects' }); const defaultFilter = { object: { favorite: true } }; @@ -52,7 +52,7 @@ export function Component() { } + center={} left={
{t('favorites')} diff --git a/interface/app/$libraryId/labels.tsx b/interface/app/$libraryId/labels.tsx index 1d8ea9790..3382348f5 100644 --- a/interface/app/$libraryId/labels.tsx +++ b/interface/app/$libraryId/labels.tsx @@ -30,7 +30,7 @@ export function Component() { orderingKeys: objectOrderingKeysSchema }); - const search = useSearchFromSearchParams(); + const search = useSearchFromSearchParams({ defaultTarget: 'objects' }); const explorer = useExplorer({ items: labels.data || null, diff --git a/interface/app/$libraryId/location/$id.tsx b/interface/app/$libraryId/location/$id.tsx index d7b465d62..625457363 100644 --- a/interface/app/$libraryId/location/$id.tsx +++ b/interface/app/$libraryId/location/$id.tsx @@ -71,7 +71,7 @@ const LocationExplorer = ({ location }: { location: Location; path?: string }) = [location.id] ); - const search = useSearchFromSearchParams(); + const search = useSearchFromSearchParams({ defaultTarget: 'paths' }); const searchFiltersAreDefault = useMemo( () => JSON.stringify(defaultFilters) !== JSON.stringify(search.filters), diff --git a/interface/app/$libraryId/overview/index.tsx b/interface/app/$libraryId/overview/index.tsx index 38570f8b9..06b364a1d 100644 --- a/interface/app/$libraryId/overview/index.tsx +++ b/interface/app/$libraryId/overview/index.tsx @@ -24,7 +24,7 @@ export const Component = () => { const { data: node } = useBridgeQuery(['nodeState']); - const search = useSearchFromSearchParams(); + const search = useSearchFromSearchParams({ defaultTarget: 'paths' }); const stats = useLibraryQuery(['library.statistics']); diff --git a/interface/app/$libraryId/recents.tsx b/interface/app/$libraryId/recents.tsx index f0060997e..a491d1b59 100644 --- a/interface/app/$libraryId/recents.tsx +++ b/interface/app/$libraryId/recents.tsx @@ -24,7 +24,7 @@ export function Component() { orderingKeys: objectOrderingKeysSchema }); - const search = useSearchFromSearchParams(); + const search = useSearchFromSearchParams({ defaultTarget: 'paths' }); const { t } = useLocale(); @@ -52,7 +52,7 @@ export function Component() { } + center={} left={
{t('recents')} diff --git a/interface/app/$libraryId/search/Filters.tsx b/interface/app/$libraryId/search/Filters.tsx index d185b9f57..cfe7777b1 100644 --- a/interface/app/$libraryId/search/Filters.tsx +++ b/interface/app/$libraryId/search/Filters.tsx @@ -2,6 +2,7 @@ import { CircleDashed, Cube, Folder, + Heart, Icon, SelectionSlash, Tag, @@ -569,6 +570,24 @@ export const filterRegistry = [ ]; }, Render: ({ filter, search }) => + }), + createBooleanFilter({ + name: 'Favorite', + icon: Heart, + extract: (arg) => { + if ('object' in arg && 'favorite' in arg.object) return arg.object.favorite; + }, + create: (favorite) => ({ object: { favorite } }), + useOptions: () => { + return [ + { + name: 'Favorite', + value: true, + icon: 'Heart' // Spacedrive folder icon + } + ]; + }, + Render: ({ filter, search }) => }) // createInOrNotInFilter({ // name: 'Label', diff --git a/interface/app/$libraryId/search/index.tsx b/interface/app/$libraryId/search/index.tsx index 2ba4a1680..0cda1cd61 100644 --- a/interface/app/$libraryId/search/index.tsx +++ b/interface/app/$libraryId/search/index.tsx @@ -31,7 +31,7 @@ export function Component() { const { t } = useLocale(); - const search = useSearchFromSearchParams(); + const search = useSearchFromSearchParams({ defaultTarget: 'paths' }); const items = useSearchExplorerQuery({ search, diff --git a/interface/app/$libraryId/search/store.tsx b/interface/app/$libraryId/search/store.tsx index a0144019b..e05cc8ab3 100644 --- a/interface/app/$libraryId/search/store.tsx +++ b/interface/app/$libraryId/search/store.tsx @@ -68,7 +68,8 @@ export const useRegisterSearchFilterOptions = ( export function argsToOptions(args: SearchFilterArgs[], options: Map) { return args.flatMap((fixedArg) => { - const filter = filterRegistry.find((f) => f.extract(fixedArg))!; + const filter = filterRegistry.find((f) => f.extract(fixedArg)); + if (!filter) return []; return filter .argsToOptions(filter.extract(fixedArg) as any, options) diff --git a/interface/app/$libraryId/search/useSearch.ts b/interface/app/$libraryId/search/useSearch.ts index a4b2de45c..9b7b29996 100644 --- a/interface/app/$libraryId/search/useSearch.ts +++ b/interface/app/$libraryId/search/useSearch.ts @@ -22,7 +22,7 @@ export interface UseSearchProps { source: TSource; } -export function useSearchParamsSource() { +export function useSearchParamsSource(props: { defaultTarget: SearchTarget }) { const [searchParams, setSearchParams] = useRawSearchParams(); const filtersSearchParam = searchParams.get('filters'); @@ -60,7 +60,7 @@ export function useSearchParamsSource() { ); } - const target = (searchParams.get('target') ?? 'paths') as SearchTarget; + const target = (searchParams.get('target') as SearchTarget | null) ?? props.defaultTarget; return { filters, @@ -201,9 +201,9 @@ export function useSearch(props: UseSearchProps }; } -export function useSearchFromSearchParams() { +export function useSearchFromSearchParams(props: { defaultTarget: SearchTarget }) { return useSearch({ - source: useSearchParamsSource() + source: useSearchParamsSource(props) }); } diff --git a/interface/app/$libraryId/tag/$id.tsx b/interface/app/$libraryId/tag/$id.tsx index 7341ae94d..d9010279d 100644 --- a/interface/app/$libraryId/tag/$id.tsx +++ b/interface/app/$libraryId/tag/$id.tsx @@ -20,7 +20,7 @@ import { TopBarPortal } from '../TopBar/Portal'; export function Component() { const { id: tagId } = useZodRouteParams(LocationIdParamsSchema); const result = useLibraryQuery(['tags.get', tagId], { suspense: true }); - const tag = result.data; + const tag = result.data!; const { t } = useLocale(); @@ -28,9 +28,9 @@ export function Component() { const { explorerSettings, preferences } = useTagExplorerSettings(tag!); - const search = useSearchFromSearchParams(); + const search = useSearchFromSearchParams({ defaultTarget: 'objects' }); - const defaultFilters = useMemo(() => [{ object: { tags: { in: [tag!.id] } } }], [tag!.id]); + const defaultFilters = useMemo(() => [{ object: { tags: { in: [tag.id] } } }], [tag.id]); const items = useSearchExplorerQuery({ search, @@ -45,7 +45,7 @@ export function Component() { isFetchingNextPage: items.query.isFetchingNextPage, isLoadingPreferences: preferences.isLoading, settings: explorerSettings, - parent: { type: 'Tag', tag: tag! } + parent: { type: 'Tag', tag: tag } }); return (