From 1959226fb941336eb8f075f72e5bc3262b9d6406 Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Fri, 29 Mar 2024 06:46:55 +0800 Subject: [PATCH] remove fixed filters (#2257) * remove fixed filters * fix: remove blank `console.log` --------- Co-authored-by: jake <77554505+brxken128@users.noreply.github.com> --- interface/app/$libraryId/favorites.tsx | 19 +--- interface/app/$libraryId/labels.tsx | 4 +- interface/app/$libraryId/location/$id.tsx | 40 +++---- interface/app/$libraryId/recents.tsx | 19 +--- interface/app/$libraryId/saved-search/$id.tsx | 8 +- .../app/$libraryId/search/AppliedFilters.tsx | 10 +- interface/app/$libraryId/search/Filters.tsx | 37 +++---- interface/app/$libraryId/search/SearchBar.tsx | 6 +- .../app/$libraryId/search/SearchOptions.tsx | 4 +- interface/app/$libraryId/search/index.tsx | 34 +++--- interface/app/$libraryId/search/useSearch.ts | 102 +++++------------- .../settings/library/saved-searches/index.tsx | 4 +- interface/app/$libraryId/tag/$id.tsx | 22 ++-- 13 files changed, 110 insertions(+), 199 deletions(-) diff --git a/interface/app/$libraryId/favorites.tsx b/interface/app/$libraryId/favorites.tsx index f3f53da4421b..54e485659879 100644 --- a/interface/app/$libraryId/favorites.tsx +++ b/interface/app/$libraryId/favorites.tsx @@ -25,19 +25,7 @@ export function Component() { const explorerSettingsSnapshot = explorerSettings.useSettingsSnapshot(); - const fixedFilters = useMemo( - () => [ - // { object: { favorite: true } }, - ...(explorerSettingsSnapshot.layoutMode === 'media' - ? [{ object: { kind: { in: [ObjectKindEnum.Image, ObjectKindEnum.Video] } } }] - : []) - ], - [explorerSettingsSnapshot.layoutMode] - ); - - const search = useSearch({ - fixedFilters - }); + const search = useSearch(); const objects = useObjectsExplorerQuery({ arg: { @@ -45,7 +33,10 @@ export function Component() { filters: [ ...search.allFilters, // TODO: Add filter to search options - { object: { favorite: true } } + { object: { favorite: true } }, + ...(explorerSettingsSnapshot.layoutMode === 'media' + ? [{ object: { kind: { in: [ObjectKindEnum.Image, ObjectKindEnum.Video] } } }] + : []) ] }, order: explorerSettings.useSettingsSnapshot().order diff --git a/interface/app/$libraryId/labels.tsx b/interface/app/$libraryId/labels.tsx index 24beaae251e4..fe26327b9f93 100644 --- a/interface/app/$libraryId/labels.tsx +++ b/interface/app/$libraryId/labels.tsx @@ -27,7 +27,7 @@ export function Component() { // const explorerSettingsSnapshot = explorerSettings.useSettingsSnapshot(); - // const fixedFilters = useMemo( + // const filters = useMemo( // () => [ // ...(explorerSettingsSnapshot.layoutMode === 'media' // ? [{ object: { kind: { in: [ObjectKindEnum.Image, ObjectKindEnum.Video] } } }] @@ -36,7 +36,7 @@ export function Component() { // [explorerSettingsSnapshot.layoutMode] // ); - const search = useSearch({}); + const search = useSearch(); // const objects = useObjectsExplorerQuery({ // arg: { diff --git a/interface/app/$libraryId/location/$id.tsx b/interface/app/$libraryId/location/$id.tsx index 03720f20a620..96fb6e2ba7e3 100644 --- a/interface/app/$libraryId/location/$id.tsx +++ b/interface/app/$libraryId/location/$id.tsx @@ -71,7 +71,9 @@ const LocationExplorer = ({ location }: { location: Location; path?: string }) = const { layoutMode, mediaViewWithDescendants, showHiddenFiles } = explorerSettings.useSettingsSnapshot(); - const search = useLocationSearch(explorerSettings, location); + const search = useLocationSearch(location); + + const explorerSettingsSnapshot = explorerSettings.useSettingsSnapshot(); const paths = usePathsExplorerQuery({ arg: { @@ -84,12 +86,15 @@ const LocationExplorer = ({ location }: { location: Location; path?: string }) = path: path ?? '', include_descendants: search.search !== '' || - search.dynamicFilters.length > 0 || + search.filters.length > 0 || (layoutMode === 'media' && mediaViewWithDescendants) } } }, - !showHiddenFiles && { filePath: { hidden: false } } + !showHiddenFiles && { filePath: { hidden: false } }, + explorerSettingsSnapshot.layoutMode === 'media' && [ + { object: { kind: { in: [ObjectKindEnum.Image, ObjectKindEnum.Video] } } } + ] ].filter(Boolean) as any, take }, @@ -268,47 +273,32 @@ function useLocationExplorerSettings(location: Location) { }; } -function useLocationSearch( - explorerSettings: UseExplorerSettings, - location: Location -) { +function useLocationSearch(location: Location) { const [searchParams, setSearchParams] = useRawSearchParams(); - const explorerSettingsSnapshot = explorerSettings.useSettingsSnapshot(); - - const fixedFilters = useMemo( - () => [ - { filePath: { locations: { in: [location.id] } } }, - ...(explorerSettingsSnapshot.layoutMode === 'media' - ? [{ object: { kind: { in: [ObjectKindEnum.Image, ObjectKindEnum.Video] } } }] - : []) - ], - [location.id, explorerSettingsSnapshot.layoutMode] - ); const filtersParam = searchParams.get('filters'); - const dynamicFilters = useMemo(() => JSON.parse(filtersParam ?? '[]'), [filtersParam]); + const filters = useMemo(() => JSON.parse(filtersParam ?? '[]'), [filtersParam]); const searchQueryParam = searchParams.get('search'); const search = useSearch({ - open: !!searchQueryParam || dynamicFilters.length > 0 || undefined, + open: !!searchQueryParam || filters.length > 0 || undefined, search: searchParams.get('search') ?? undefined, - fixedFilters, - dynamicFilters + defaultFilters: [{ filePath: { locations: { in: [location.id] } } }], + filters: filters }); useEffect(() => { setSearchParams( (p) => { - if (search.dynamicFilters.length > 0) - p.set('filters', JSON.stringify(search.dynamicFilters)); + if (search.filters.length > 0) p.set('filters', JSON.stringify(search.filters)); else p.delete('filters'); return p; }, { replace: true } ); - }, [search.dynamicFilters, setSearchParams]); + }, [search.filters, setSearchParams]); const searchQuery = search.search; diff --git a/interface/app/$libraryId/recents.tsx b/interface/app/$libraryId/recents.tsx index f415a0307454..7baca400a406 100644 --- a/interface/app/$libraryId/recents.tsx +++ b/interface/app/$libraryId/recents.tsx @@ -25,19 +25,7 @@ export function Component() { const explorerSettingsSnapshot = explorerSettings.useSettingsSnapshot(); - const fixedFilters = useMemo( - () => [ - // { object: { dateAccessed: { from: new Date(0).toISOString() } } }, - ...(explorerSettingsSnapshot.layoutMode === 'media' - ? [{ object: { kind: { in: [ObjectKindEnum.Image, ObjectKindEnum.Video] } } }] - : []) - ], - [explorerSettingsSnapshot.layoutMode] - ); - - const search = useSearch({ - fixedFilters - }); + const search = useSearch(); const objects = useObjectsExplorerQuery({ arg: { @@ -45,7 +33,10 @@ export function Component() { filters: [ ...search.allFilters, // TODO: Add fil ter to search options - { object: { dateAccessed: { from: new Date(0).toISOString() } } } + { object: { dateAccessed: { from: new Date(0).toISOString() } } }, + ...(explorerSettingsSnapshot.layoutMode === 'media' + ? [{ object: { kind: { in: [ObjectKindEnum.Image, ObjectKindEnum.Video] } } }] + : []) ] }, order: explorerSettings.useSettingsSnapshot().order diff --git a/interface/app/$libraryId/saved-search/$id.tsx b/interface/app/$libraryId/saved-search/$id.tsx index 1ce371d9ed75..4f6c5742b050 100644 --- a/interface/app/$libraryId/saved-search/$id.tsx +++ b/interface/app/$libraryId/saved-search/$id.tsx @@ -46,14 +46,14 @@ export const Component = () => { const rawFilters = savedSearch.data?.filters; - const dynamicFilters = useMemo(() => { + const filters = useMemo(() => { if (rawFilters) return JSON.parse(rawFilters) as SearchFilterArgs[]; }, [rawFilters]); const search = useSearch({ open: true, search: savedSearch.data?.search ?? undefined, - dynamicFilters + filters: filters }); const paths = usePathsExplorerQuery({ @@ -85,7 +85,7 @@ export const Component = () => { >
- {(search.dynamicFilters !== dynamicFilters || + {(search.filters !== filters || search.search !== savedSearch.data?.search) && ( )} @@ -123,7 +123,7 @@ function SaveButton({ searchId }: { searchId: number }) { updateSavedSearch.mutate([ searchId, { - filters: JSON.stringify(search.dynamicFilters), + filters: JSON.stringify(search.filters), search: search.search } ]); diff --git a/interface/app/$libraryId/search/AppliedFilters.tsx b/interface/app/$libraryId/search/AppliedFilters.tsx index b0f965aa0907..141f5c22189a 100644 --- a/interface/app/$libraryId/search/AppliedFilters.tsx +++ b/interface/app/$libraryId/search/AppliedFilters.tsx @@ -55,13 +55,11 @@ export const AppliedFilters = ({ allowRemove = true }: { allowRemove?: boolean } onDelete={ removalIndex !== null && allowRemove ? () => { - search.updateDynamicFilters( - (dyanmicFilters) => { - dyanmicFilters.splice(removalIndex, 1); + search.updateFilters((dyanmicFilters) => { + dyanmicFilters.splice(removalIndex, 1); - return dyanmicFilters; - } - ); + return dyanmicFilters; + }); } : undefined } diff --git a/interface/app/$libraryId/search/Filters.tsx b/interface/app/$libraryId/search/Filters.tsx index 7b204b5bce34..a5b504cc798e 100644 --- a/interface/app/$libraryId/search/Filters.tsx +++ b/interface/app/$libraryId/search/Filters.tsx @@ -71,28 +71,25 @@ export function useToggleOptionSelected({ search }: { search: UseSearch }) { option: FilterOption; select: boolean; }) => { - search.updateDynamicFilters((dynamicFilters) => { - const key = getKey({ ...option, type: filter.name }); - if (search.fixedFiltersKeys?.has(key)) return dynamicFilters; - - const rawArg = dynamicFilters.find((arg) => filter.extract(arg)); + search.updateFilters((filters) => { + const rawArg = filters.find((arg) => filter.extract(arg)); if (!rawArg) { const arg = filter.create(option.value); - dynamicFilters.push(arg); + filters.push(arg); } else { - const rawArgIndex = dynamicFilters.findIndex((arg) => filter.extract(arg))!; + const rawArgIndex = filters.findIndex((arg) => filter.extract(arg))!; const arg = filter.extract(rawArg)!; if (select) { if (rawArg) filter.applyAdd(arg, option); } else { - if (!filter.applyRemove(arg, option)) dynamicFilters.splice(rawArgIndex, 1); + if (!filter.applyRemove(arg, option)) filters.splice(rawArgIndex, 1); } } - return dynamicFilters; + return filters; }); }; } @@ -159,14 +156,14 @@ const FilterOptionText = ({ filter, search }: { filter: SearchFilterCRUD; search className="flex gap-1.5" onSubmit={(e) => { e.preventDefault(); - search.updateDynamicFilters((dynamicFilters) => { - if (allFiltersKeys.has(key)) return dynamicFilters; + search.updateFilters((filters) => { + if (allFiltersKeys.has(key)) return filters; const arg = filter.create(value); - dynamicFilters.push(arg); + filters.push(arg); setValue(''); - return dynamicFilters; + return filters; }); }} > @@ -191,7 +188,7 @@ const FilterOptionBoolean = ({ filter: SearchFilterCRUD; search: UseSearch; }) => { - const { fixedFiltersKeys, allFiltersKeys } = search; + const { allFiltersKeys } = search; const key = getKey({ type: filter.name, @@ -204,19 +201,17 @@ const FilterOptionBoolean = ({ icon={filter.icon} selected={allFiltersKeys?.has(key)} setSelected={() => { - search.updateDynamicFilters((dynamicFilters) => { - if (fixedFiltersKeys?.has(key)) return dynamicFilters; - - const index = dynamicFilters.findIndex((f) => filter.extract(f) !== undefined); + search.updateFilters((filters) => { + const index = filters.findIndex((f) => filter.extract(f) !== undefined); if (index !== -1) { - dynamicFilters.splice(index, 1); + filters.splice(index, 1); } else { const arg = filter.create(true); - dynamicFilters.push(arg); + filters.push(arg); } - return dynamicFilters; + return filters; }); }} > diff --git a/interface/app/$libraryId/search/SearchBar.tsx b/interface/app/$libraryId/search/SearchBar.tsx index e49c1441d506..85205ced6540 100644 --- a/interface/app/$libraryId/search/SearchBar.tsx +++ b/interface/app/$libraryId/search/SearchBar.tsx @@ -81,6 +81,7 @@ export default ({ redirectToSearch }: Props) => { function clearValue() { search.setSearch(''); + search.setFilters([]); } return ( @@ -99,7 +100,10 @@ export default ({ redirectToSearch }: Props) => { search.setSearchBarFocused(false); } }} - onFocus={() => search.setSearchBarFocused(true)} + onFocus={() => { + search.setSearchBarFocused(true); + if (search.defaultFilters) search.setFilters(search.defaultFilters); + }} right={
{ diff --git a/interface/app/$libraryId/search/SearchOptions.tsx b/interface/app/$libraryId/search/SearchOptions.tsx index aa77f0677a76..1cf649b13891 100644 --- a/interface/app/$libraryId/search/SearchOptions.tsx +++ b/interface/app/$libraryId/search/SearchOptions.tsx @@ -124,9 +124,7 @@ export const SearchOptions = ({ {children ?? ( <> - {(search.dynamicFilters.length > 0 || search.search !== '') && ( - - )} + {(search.filters.length > 0 || search.search !== '') && } diff --git a/interface/app/$libraryId/search/index.tsx b/interface/app/$libraryId/search/index.tsx index 3f7ec1e84799..3ec25317dc3c 100644 --- a/interface/app/$libraryId/search/index.tsx +++ b/interface/app/$libraryId/search/index.tsx @@ -27,13 +27,19 @@ export function Component() { }, []), orderingKeys: objectOrderingKeysSchema }); + const explorerSettingsSnapshot = explorerSettings.useSettingsSnapshot(); - const search = useSearchWithFilters(explorerSettings); + const search = useSearchWithFilters(); const objects = useObjectsExplorerQuery({ arg: { take: 100, - filters: search.allFilters + filters: [ + ...search.allFilters, + ...(explorerSettingsSnapshot.layoutMode === 'media' + ? [{ object: { kind: { in: [ObjectKindEnum.Image, ObjectKindEnum.Video] } } }] + : []) + ] }, order: explorerSettings.useSettingsSnapshot().order }); @@ -77,43 +83,31 @@ export function Component() { ); } -function useSearchWithFilters(explorerSettings: UseExplorerSettings) { +function useSearchWithFilters() { const [searchParams, setSearchParams] = useRawSearchParams(); - const explorerSettingsSnapshot = explorerSettings.useSettingsSnapshot(); - - const fixedFilters = useMemo( - () => [ - ...(explorerSettingsSnapshot.layoutMode === 'media' - ? [{ object: { kind: { in: [ObjectKindEnum.Image, ObjectKindEnum.Video] } } }] - : []) - ], - [explorerSettingsSnapshot.layoutMode] - ); const filtersParam = searchParams.get('filters'); - const dynamicFilters = useMemo(() => JSON.parse(filtersParam ?? '[]'), [filtersParam]); + const filters = useMemo(() => JSON.parse(filtersParam ?? '[]'), [filtersParam]); const searchQueryParam = searchParams.get('search'); const search = useSearch({ - open: !!searchQueryParam || dynamicFilters.length > 0 || undefined, + open: !!searchQueryParam || filters.length > 0 || undefined, search: searchParams.get('search') ?? undefined, - fixedFilters, - dynamicFilters + filters }); useEffect(() => { setSearchParams( (p) => { - if (search.dynamicFilters.length > 0) - p.set('filters', JSON.stringify(search.dynamicFilters)); + if (search.filters.length > 0) p.set('filters', JSON.stringify(search.filters)); else p.delete('filters'); return p; }, { replace: true } ); - }, [search.dynamicFilters, setSearchParams]); + }, [search.filters, setSearchParams]); const searchQuery = search.search; diff --git a/interface/app/$libraryId/search/useSearch.ts b/interface/app/$libraryId/search/useSearch.ts index f81207ecb650..a2746fa4a97f 100644 --- a/interface/app/$libraryId/search/useSearch.ts +++ b/interface/app/$libraryId/search/useSearch.ts @@ -9,15 +9,12 @@ import { argsToOptions, getKey, useSearchStore } from './store'; export interface UseSearchProps { open?: boolean; search?: string; - /** - * Filters that cannot be removed - */ - fixedFilters?: SearchFilterArgs[]; /** * Filters that can be removed. * When this value changes dynamic filters stored internally will reset. */ - dynamicFilters?: SearchFilterArgs[]; + filters?: SearchFilterArgs[]; + defaultFilters?: SearchFilterArgs[]; } export function useSearch(props?: UseSearchProps) { @@ -25,45 +22,22 @@ export function useSearch(props?: UseSearchProps) { const searchState = useSearchStore(); - // Filters that can't be removed - - const fixedFilters = useMemo(() => props?.fixedFilters ?? [], [props?.fixedFilters]); - - const fixedFiltersAsOptions = useMemo( - () => argsToOptions(fixedFilters, searchState.filterOptions), - [fixedFilters, searchState.filterOptions] - ); + const [filters, setFilters] = useState(props?.filters ?? []); + const [filtersFromProps, setFiltersFromProps] = useState(props?.filters); - const fixedFiltersKeys: Set = useMemo(() => { - return new Set( - fixedFiltersAsOptions.map(({ arg, filter }) => - getKey({ - type: filter.name, - name: arg.name, - value: arg.value - }) - ) - ); - }, [fixedFiltersAsOptions]); - - // Filters that can be removed - - const [dynamicFilters, setDynamicFilters] = useState(props?.dynamicFilters ?? []); - const [dynamicFiltersFromProps, setDynamicFiltersFromProps] = useState(props?.dynamicFilters); - - if (dynamicFiltersFromProps !== props?.dynamicFilters) { - setDynamicFiltersFromProps(props?.dynamicFilters); - setDynamicFilters(props?.dynamicFilters ?? []); + if (filtersFromProps !== props?.filters) { + setFiltersFromProps(props?.filters); + setFilters(props?.filters ?? []); } - const dynamicFiltersAsOptions = useMemo( - () => argsToOptions(dynamicFilters, searchState.filterOptions), - [dynamicFilters, searchState.filterOptions] + const filtersAsOptions = useMemo( + () => argsToOptions(filters, searchState.filterOptions), + [filters, searchState.filterOptions] ); - const dynamicFiltersKeys: Set = useMemo(() => { + const filtersKeys: Set = useMemo(() => { return new Set( - dynamicFiltersAsOptions.map(({ arg, filter }) => + filtersAsOptions.map(({ arg, filter }) => getKey({ type: filter.name, name: arg.name, @@ -71,52 +45,31 @@ export function useSearch(props?: UseSearchProps) { }) ) ); - }, [dynamicFiltersAsOptions]); + }, [filtersAsOptions]); - const updateDynamicFilters = useCallback( + const updateFilters = useCallback( (cb: (args: SearchFilterArgs[]) => SearchFilterArgs[]) => - setDynamicFilters((filters) => produce(filters, cb)), + setFilters((filters) => produce(filters, cb)), [] ); // Merging of filters that should be ORed const mergedFilters = useMemo(() => { - const value: { arg: SearchFilterArgs; removalIndex: number | null }[] = fixedFilters.map( - (arg) => ({ - arg, - removalIndex: null - }) - ); + const value: { arg: SearchFilterArgs; removalIndex: number | null }[] = []; - for (const [index, arg] of dynamicFilters.entries()) { + for (const [index, arg] of filters.entries()) { const filter = filterRegistry.find((f) => f.extract(arg)); if (!filter) continue; - const fixedEquivalentIndex = fixedFilters.findIndex( - (a) => filter.extract(a) !== undefined - ); - - if (fixedEquivalentIndex !== -1) { - const merged = filter.merge( - filter.extract(fixedFilters[fixedEquivalentIndex]!)! as any, - filter.extract(arg)! as any - ); - - value[fixedEquivalentIndex] = { - arg: filter.create(merged), - removalIndex: fixedEquivalentIndex - }; - } else { - value.push({ - arg, - removalIndex: index - }); - } + value.push({ + arg, + removalIndex: index + }); } return value; - }, [fixedFilters, dynamicFilters]); + }, [filters]); // Filters generated from the search query @@ -167,17 +120,16 @@ export function useSearch(props?: UseSearchProps) { return { open: props?.open || searchBarFocused, - fixedFilters, - fixedFiltersKeys, search, rawSearch, setSearch: setRawSearch, searchBarFocused, setSearchBarFocused, - dynamicFilters, - setDynamicFilters, - updateDynamicFilters, - dynamicFiltersKeys, + defaultFilters: props?.defaultFilters, + filters, + setFilters, + updateFilters, + filtersKeys, mergedFilters, allFilters, allFiltersKeys diff --git a/interface/app/$libraryId/settings/library/saved-searches/index.tsx b/interface/app/$libraryId/settings/library/saved-searches/index.tsx index 8d5eee88fd24..187787f2911b 100644 --- a/interface/app/$libraryId/settings/library/saved-searches/index.tsx +++ b/interface/app/$libraryId/settings/library/saved-searches/index.tsx @@ -82,13 +82,13 @@ function EditForm({ savedSearch, onDelete }: { savedSearch: SavedSearch; onDelet updateSavedSearch.mutate([savedSearch.id, { name: data.name ?? '' }]); }); - const fixedFilters = useMemo(() => { + const filters = useMemo(() => { if (savedSearch.filters === null) return []; return JSON.parse(savedSearch.filters) as SearchFilterArgs[]; }, [savedSearch.filters]); - const search = useSearch({ search: savedSearch.search ?? undefined, fixedFilters }); + const search = useSearch({ search: savedSearch.search ?? undefined, filters }); return (
diff --git a/interface/app/$libraryId/tag/$id.tsx b/interface/app/$libraryId/tag/$id.tsx index fb7b4f2697c8..dbd53ca1e7a9 100644 --- a/interface/app/$libraryId/tag/$id.tsx +++ b/interface/app/$libraryId/tag/$id.tsx @@ -38,22 +38,20 @@ export function Component() { const explorerSettingsSnapshot = explorerSettings.useSettingsSnapshot(); - const fixedFilters = useMemo( - () => [ - { object: { tags: { in: [tag!.id] } } }, - ...(explorerSettingsSnapshot.layoutMode === 'media' - ? [{ object: { kind: { in: [ObjectKindEnum.Image, ObjectKindEnum.Video] } } }] - : []) - ], - [tag, explorerSettingsSnapshot.layoutMode] - ); - const search = useSearch({ - fixedFilters + defaultFilters: [{ object: { tags: { in: [tag!.id] } } }] }); const objects = useObjectsExplorerQuery({ - arg: { take: 100, filters: search.allFilters }, + arg: { + take: 100, + filters: [ + ...search.allFilters, + ...(explorerSettingsSnapshot.layoutMode === 'media' + ? [{ object: { kind: { in: [ObjectKindEnum.Image, ObjectKindEnum.Video] } } }] + : []) + ] + }, order: explorerSettings.useSettingsSnapshot().order });