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

19
src/components/library/AlbumList.tsx

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

25
src/hooks/useAdvancedFilter.ts

@ -7,6 +7,7 @@ const useAdvancedFilter = (data: any[], filters: AdvancedFilters) => {
const [byStarredData, setByStarredData] = useState<any[]>([]);
const [byGenreData, setByGenreData] = useState<any[]>([]);
const [byArtistData, setByArtistData] = useState<any[]>([]);
const [byArtistBaseData, setByArtistBaseData] = useState<any[]>([]);
const [filterProps, setFilterProps] = useState(filters);
@ -64,16 +65,38 @@ const useAdvancedFilter = (data: any[], filters: AdvancedFilters) => {
})
: 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')));
setByGenreData(_.compact(_.uniqBy(filteredByGenres, 'uniqueId')));
setByArtistData(_.compact(_.uniqBy(filteredByArtists, 'uniqueId')));
setByArtistBaseData(_.compact(_.uniqBy(filteredByArtistsBase, 'uniqueId')));
setFilteredData(_.compact(_.uniqBy(filteredByArtists, 'uniqueId')));
} else {
setFilteredData(data);
}
}, [data, filterProps, filters]);
return { filteredData, byStarredData, byGenreData, byArtistData };
return { filteredData, byStarredData, byGenreData, byArtistData, byArtistBaseData };
};
export default useAdvancedFilter;

Loading…
Cancel
Save