Browse Source

add custom search hook

master
jeffvli 3 years ago
parent
commit
e2246e3b79
  1. 34
      src/components/library/LibraryView.tsx
  2. 26
      src/components/player/NowPlayingView.tsx
  3. 27
      src/components/playlist/PlaylistList.tsx
  4. 28
      src/components/playlist/PlaylistView.tsx
  5. 45
      src/components/starred/StarredView.tsx
  6. 3
      src/components/viewtypes/GridViewType.tsx
  7. 38
      src/hooks/useSearchQuery.ts

34
src/components/library/LibraryView.tsx

@ -5,6 +5,7 @@ import { useQuery } from 'react-query';
import VisibilitySensor from 'react-visibility-sensor';
import settings from 'electron-settings';
import _ from 'lodash';
import useSearchQuery from '../../hooks/useSearchQuery';
import { getAlbumsDirect, getArtists } from '../../api/api';
import GenericPage from '../layout/GenericPage';
import GenericPageHeader from '../layout/GenericPageHeader';
@ -26,12 +27,9 @@ const ALBUM_SORT_TYPES = [
const LibraryView = () => {
const [currentPage, setCurrentPage] = useState('albums');
const [sortBy, setSortBy] = useState(null);
const [searchQuery, setSearchQuery] = useState('');
const [data, setData] = useState<any[]>([]);
const [filteredData, setFilteredData] = useState<any[]>([]);
const [offset, setOffset] = useState(0);
const [viewType, setViewType] = useState(settings.getSync('viewType'));
const { isLoading: isLoadingArtists, data: artists }: any = useQuery(
'artists',
getArtists,
@ -39,26 +37,16 @@ const LibraryView = () => {
enabled: currentPage === 'artists',
}
);
useEffect(() => {
if (searchQuery !== '') {
if (currentPage === 'albums') {
setFilteredData(
data.filter((entry: any) => {
return entry.name.toLowerCase().includes(searchQuery.toLowerCase());
})
);
} else if (currentPage === 'artists') {
setFilteredData(
artists.filter((entry: any) => {
return entry.name.toLowerCase().includes(searchQuery.toLowerCase());
})
);
}
} else {
setFilteredData([]);
}
}, [artists, currentPage, data, searchQuery]);
const [searchQuery, setSearchQuery] = useState('');
const filteredData = useSearchQuery(
searchQuery,
currentPage === 'artists'
? artists
: currentPage === 'albums'
? data
: data,
['name', 'artist']
);
const onChange = (isVisible: boolean) => {
if (isVisible) {

26
src/components/player/NowPlayingView.tsx

@ -1,5 +1,6 @@
import React, { useState, useEffect } from 'react';
import React, { useState } from 'react';
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import useSearchQuery from '../../hooks/useSearchQuery';
import {
moveUp,
moveDown,
@ -32,7 +33,6 @@ const tableColumns = [
resizable: true,
width: 350,
},
{
id: 'Artist',
dataKey: 'artist',
@ -57,23 +57,15 @@ const tableColumns = [
];
const NowPlayingView = () => {
const [searchQuery, setSearchQuery] = useState('');
const [filteredData, setFilteredData] = useState([]);
const dispatch = useAppDispatch();
const playQueue = useAppSelector((state) => state.playQueue);
const multiSelect = useAppSelector((state) => state.multiSelect);
const dispatch = useAppDispatch();
useEffect(() => {
if (searchQuery !== '') {
setFilteredData(
playQueue.entry.filter((entry: any) => {
return entry.title.toLowerCase().includes(searchQuery.toLowerCase());
})
);
} else {
setFilteredData([]);
}
}, [playQueue?.entry, searchQuery]);
const [searchQuery, setSearchQuery] = useState('');
const filteredData = useSearchQuery(searchQuery, playQueue.entry, [
'title',
'artist',
'album',
]);
let timeout: any = null;
const handleRowClick = (e: any, rowData: any) => {

27
src/components/playlist/PlaylistList.tsx

@ -1,8 +1,9 @@
import React, { useState, useEffect } from 'react';
import React, { useState } from 'react';
import { useQuery } from 'react-query';
import { useHistory } from 'react-router-dom';
import { Tag, SelectPicker } from 'rsuite';
import settings from 'electron-settings';
import useSearchQuery from '../../hooks/useSearchQuery';
import { getPlaylists } from '../../api/api';
import ListViewType from '../viewtypes/ListViewType';
import Loader from '../loader/Loader';
@ -47,32 +48,20 @@ const tableColumns = [
];
const PlaylistList = () => {
const [searchQuery, setSearchQuery] = useState('');
const history = useHistory();
const [sortBy, setSortBy] = useState('');
const [filteredData, setFilteredData] = useState<any[]>([]);
const [viewType, setViewType] = useState(
settings.getSync('viewType') || 'list'
);
const history = useHistory();
const { isLoading, isError, data: playlists, error }: any = useQuery(
['playlists', sortBy],
() => getPlaylists(sortBy)
);
useEffect(() => {
if (searchQuery !== '') {
setFilteredData(
playlists.filter((playlist: any) => {
return (
playlist.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
playlist.comment?.toLowerCase().includes(searchQuery.toLowerCase())
);
})
);
} else {
setFilteredData([]);
}
}, [playlists, searchQuery]);
const [searchQuery, setSearchQuery] = useState('');
const filteredData = useSearchQuery(searchQuery, playlists, [
'name',
'comment',
]);
const handleRowClick = (_e: any, rowData: any) => {
history.push(`playlist/${rowData.id}`);

28
src/components/playlist/PlaylistView.tsx

@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import { useQuery } from 'react-query';
import { useParams } from 'react-router-dom';
import { getPlaylist } from '../../api/api';
@ -11,10 +11,11 @@ import {
setSelected,
clearSelected,
} from '../../redux/multiSelectSlice';
import useSearchQuery from '../../hooks/useSearchQuery';
import GenericPage from '../layout/GenericPage';
import ListViewType from '../viewtypes/ListViewType';
import Loader from '../loader/Loader';
import PlaylistViewHeader from './PlaylistViewHeader';
import GenericPageHeader from '../layout/GenericPageHeader';
interface PlaylistParams {
id: string;
@ -60,13 +61,18 @@ const tableColumns = [
];
const PlaylistView = () => {
const dispatch = useAppDispatch();
const { id } = useParams<PlaylistParams>();
const { isLoading, isError, data, error }: any = useQuery(
['playlist', id],
() => getPlaylist(id)
);
const dispatch = useAppDispatch();
const [searchQuery, setSearchQuery] = useState('');
const filteredData = useSearchQuery(searchQuery, data?.entry, [
'title',
'artist',
'album',
]);
let timeout: any = null;
const handleRowClick = (e: any, rowData: any) => {
@ -107,18 +113,20 @@ const PlaylistView = () => {
return (
<GenericPage
title="Playlists"
header={
<PlaylistViewHeader
name={data.name}
comment={data.comment}
songCount={data.songCount}
<GenericPageHeader
image={data.image}
title={data.name}
subtitle={data.comment}
searchQuery={searchQuery}
handleSearch={(e: any) => setSearchQuery(e)}
clearSearchQuery={() => setSearchQuery('')}
showSearchBar
/>
}
>
<ListViewType
data={data.entry}
data={searchQuery !== '' ? filteredData : data.entry}
tableColumns={tableColumns}
handleRowClick={handleRowClick}
handleRowDoubleClick={handleRowDoubleClick}

45
src/components/starred/StarredView.tsx

@ -3,6 +3,7 @@ import React, { useEffect, useState } from 'react';
import { useQuery } from 'react-query';
import { Nav } from 'rsuite';
import settings from 'electron-settings';
import useSearchQuery from '../../hooks/useSearchQuery';
import { useAppDispatch } from '../../redux/hooks';
import { fixPlayer2Index, setPlayQueue } from '../../redux/playQueueSlice';
import {
@ -96,9 +97,8 @@ const albumTableColumns = [
];
const StarredView = () => {
const dispatch = useAppDispatch();
const [currentPage, setCurrentPage] = useState('Tracks');
const [searchQuery, setSearchQuery] = useState('');
const [filteredData, setFilteredData] = useState([]);
const [viewType, setViewType] = useState(
settings.getSync('viewType') || 'list'
);
@ -106,37 +106,16 @@ const StarredView = () => {
'starred',
getStarred
);
const dispatch = useAppDispatch();
useEffect(() => {
if (searchQuery !== '') {
switch (currentPage) {
case 'Tracks':
setFilteredData(
data.song.filter((song: any) => {
return song.title
.toLowerCase()
.includes(searchQuery.toLowerCase());
})
);
break;
case 'Albums':
setFilteredData(
data.album.filter((album: any) => {
return album.name
.toLowerCase()
.includes(searchQuery.toLowerCase());
})
);
break;
default:
break;
}
} else {
setFilteredData([]);
}
}, [currentPage, searchQuery, data?.album, data?.song]);
const [searchQuery, setSearchQuery] = useState('');
const filteredData = useSearchQuery(
searchQuery,
currentPage === 'Tracks'
? data?.song
: currentPage === 'Albums'
? data?.album
: data?.song,
['title', 'artist', 'album']
);
let timeout: any = null;
const handleRowClick = (e: any, rowData: any) => {

3
src/components/viewtypes/GridViewType.tsx

@ -1,4 +1,5 @@
import React from 'react';
import { nanoid } from 'nanoid';
import { FlexboxGrid, Col } from 'rsuite';
import Card from '../card/Card';
@ -13,7 +14,7 @@ const GridViewType = ({
return (
<FlexboxGrid justify="center">
{data.map((item: any) => (
<FlexboxGrid.Item componentClass={Col} key={item.id}>
<FlexboxGrid.Item componentClass={Col} key={nanoid()}>
<Card
title={item[cardTitle.property]}
subtitle={`${item[cardSubtitle.property]}${cardSubtitle.unit}`}

38
src/hooks/useSearchQuery.ts

@ -0,0 +1,38 @@
import { useState, useEffect, SetStateAction } from 'react';
import _ from 'lodash';
const useSearchQuery = (
searchQuery: string,
data: any[],
filterProperties: string[]
) => {
const [filteredData, setFilteredData] = useState<any[]>([]);
const [filterProps] = useState(filterProperties);
useEffect(() => {
const debounce = setTimeout(() => {
if (searchQuery !== '') {
const matches: SetStateAction<any[]> = [];
filterProps.map((prop: string) => {
const filteredDataByProp = data.filter((entry: any) => {
return entry[prop]
?.toLowerCase()
.includes(searchQuery.toLowerCase());
});
return filteredDataByProp.map((entry) => matches.push(entry));
});
setFilteredData(_.uniqBy(matches, 'id'));
} else {
setFilteredData([]);
}
}, 500);
return () => clearTimeout(debounce);
}, [data, filterProps, searchQuery]);
return filteredData;
};
export default useSearchQuery;
Loading…
Cancel
Save