mirror of
https://github.com/jeffvli/sonixd.git
synced 2026-04-30 11:12:36 -04:00
Add configurable music folder filters
This commit is contained in:
@@ -85,7 +85,15 @@ const miscState: General = {
|
||||
};
|
||||
|
||||
const folderState: FolderSelection = {
|
||||
id: undefined,
|
||||
musicFolder: undefined,
|
||||
applied: {
|
||||
albums: true,
|
||||
artists: true,
|
||||
dashboard: false,
|
||||
search: false,
|
||||
starred: false,
|
||||
},
|
||||
currentViewedFolder: undefined,
|
||||
};
|
||||
|
||||
const mockInitialState = {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import _ from 'lodash';
|
||||
import settings from 'electron-settings';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
@@ -8,37 +8,45 @@ import PageLoader from '../loader/PageLoader';
|
||||
import GenericPage from '../layout/GenericPage';
|
||||
import GenericPageHeader from '../layout/GenericPageHeader';
|
||||
import ScrollingMenu from '../scrollingmenu/ScrollingMenu';
|
||||
import { useAppDispatch } from '../../redux/hooks';
|
||||
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
|
||||
import { setStar } from '../../redux/playQueueSlice';
|
||||
|
||||
const Dashboard = () => {
|
||||
const history = useHistory();
|
||||
const dispatch = useAppDispatch();
|
||||
const queryClient = useQueryClient();
|
||||
const folder = useAppSelector((state) => state.folder);
|
||||
const cardSize = Number(settings.getSync('gridCardSize'));
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [musicFolder, setMusicFolder] = useState(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
if (folder.applied.dashboard) {
|
||||
setMusicFolder(folder.musicFolder);
|
||||
}
|
||||
}, [folder]);
|
||||
|
||||
const { isLoading: isLoadingRecent, data: recentAlbums }: any = useQuery(
|
||||
['recentAlbums'],
|
||||
() => getAlbums({ type: 'recent', size: 20 }, 250),
|
||||
['recentAlbums', musicFolder],
|
||||
() => getAlbums({ type: 'recent', size: 20, musicFolderId: musicFolder }, 250),
|
||||
{ refetchOnWindowFocus: false }
|
||||
);
|
||||
|
||||
const { isLoading: isLoadingNewest, data: newestAlbums }: any = useQuery(
|
||||
['newestAlbums'],
|
||||
() => getAlbums({ type: 'newest', size: 20 }, 250),
|
||||
['newestAlbums', musicFolder],
|
||||
() => getAlbums({ type: 'newest', size: 20, musicFolderId: musicFolder }, 250),
|
||||
{ refetchOnWindowFocus: false }
|
||||
);
|
||||
|
||||
const { isLoading: isLoadingRandom, data: randomAlbums }: any = useQuery(
|
||||
['randomAlbums'],
|
||||
() => getAlbums({ type: 'random', size: 20 }, 250),
|
||||
['randomAlbums', musicFolder],
|
||||
() => getAlbums({ type: 'random', size: 20, musicFolderId: musicFolder }, 250),
|
||||
{ refetchOnWindowFocus: false }
|
||||
);
|
||||
|
||||
const { isLoading: isLoadingFrequent, data: frequentAlbums }: any = useQuery(
|
||||
['frequentAlbums'],
|
||||
() => getAlbums({ type: 'frequent', size: 20 }, 250),
|
||||
['frequentAlbums', musicFolder],
|
||||
() => getAlbums({ type: 'frequent', size: 20, musicFolderId: musicFolder }, 250),
|
||||
{ refetchOnWindowFocus: false }
|
||||
);
|
||||
|
||||
@@ -46,7 +54,7 @@ const Dashboard = () => {
|
||||
if (!rowData.starred) {
|
||||
await star(rowData.id, 'album');
|
||||
dispatch(setStar({ id: [rowData.id], type: 'star' }));
|
||||
queryClient.setQueryData(['recentAlbums'], (oldData: any) => {
|
||||
queryClient.setQueryData(['recentAlbums', musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData?.album, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData.album[index].starred = Date.now();
|
||||
@@ -54,7 +62,7 @@ const Dashboard = () => {
|
||||
|
||||
return oldData;
|
||||
});
|
||||
queryClient.setQueryData(['newestAlbums'], (oldData: any) => {
|
||||
queryClient.setQueryData(['newestAlbums', musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData?.album, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData.album[index].starred = Date.now();
|
||||
@@ -62,7 +70,7 @@ const Dashboard = () => {
|
||||
|
||||
return oldData;
|
||||
});
|
||||
queryClient.setQueryData(['randomAlbums'], (oldData: any) => {
|
||||
queryClient.setQueryData(['randomAlbums', musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData?.album, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData.album[index].starred = Date.now();
|
||||
@@ -70,7 +78,7 @@ const Dashboard = () => {
|
||||
|
||||
return oldData;
|
||||
});
|
||||
queryClient.setQueryData(['frequentAlbums'], (oldData: any) => {
|
||||
queryClient.setQueryData(['frequentAlbums', musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData?.album, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData.album[index].starred = Date.now();
|
||||
@@ -81,7 +89,7 @@ const Dashboard = () => {
|
||||
} else {
|
||||
await unstar(rowData.id, 'album');
|
||||
dispatch(setStar({ id: [rowData.id], type: 'unstar' }));
|
||||
queryClient.setQueryData(['recentAlbums'], (oldData: any) => {
|
||||
queryClient.setQueryData(['recentAlbums', musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData?.album, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData.album[index].starred = undefined;
|
||||
@@ -89,7 +97,7 @@ const Dashboard = () => {
|
||||
|
||||
return oldData;
|
||||
});
|
||||
queryClient.setQueryData(['newestAlbums'], (oldData: any) => {
|
||||
queryClient.setQueryData(['newestAlbums', musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData?.album, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData.album[index].starred = undefined;
|
||||
@@ -97,7 +105,7 @@ const Dashboard = () => {
|
||||
|
||||
return oldData;
|
||||
});
|
||||
queryClient.setQueryData(['randomAlbums'], (oldData: any) => {
|
||||
queryClient.setQueryData(['randomAlbums', musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData?.album, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData.album[index].starred = undefined;
|
||||
@@ -105,7 +113,7 @@ const Dashboard = () => {
|
||||
|
||||
return oldData;
|
||||
});
|
||||
queryClient.setQueryData(['frequentAlbums'], (oldData: any) => {
|
||||
queryClient.setQueryData(['frequentAlbums', musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData?.album, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData.album[index].starred = undefined;
|
||||
|
||||
@@ -11,7 +11,7 @@ import GenericPageHeader from '../layout/GenericPageHeader';
|
||||
import GenericPage from '../layout/GenericPage';
|
||||
import { getAlbumsDirect, getAllAlbums, getGenres, star, unstar } from '../../api/api';
|
||||
import PageLoader from '../loader/PageLoader';
|
||||
import { useAppDispatch } from '../../redux/hooks';
|
||||
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
|
||||
import {
|
||||
toggleSelected,
|
||||
setRangeSelected,
|
||||
@@ -36,17 +36,34 @@ const AlbumList = () => {
|
||||
const history = useHistory();
|
||||
const query = useRouterQuery();
|
||||
const queryClient = useQueryClient();
|
||||
const folder = useAppSelector((state) => state.folder);
|
||||
const [isRefreshing, setIsRefreshing] = useState(false);
|
||||
const [sortBy, setSortBy] = useState(query.get('sortType') || 'random');
|
||||
const [sortTypes, setSortTypes] = useState<any[]>();
|
||||
const [offset, setOffset] = useState(0);
|
||||
const [viewType, setViewType] = useState(settings.getSync('albumViewType'));
|
||||
const [musicFolder, setMusicFolder] = useState(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
if (folder.applied.albums) {
|
||||
setMusicFolder(folder.musicFolder);
|
||||
}
|
||||
}, [folder]);
|
||||
|
||||
const { isLoading, isError, data: albums, error }: any = useQuery(
|
||||
['albumList', offset, sortBy],
|
||||
['albumList', sortBy, musicFolder],
|
||||
() =>
|
||||
sortBy === 'random'
|
||||
? getAlbumsDirect({ type: 'random', size: settings.getSync('gridCardSize') })
|
||||
: getAllAlbums(offset, sortBy),
|
||||
? getAlbumsDirect({
|
||||
type: 'random',
|
||||
size: Number(settings.getSync('gridCardSize')),
|
||||
musicFolderId: musicFolder,
|
||||
})
|
||||
: getAllAlbums({
|
||||
type: sortBy,
|
||||
size: 500,
|
||||
offset: 0,
|
||||
musicFolderId: musicFolder,
|
||||
}),
|
||||
{
|
||||
refetchOnWindowFocus: false,
|
||||
cacheTime: 3600000, // Stay in cache for 1 hour
|
||||
@@ -110,7 +127,7 @@ const AlbumList = () => {
|
||||
const handleRowFavorite = async (rowData: any) => {
|
||||
if (!rowData.starred) {
|
||||
await star(rowData.id, 'album');
|
||||
queryClient.setQueryData(['albumList', offset, sortBy], (oldData: any) => {
|
||||
queryClient.setQueryData(['albumList', sortBy, musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData[index].starred = Date.now();
|
||||
@@ -120,7 +137,7 @@ const AlbumList = () => {
|
||||
});
|
||||
} else {
|
||||
await unstar(rowData.id, 'album');
|
||||
queryClient.setQueryData(['albumList', offset, sortBy], (oldData: any) => {
|
||||
queryClient.setQueryData(['albumList', sortBy, musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData[index].starred = undefined;
|
||||
@@ -148,9 +165,8 @@ const AlbumList = () => {
|
||||
cleanable={false}
|
||||
placeholder="Sort Type"
|
||||
onChange={async (value: string) => {
|
||||
await queryClient.cancelQueries(['albumList', offset, sortBy]);
|
||||
await queryClient.cancelQueries(['albumList', sortBy, musicFolder]);
|
||||
setSearchQuery('');
|
||||
setOffset(0);
|
||||
setSortBy(value);
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import _ from 'lodash';
|
||||
import settings from 'electron-settings';
|
||||
import { useQuery, useQueryClient } from 'react-query';
|
||||
@@ -10,7 +10,7 @@ import GenericPage from '../layout/GenericPage';
|
||||
import GenericPageHeader from '../layout/GenericPageHeader';
|
||||
import ListViewType from '../viewtypes/ListViewType';
|
||||
import PageLoader from '../loader/PageLoader';
|
||||
import { useAppDispatch } from '../../redux/hooks';
|
||||
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
|
||||
import {
|
||||
clearSelected,
|
||||
setRangeSelected,
|
||||
@@ -24,11 +24,20 @@ const ArtistList = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const history = useHistory();
|
||||
const queryClient = useQueryClient();
|
||||
const folder = useAppSelector((state) => state.folder);
|
||||
const [isRefreshing, setIsRefreshing] = useState(false);
|
||||
const [viewType, setViewType] = useState(settings.getSync('artistViewType'));
|
||||
const [musicFolder, setMusicFolder] = useState(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
if (folder.applied.artists) {
|
||||
setMusicFolder(folder.musicFolder);
|
||||
}
|
||||
}, [folder]);
|
||||
|
||||
const { isLoading, isError, data: artists, error }: any = useQuery(
|
||||
['artistList'],
|
||||
() => getArtists(),
|
||||
['artistList', musicFolder],
|
||||
() => getArtists({ musicFolderId: musicFolder }),
|
||||
{
|
||||
refetchOnWindowFocus: false,
|
||||
cacheTime: 3600000, // Stay in cache for 1 hour
|
||||
@@ -64,14 +73,14 @@ const ArtistList = () => {
|
||||
|
||||
const handleRefresh = async () => {
|
||||
setIsRefreshing(true);
|
||||
await queryClient.refetchQueries(['artistList'], { active: true });
|
||||
await queryClient.refetchQueries(['artistList', musicFolder], { active: true });
|
||||
setIsRefreshing(false);
|
||||
};
|
||||
|
||||
const handleRowFavorite = async (rowData: any) => {
|
||||
if (!rowData.starred) {
|
||||
await star(rowData.id, 'artist');
|
||||
queryClient.setQueryData(['artistList'], (oldData: any) => {
|
||||
queryClient.setQueryData(['artistList', musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData[index].starred = Date.now();
|
||||
@@ -81,7 +90,7 @@ const ArtistList = () => {
|
||||
});
|
||||
} else {
|
||||
await unstar(rowData.id, 'artist');
|
||||
queryClient.setQueryData(['artistList'], (oldData: any) => {
|
||||
queryClient.setQueryData(['artistList', musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData[index].starred = undefined;
|
||||
|
||||
@@ -4,7 +4,14 @@ import _ from 'lodash';
|
||||
import { useQuery, useQueryClient } from 'react-query';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { ButtonToolbar, Icon } from 'rsuite';
|
||||
import { getIndexes, getMusicDirectory, setRating, star, unstar } from '../../api/api';
|
||||
import {
|
||||
getIndexes,
|
||||
getMusicDirectory,
|
||||
getMusicFolders,
|
||||
setRating,
|
||||
star,
|
||||
unstar,
|
||||
} from '../../api/api';
|
||||
import PageLoader from '../loader/PageLoader';
|
||||
import ListViewType from '../viewtypes/ListViewType';
|
||||
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
|
||||
@@ -29,9 +36,11 @@ const FolderList = () => {
|
||||
const query = useRouterQuery();
|
||||
const queryClient = useQueryClient();
|
||||
const folder = useAppSelector((state) => state.folder);
|
||||
const [musicFolder, setMusicFolder] = useState(undefined);
|
||||
|
||||
const { isLoading, isError, data: indexData, error }: any = useQuery(
|
||||
['indexes'],
|
||||
() => getIndexes(),
|
||||
['indexes', musicFolder],
|
||||
() => getIndexes({ musicFolderId: musicFolder }),
|
||||
{
|
||||
refetchOnReconnect: false,
|
||||
refetchOnWindowFocus: false,
|
||||
@@ -47,6 +56,11 @@ const FolderList = () => {
|
||||
}
|
||||
);
|
||||
|
||||
const { isLoading: isLoadingMusicFolders, data: musicFolders } = useQuery(
|
||||
['musicFolders'],
|
||||
getMusicFolders
|
||||
);
|
||||
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const filteredData = useSearchQuery(
|
||||
searchQuery,
|
||||
@@ -137,7 +151,13 @@ const FolderList = () => {
|
||||
hideDivider
|
||||
header={
|
||||
<GenericPageHeader
|
||||
title={`${folderData?.name ? folderData.name : 'Select a folder'}`}
|
||||
title={`${
|
||||
folderData?.name
|
||||
? folderData.name
|
||||
: isLoadingFolderData
|
||||
? 'Loading...'
|
||||
: 'Select a folder'
|
||||
}`}
|
||||
showSearchBar
|
||||
searchQuery={searchQuery}
|
||||
handleSearch={(e: any) => setSearchQuery(e)}
|
||||
@@ -147,15 +167,14 @@ const FolderList = () => {
|
||||
<>
|
||||
<ButtonToolbar>
|
||||
<StyledInputPicker
|
||||
data={indexData.folders}
|
||||
size="sm"
|
||||
labelKey="name"
|
||||
data={isLoadingMusicFolders ? [] : musicFolders}
|
||||
defaultValue={settings.getSync('musicFolder.id') || undefined}
|
||||
valueKey="id"
|
||||
virtualized
|
||||
onChange={(e: string) => {
|
||||
history.push(`/library/folder?folderId=${e}`);
|
||||
dispatch(setCurrentViewedFolder(e));
|
||||
labelKey="name"
|
||||
onChange={(e: any) => {
|
||||
setMusicFolder(e);
|
||||
}}
|
||||
style={{ width: '250px' }}
|
||||
/>
|
||||
|
||||
<StyledButton
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import _ from 'lodash';
|
||||
import settings from 'electron-settings';
|
||||
import { useQuery, useQueryClient } from 'react-query';
|
||||
@@ -27,11 +27,20 @@ const SearchView = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const multiSelect = useAppSelector((state) => state.multiSelect);
|
||||
const playQueue = useAppSelector((state) => state.playQueue);
|
||||
const folder = useAppSelector((state) => state.folder);
|
||||
const urlQuery = query.get('query') || '';
|
||||
const cardSize = Number(settings.getSync('gridCardSize'));
|
||||
const [searchQuery, setSearchQuery] = useState(query.get('query') || '');
|
||||
const { isLoading, isError, data, error }: any = useQuery(['search', urlQuery], () =>
|
||||
search3(urlQuery)
|
||||
const [musicFolder, setMusicFolder] = useState(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
if (folder.applied.search) {
|
||||
setMusicFolder(folder.musicFolder);
|
||||
}
|
||||
}, [folder]);
|
||||
|
||||
const { isLoading, isError, data, error }: any = useQuery(['search', urlQuery, musicFolder], () =>
|
||||
search3({ query: urlQuery, songCount: 100, musicFolderId: musicFolder })
|
||||
);
|
||||
|
||||
let timeout: any = null;
|
||||
@@ -70,7 +79,7 @@ const SearchView = () => {
|
||||
const handleRowFavorite = async (rowData: any) => {
|
||||
if (!rowData.starred) {
|
||||
await star(rowData.id, 'music');
|
||||
queryClient.setQueryData(['search', urlQuery], (oldData: any) => {
|
||||
queryClient.setQueryData(['search', urlQuery, musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData.song, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData.song[index].starred = Date.now();
|
||||
@@ -80,7 +89,7 @@ const SearchView = () => {
|
||||
});
|
||||
} else {
|
||||
await unstar(rowData.id, 'album');
|
||||
queryClient.setQueryData(['search', urlQuery], (oldData: any) => {
|
||||
queryClient.setQueryData(['search', urlQuery, musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData.song, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData.song[index].starred = undefined;
|
||||
@@ -94,7 +103,7 @@ const SearchView = () => {
|
||||
const handleArtistFavorite = async (rowData: any) => {
|
||||
if (!rowData.starred) {
|
||||
await star(rowData.id, 'artist');
|
||||
queryClient.setQueryData(['search', urlQuery], (oldData: any) => {
|
||||
queryClient.setQueryData(['search', urlQuery, musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData.artist, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData.artist[index].starred = Date.now();
|
||||
@@ -104,7 +113,7 @@ const SearchView = () => {
|
||||
});
|
||||
} else {
|
||||
await unstar(rowData.id, 'album');
|
||||
queryClient.setQueryData(['search', urlQuery], (oldData: any) => {
|
||||
queryClient.setQueryData(['search', urlQuery, musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData.artist, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData.artist[index].starred = undefined;
|
||||
@@ -118,7 +127,7 @@ const SearchView = () => {
|
||||
const handleAlbumFavorite = async (rowData: any) => {
|
||||
if (!rowData.starred) {
|
||||
await star(rowData.id, 'artist');
|
||||
queryClient.setQueryData(['search', urlQuery], (oldData: any) => {
|
||||
queryClient.setQueryData(['search', urlQuery, musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData.album, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData.album[index].starred = Date.now();
|
||||
@@ -128,7 +137,7 @@ const SearchView = () => {
|
||||
});
|
||||
} else {
|
||||
await unstar(rowData.id, 'album');
|
||||
queryClient.setQueryData(['search', urlQuery], (oldData: any) => {
|
||||
queryClient.setQueryData(['search', urlQuery, musicFolder], (oldData: any) => {
|
||||
const starredIndices = _.keys(_.pickBy(oldData.album, { id: rowData.id }));
|
||||
starredIndices.forEach((index) => {
|
||||
oldData.album[index].starred = undefined;
|
||||
|
||||
@@ -1,32 +1,83 @@
|
||||
import React from 'react';
|
||||
import settings from 'electron-settings';
|
||||
import { useQuery } from 'react-query';
|
||||
import { CheckboxGroup } from 'rsuite';
|
||||
import { ConfigPanel } from '../styled';
|
||||
import { StyledInputPicker } from '../../shared/styled';
|
||||
import { useAppDispatch } from '../../../redux/hooks';
|
||||
import { StyledCheckbox, StyledInputPicker } from '../../shared/styled';
|
||||
import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
|
||||
import { getMusicFolders } from '../../../api/api';
|
||||
import { setMusicFolder } from '../../../redux/folderSlice';
|
||||
import { setAppliedFolderViews, setMusicFolder } from '../../../redux/folderSlice';
|
||||
|
||||
const ServerConfig = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const folder = useAppSelector((state) => state.folder);
|
||||
const { isLoading, data: musicFolders } = useQuery(['musicFolders'], getMusicFolders);
|
||||
|
||||
return (
|
||||
<ConfigPanel header="Server" bordered>
|
||||
<p>Select your music folder</p>
|
||||
<p>Select a music folder (leaving this blank will use all folders).</p>
|
||||
<br />
|
||||
|
||||
<StyledInputPicker
|
||||
data={!isLoading && musicFolders}
|
||||
defaultValue={settings.getSync('musicFolder') || 0}
|
||||
data={isLoading ? [] : musicFolders}
|
||||
defaultValue={settings.getSync('musicFolder.id') || undefined}
|
||||
valueKey="id"
|
||||
labelKey="name"
|
||||
cleanable={false}
|
||||
onChange={(e: any) => {
|
||||
settings.setSync('musicFolder', e);
|
||||
settings.setSync('musicFolder.id', e);
|
||||
dispatch(setMusicFolder(e));
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
<br />
|
||||
<p>Select which pages to apply music folder filtering to:</p>
|
||||
<CheckboxGroup>
|
||||
<StyledCheckbox
|
||||
defaultChecked={folder.applied.albums}
|
||||
onChange={(_v: any, e: boolean) => {
|
||||
dispatch(setAppliedFolderViews({ ...folder.applied, albums: e }));
|
||||
settings.setSync('musicFolder.albums', e);
|
||||
}}
|
||||
>
|
||||
Albums
|
||||
</StyledCheckbox>
|
||||
<StyledCheckbox
|
||||
defaultChecked={folder.applied.artists}
|
||||
onChange={(_v: any, e: boolean) => {
|
||||
dispatch(setAppliedFolderViews({ ...folder.applied, artists: e }));
|
||||
settings.setSync('musicFolder.artists', e);
|
||||
}}
|
||||
>
|
||||
Artists
|
||||
</StyledCheckbox>
|
||||
<StyledCheckbox
|
||||
defaultChecked={folder.applied.dashboard}
|
||||
onChange={(_v: any, e: boolean) => {
|
||||
dispatch(setAppliedFolderViews({ ...folder.applied, dashboard: e }));
|
||||
settings.setSync('musicFolder.dashboard', e);
|
||||
}}
|
||||
>
|
||||
Dashboard
|
||||
</StyledCheckbox>
|
||||
<StyledCheckbox
|
||||
defaultChecked={folder.applied.starred}
|
||||
onChange={(_v: any, e: boolean) => {
|
||||
dispatch(setAppliedFolderViews({ ...folder.applied, starred: e }));
|
||||
settings.setSync('musicFolder.starred', e);
|
||||
}}
|
||||
>
|
||||
Favorites
|
||||
</StyledCheckbox>
|
||||
<StyledCheckbox
|
||||
defaultChecked={folder.applied.search}
|
||||
onChange={(_v: any, e: boolean) => {
|
||||
dispatch(setAppliedFolderViews({ ...folder.applied, search: e }));
|
||||
settings.setSync('musicFolder.search', e);
|
||||
}}
|
||||
>
|
||||
Search
|
||||
</StyledCheckbox>
|
||||
</CheckboxGroup>
|
||||
</div>
|
||||
</ConfigPanel>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -46,8 +46,28 @@ const setDefaultSettings = (force: boolean) => {
|
||||
settings.setSync('scrobble', false);
|
||||
}
|
||||
|
||||
if (force || !settings.hasSync('musicFolder')) {
|
||||
settings.setSync('musicFolder', 0);
|
||||
if (force || !settings.hasSync('musicFolder.id')) {
|
||||
settings.setSync('musicFolder.id', null);
|
||||
}
|
||||
|
||||
if (force || !settings.hasSync('musicFolder.albums')) {
|
||||
settings.setSync('musicFolder.albums', true);
|
||||
}
|
||||
|
||||
if (force || !settings.hasSync('musicFolder.artists')) {
|
||||
settings.setSync('musicFolder.artists', true);
|
||||
}
|
||||
|
||||
if (force || !settings.hasSync('musicFolder.dashboard')) {
|
||||
settings.setSync('musicFolder.dashboard', false);
|
||||
}
|
||||
|
||||
if (force || !settings.hasSync('musicFolder.search')) {
|
||||
settings.setSync('musicFolder.search', false);
|
||||
}
|
||||
|
||||
if (force || !settings.hasSync('musicFolder.starred')) {
|
||||
settings.setSync('musicFolder.starred', false);
|
||||
}
|
||||
|
||||
if (force || !settings.hasSync('volume')) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useHistory } from 'react-router';
|
||||
import { useQuery, useQueryClient } from 'react-query';
|
||||
import { Nav } from 'rsuite';
|
||||
@@ -28,11 +28,24 @@ const StarredView = () => {
|
||||
const query = useRouterQuery();
|
||||
const queryClient = useQueryClient();
|
||||
const multiSelect = useAppSelector((state) => state.multiSelect);
|
||||
const folder = useAppSelector((state) => state.folder);
|
||||
const [page, setPage] = useState(query.get('page') || 'tracks');
|
||||
const [viewType, setViewType] = useState(settings.getSync('albumViewType') || 'list');
|
||||
const { isLoading, isError, data, error }: any = useQuery('starred', getStarred, {
|
||||
refetchOnWindowFocus: multiSelect.selected.length < 1,
|
||||
});
|
||||
const [musicFolder, setMusicFolder] = useState(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
if (folder.applied.starred) {
|
||||
setMusicFolder(folder.musicFolder);
|
||||
}
|
||||
}, [folder]);
|
||||
|
||||
const { isLoading, isError, data, error }: any = useQuery(
|
||||
['starred', musicFolder],
|
||||
() => getStarred({ musicFolderId: musicFolder }),
|
||||
{
|
||||
refetchOnWindowFocus: multiSelect.selected.length < 1,
|
||||
}
|
||||
);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const filteredData = useSearchQuery(
|
||||
searchQuery,
|
||||
@@ -95,21 +108,21 @@ const StarredView = () => {
|
||||
const handleRowFavorite = async (rowData: any) => {
|
||||
await unstar(rowData.id, 'music');
|
||||
dispatch(setStar({ id: [rowData.id], type: 'unstar' }));
|
||||
await queryClient.refetchQueries(['starred'], {
|
||||
await queryClient.refetchQueries(['starred', musicFolder], {
|
||||
active: true,
|
||||
});
|
||||
};
|
||||
|
||||
const handleRowFavoriteAlbum = async (rowData: any) => {
|
||||
await unstar(rowData.id, 'album');
|
||||
await queryClient.refetchQueries(['starred'], {
|
||||
await queryClient.refetchQueries(['starred', musicFolder], {
|
||||
active: true,
|
||||
});
|
||||
};
|
||||
|
||||
const handleRowFavoriteArtist = async (rowData: any) => {
|
||||
await unstar(rowData.id, 'artist');
|
||||
await queryClient.refetchQueries(['starred'], {
|
||||
await queryClient.refetchQueries(['starred', musicFolder], {
|
||||
active: true,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -2,15 +2,29 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||
import settings from 'electron-settings';
|
||||
import { mockSettings } from '../shared/mockSettings';
|
||||
|
||||
const parsedSettings = process.env.NODE_ENV === 'test' ? mockSettings : settings.getSync();
|
||||
const parsedSettings: any = process.env.NODE_ENV === 'test' ? mockSettings : settings.getSync();
|
||||
|
||||
export interface FolderSelection {
|
||||
musicFolder: string | number;
|
||||
musicFolder?: string | number;
|
||||
applied: {
|
||||
albums: boolean;
|
||||
artists: boolean;
|
||||
dashboard: boolean;
|
||||
search: boolean;
|
||||
starred: boolean;
|
||||
};
|
||||
currentViewedFolder?: string;
|
||||
}
|
||||
|
||||
const initialState: FolderSelection = {
|
||||
musicFolder: Number(parsedSettings.musicFolder) || 0,
|
||||
musicFolder: Number(parsedSettings.musicFolder.id) || undefined,
|
||||
applied: {
|
||||
albums: Boolean(parsedSettings.musicFolder.albums),
|
||||
artists: Boolean(parsedSettings.musicFolder.artists),
|
||||
dashboard: Boolean(parsedSettings.musicFolder.artists),
|
||||
search: Boolean(parsedSettings.musicFolder.search),
|
||||
starred: Boolean(parsedSettings.musicFolder.starred),
|
||||
},
|
||||
currentViewedFolder: undefined,
|
||||
};
|
||||
|
||||
@@ -25,8 +39,16 @@ const folderSlice = createSlice({
|
||||
setCurrentViewedFolder: (state, action: PayloadAction<string>) => {
|
||||
state.currentViewedFolder = action.payload;
|
||||
},
|
||||
|
||||
setAppliedFolderViews: (state, action: PayloadAction<any>) => {
|
||||
state.applied = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const { setMusicFolder, setCurrentViewedFolder } = folderSlice.actions;
|
||||
export const {
|
||||
setMusicFolder,
|
||||
setCurrentViewedFolder,
|
||||
setAppliedFolderViews,
|
||||
} = folderSlice.actions;
|
||||
export default folderSlice.reducer;
|
||||
|
||||
@@ -16,6 +16,14 @@ export const mockSettings = {
|
||||
fadeDuration: 9,
|
||||
fadeType: 'equalPower',
|
||||
scrobble: false,
|
||||
musicFolder: {
|
||||
id: null,
|
||||
albums: true,
|
||||
artists: true,
|
||||
dashboard: false,
|
||||
search: false,
|
||||
starred: false,
|
||||
},
|
||||
gridCardSize: 200,
|
||||
playlistViewType: 'grid',
|
||||
albumViewType: 'grid',
|
||||
|
||||
Reference in New Issue
Block a user