Browse Source

Clean up dual filter logic

master
jeffvli 3 years ago
committed by Jeff
parent
commit
4ce2f3a4e9
  1. 69
      src/components/library/AdvancedFilters.tsx
  2. 19
      src/components/library/AlbumList.tsx
  3. 25
      src/hooks/useAdvancedFilter.ts

69
src/components/library/AdvancedFilters.tsx

@ -21,31 +21,64 @@ const AdvancedFilters = ({ filteredData, originalData, filter, setAdvancedFilter
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const [availableGenres, setAvailableGenres] = useState<any[]>([]); const [availableGenres, setAvailableGenres] = useState<any[]>([]);
const [availableArtists, setAvailableArtists] = useState<any[]>([]); const [availableArtists, setAvailableArtists] = useState<any[]>([]);
const [data, setData] = useState<any[]>([]); const [genreListData, setGenreListData] = useState<any[]>([]);
const [artistListData, setArtistListData] = useState<any[]>([]);
const genreFilterPickerContainerRef = useRef<any>(); const genreFilterPickerContainerRef = useRef<any>();
const artistFilterPickerContainerRef = useRef<any>(); const artistFilterPickerContainerRef = useRef<any>();
// Filter flow from TOP to BOTTOM (see useAdvancedFilter hook)
// 1. byStarredData
// 2. byGenreData
// 3. byArtistData
// 4. filteredData
useEffect(() => { useEffect(() => {
if ( if (filter.properties.artist.type === 'and') {
filter.properties.artist.type === 'or' && return setArtistListData(filteredData.byArtistData);
filter.properties.artist.list.length > 0 &&
filter.properties.genre.list.length > 0
) {
return setData(filteredData.byGenreData);
} }
if (filter.properties.artist.type === 'or' && filter.properties.artist.list.length > 0) { if (filter.properties.starred) {
return setData(filteredData.byStarredData); return setArtistListData(filteredData.byGenreData);
} }
if (filter.properties.genre.list.length > 0) { if (filter.properties.artist.type === 'or') {
return setData(filteredData.filteredData); return setArtistListData(filteredData.byGenreData);
} }
return setData(originalData); return setArtistListData(originalData);
}, [ }, [
filter.properties.artist.list.length, filter.properties.artist.list.length,
filter.properties.artist.type, filter.properties.artist.type,
filter.properties.starred,
filteredData.byArtistData,
filteredData.byGenreData,
originalData,
]);
useEffect(() => {
if (filter.properties.starred) {
if (filter.properties.genre.type === 'and') {
return setGenreListData(filteredData.filteredData);
}
return setGenreListData(filteredData.byArtistData);
}
if (filter.properties.artist.list.length > 0) {
if (filter.properties.genre.type === 'and') {
return setGenreListData(filteredData.filteredData);
}
return setGenreListData(filteredData.byArtistBaseData);
}
if (filter.properties.genre.list.length > 0) {
if (filter.properties.genre.type === 'and') {
return setGenreListData(filteredData.byGenreData);
}
}
return setGenreListData(originalData);
}, [
filter.properties.artist.list.length,
filter.properties.genre.list.length, filter.properties.genre.list.length,
filter.properties.genre.type, filter.properties.genre.type,
filter.properties.starred, filter.properties.starred,
@ -54,7 +87,7 @@ const AdvancedFilters = ({ filteredData, originalData, filter, setAdvancedFilter
]); ]);
useEffect(() => { useEffect(() => {
const allGenres = _.flatten(_.map(data, 'genre')); const allGenres = _.flatten(_.map(genreListData, 'genre'));
const counts = _.countBy(allGenres, 'title'); const counts = _.countBy(allGenres, 'title');
const uniqueGenres = _.orderBy(_.uniqBy(allGenres, 'title'), [ const uniqueGenres = _.orderBy(_.uniqBy(allGenres, 'title'), [
(entry: any) => { (entry: any) => {
@ -73,10 +106,10 @@ const AdvancedFilters = ({ filteredData, originalData, filter, setAdvancedFilter
}; };
}) })
); );
}, [data, filter.properties.genre.type, filter.properties.starred, filteredData, originalData]); }, [genreListData]);
useEffect(() => { useEffect(() => {
const allArtists = _.flatten(_.map(data, 'artist')); const allArtists = _.flatten(_.map(artistListData, 'artist'));
const counts = _.countBy(allArtists, 'id'); const counts = _.countBy(allArtists, 'id');
const uniqueArtists = _.orderBy(_.uniqBy(allArtists, 'id'), [ const uniqueArtists = _.orderBy(_.uniqBy(allArtists, 'id'), [
(entry: any) => { (entry: any) => {
@ -95,7 +128,7 @@ const AdvancedFilters = ({ filteredData, originalData, filter, setAdvancedFilter
}; };
}) })
); );
}, [data, filter.properties.artist.type, filter.properties.starred, filteredData, originalData]); }, [artistListData]);
return ( return (
<div> <div>
@ -166,7 +199,7 @@ const AdvancedFilters = ({ filteredData, originalData, filter, setAdvancedFilter
}} }}
/> />
<StyledIconButton <StyledIconButton
appearance={filter.properties.genre.list.length > 0 ? 'primary' : ''} appearance={filter.properties.genre.list.length > 0 ? 'primary' : 'subtle'}
disabled={filter.properties.genre.list.length === 0} disabled={filter.properties.genre.list.length === 0}
size="xs" size="xs"
icon={<Icon icon="close" />} icon={<Icon icon="close" />}
@ -227,7 +260,7 @@ const AdvancedFilters = ({ filteredData, originalData, filter, setAdvancedFilter
}} }}
/> />
<StyledIconButton <StyledIconButton
appearance={filter.properties.artist.list.length > 0 ? 'primary' : ''} appearance={filter.properties.artist.list.length > 0 ? 'primary' : 'subtle'}
disabled={filter.properties.artist.list.length === 0} disabled={filter.properties.artist.list.length === 0}
size="xs" size="xs"
icon={<Icon icon="close" />} icon={<Icon icon="close" />}

19
src/components/library/AlbumList.tsx

@ -132,10 +132,13 @@ const AlbumList = () => {
'year', 'year',
]); ]);
const { filteredData, byArtistData, byGenreData, byStarredData } = useAdvancedFilter( const {
albums, filteredData,
album.advancedFilters byArtistData,
); byArtistBaseData,
byGenreData,
byStarredData,
} = useAdvancedFilter(albums, album.advancedFilters);
useEffect(() => { useEffect(() => {
setSortTypes(_.compact(_.concat(ALBUM_SORT_TYPES, genres))); setSortTypes(_.compact(_.concat(ALBUM_SORT_TYPES, genres)));
@ -260,7 +263,13 @@ const AlbumList = () => {
speaker={ speaker={
<StyledPopover width="400px"> <StyledPopover width="400px">
<AdvancedFilters <AdvancedFilters
filteredData={{ filteredData, byArtistData, byGenreData, byStarredData }} filteredData={{
filteredData,
byArtistData,
byArtistBaseData,
byGenreData,
byStarredData,
}}
originalData={albums} originalData={albums}
filter={album.advancedFilters} filter={album.advancedFilters}
setAdvancedFilters={setAdvancedFilters} setAdvancedFilters={setAdvancedFilters}

25
src/hooks/useAdvancedFilter.ts

@ -7,6 +7,7 @@ const useAdvancedFilter = (data: any[], filters: AdvancedFilters) => {
const [byStarredData, setByStarredData] = useState<any[]>([]); const [byStarredData, setByStarredData] = useState<any[]>([]);
const [byGenreData, setByGenreData] = useState<any[]>([]); const [byGenreData, setByGenreData] = useState<any[]>([]);
const [byArtistData, setByArtistData] = useState<any[]>([]); const [byArtistData, setByArtistData] = useState<any[]>([]);
const [byArtistBaseData, setByArtistBaseData] = useState<any[]>([]);
const [filterProps, setFilterProps] = useState(filters); const [filterProps, setFilterProps] = useState(filters);
@ -64,16 +65,38 @@ const useAdvancedFilter = (data: any[], filters: AdvancedFilters) => {
}) })
: filteredByGenres; : filteredByGenres;
// Instead of filtering from the previous (genre), start from the starred filter
const filteredByArtistsBase =
filterProps.properties.artist.list.length > 0
? (filteredByStarred || []).filter((entry) => {
const entryArtistIds = _.map(entry.artist, 'id');
if (filterProps.properties.artist.type === 'or') {
return entryArtistIds.some((artistId) => artistId.match(artistRegex));
}
const matches = [];
for (let i = 0; i < filterProps.properties.artist.list.length; i += 1) {
if (entryArtistIds.includes(filterProps.properties.artist.list[i])) {
matches.push(entry);
}
}
return matches.length === filterProps.properties.artist.list.length;
})
: filteredByStarred;
setByStarredData(_.compact(_.uniqBy(filteredByStarred, 'uniqueId'))); setByStarredData(_.compact(_.uniqBy(filteredByStarred, 'uniqueId')));
setByGenreData(_.compact(_.uniqBy(filteredByGenres, 'uniqueId'))); setByGenreData(_.compact(_.uniqBy(filteredByGenres, 'uniqueId')));
setByArtistData(_.compact(_.uniqBy(filteredByArtists, 'uniqueId'))); setByArtistData(_.compact(_.uniqBy(filteredByArtists, 'uniqueId')));
setByArtistBaseData(_.compact(_.uniqBy(filteredByArtistsBase, 'uniqueId')));
setFilteredData(_.compact(_.uniqBy(filteredByArtists, 'uniqueId'))); setFilteredData(_.compact(_.uniqBy(filteredByArtists, 'uniqueId')));
} else { } else {
setFilteredData(data); setFilteredData(data);
} }
}, [data, filterProps, filters]); }, [data, filterProps, filters]);
return { filteredData, byStarredData, byGenreData, byArtistData }; return { filteredData, byStarredData, byGenreData, byArtistData, byArtistBaseData };
}; };
export default useAdvancedFilter; export default useAdvancedFilter;

Loading…
Cancel
Save