mirror of
https://github.com/antebudimir/feishin.git
synced 2025-12-31 10:03:33 +00:00
Split stores
This commit is contained in:
parent
2a858f3107
commit
b742b814c0
7 changed files with 200 additions and 122 deletions
83
src/renderer/store/album.store.ts
Normal file
83
src/renderer/store/album.store.ts
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
import merge from 'lodash/merge';
|
||||||
|
import create from 'zustand';
|
||||||
|
import { devtools, persist } from 'zustand/middleware';
|
||||||
|
import { immer } from 'zustand/middleware/immer';
|
||||||
|
import { AlbumListArgs, AlbumListSort, SortOrder } from '/@/renderer/api/types';
|
||||||
|
import { CardDisplayType } from '/@/renderer/types';
|
||||||
|
|
||||||
|
type TableProps = {
|
||||||
|
scrollOffset: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ListProps<T> = {
|
||||||
|
display: CardDisplayType;
|
||||||
|
filter: T;
|
||||||
|
grid: {
|
||||||
|
scrollOffset: number;
|
||||||
|
size: number;
|
||||||
|
};
|
||||||
|
table: TableProps;
|
||||||
|
};
|
||||||
|
|
||||||
|
type AlbumListFilter = Omit<AlbumListArgs['query'], 'startIndex' | 'limit'>;
|
||||||
|
|
||||||
|
export interface AlbumState {
|
||||||
|
list: ListProps<AlbumListFilter>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AlbumSlice extends AlbumState {
|
||||||
|
actions: {
|
||||||
|
setFilters: (data: Partial<AlbumListFilter>) => void;
|
||||||
|
setStore: (data: Partial<AlbumSlice>) => void;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useAlbumStore = create<AlbumSlice>()(
|
||||||
|
persist(
|
||||||
|
devtools(
|
||||||
|
immer((set, get) => ({
|
||||||
|
actions: {
|
||||||
|
setFilters: (data) => {
|
||||||
|
set((state) => {
|
||||||
|
state.list.filter = { ...state.list.filter, ...data };
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setStore: (data) => {
|
||||||
|
set({ ...get(), ...data });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
list: {
|
||||||
|
display: CardDisplayType.CARD,
|
||||||
|
filter: {
|
||||||
|
musicFolderId: undefined,
|
||||||
|
sortBy: AlbumListSort.RECENTLY_ADDED,
|
||||||
|
sortOrder: SortOrder.ASC,
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
scrollOffset: 0,
|
||||||
|
size: 50,
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
scrollOffset: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
{ name: 'store_album' },
|
||||||
|
),
|
||||||
|
{
|
||||||
|
merge: (persistedState, currentState) => {
|
||||||
|
return merge(currentState, persistedState);
|
||||||
|
},
|
||||||
|
name: 'store_album',
|
||||||
|
version: 1,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
export const useAlbumStoreActions = () => useAlbumStore((state) => state.actions);
|
||||||
|
|
||||||
|
export const useSetAlbumStore = () => useAlbumStore((state) => state.actions.setStore);
|
||||||
|
|
||||||
|
export const useSetAlbumFilters = () => useAlbumStore((state) => state.actions.setFilters);
|
||||||
|
|
||||||
|
export const useAlbumListStore = () => useAlbumStore((state) => state.list);
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
import merge from 'lodash/merge';
|
import merge from 'lodash/merge';
|
||||||
import { nanoid } from 'nanoid/non-secure';
|
|
||||||
import create from 'zustand';
|
import create from 'zustand';
|
||||||
import { devtools, persist } from 'zustand/middleware';
|
import { devtools, persist } from 'zustand/middleware';
|
||||||
import { immer } from 'zustand/middleware/immer';
|
import { immer } from 'zustand/middleware/immer';
|
||||||
import { AlbumListSort, SongListSort, SortOrder } from '/@/renderer/api/types';
|
import { Platform } from '/@/renderer/types';
|
||||||
import { AdvancedFilterGroup, CardDisplayType, Platform, FilterGroupType } from '/@/renderer/types';
|
|
||||||
|
|
||||||
type SidebarProps = {
|
type SidebarProps = {
|
||||||
expanded: string[];
|
expanded: string[];
|
||||||
|
|
@ -14,38 +12,12 @@ type SidebarProps = {
|
||||||
rightWidth: string;
|
rightWidth: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type LibraryPageProps<TSort> = {
|
|
||||||
list: ListProps<TSort>;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ListFilter<TSort> = {
|
|
||||||
musicFolderId?: string;
|
|
||||||
sortBy: TSort;
|
|
||||||
sortOrder: SortOrder;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ListAdvancedFilter = {
|
|
||||||
enabled: boolean;
|
|
||||||
filter: AdvancedFilterGroup;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ListProps<T> = {
|
|
||||||
advancedFilter: ListAdvancedFilter;
|
|
||||||
display: CardDisplayType;
|
|
||||||
filter: ListFilter<T>;
|
|
||||||
gridScrollOffset: number;
|
|
||||||
listScrollOffset: number;
|
|
||||||
size: number;
|
|
||||||
type: 'list' | 'grid';
|
|
||||||
};
|
|
||||||
|
|
||||||
type TitlebarProps = {
|
type TitlebarProps = {
|
||||||
backgroundColor: string;
|
backgroundColor: string;
|
||||||
outOfView: boolean;
|
outOfView: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface AppState {
|
export interface AppState {
|
||||||
albums: LibraryPageProps<AlbumListSort>;
|
|
||||||
isReorderingQueue: boolean;
|
isReorderingQueue: boolean;
|
||||||
platform: Platform;
|
platform: Platform;
|
||||||
sidebar: {
|
sidebar: {
|
||||||
|
|
@ -55,32 +27,12 @@ export interface AppState {
|
||||||
rightExpanded: boolean;
|
rightExpanded: boolean;
|
||||||
rightWidth: string;
|
rightWidth: string;
|
||||||
};
|
};
|
||||||
songs: LibraryPageProps<SongListSort>;
|
|
||||||
titlebar: TitlebarProps;
|
titlebar: TitlebarProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_ADVANCED_FILTERS = {
|
|
||||||
group: [],
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
field: '',
|
|
||||||
operator: '',
|
|
||||||
uniqueId: nanoid(),
|
|
||||||
value: '',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
type: FilterGroupType.AND,
|
|
||||||
uniqueId: nanoid(),
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface AppSlice extends AppState {
|
export interface AppSlice extends AppState {
|
||||||
actions: {
|
actions: {
|
||||||
resetServerDefaults: () => void;
|
|
||||||
setAppStore: (data: Partial<AppSlice>) => void;
|
setAppStore: (data: Partial<AppSlice>) => void;
|
||||||
setPage: (
|
|
||||||
page: 'albums' | 'songs',
|
|
||||||
options: Partial<LibraryPageProps<AlbumListSort | SongListSort>>,
|
|
||||||
) => void;
|
|
||||||
setSidebar: (options: Partial<SidebarProps>) => void;
|
setSidebar: (options: Partial<SidebarProps>) => void;
|
||||||
setTitlebar: (options: Partial<TitlebarProps>) => void;
|
setTitlebar: (options: Partial<TitlebarProps>) => void;
|
||||||
};
|
};
|
||||||
|
|
@ -91,27 +43,9 @@ export const useAppStore = create<AppSlice>()(
|
||||||
devtools(
|
devtools(
|
||||||
immer((set, get) => ({
|
immer((set, get) => ({
|
||||||
actions: {
|
actions: {
|
||||||
resetServerDefaults: () => {
|
|
||||||
set((state) => {
|
|
||||||
state.albums.list = {
|
|
||||||
...state.albums.list,
|
|
||||||
filter: {
|
|
||||||
...state.albums.list.filter,
|
|
||||||
musicFolderId: undefined,
|
|
||||||
},
|
|
||||||
gridScrollOffset: 0,
|
|
||||||
listScrollOffset: 0,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
},
|
|
||||||
setAppStore: (data) => {
|
setAppStore: (data) => {
|
||||||
set({ ...get(), ...data });
|
set({ ...get(), ...data });
|
||||||
},
|
},
|
||||||
setPage: (page: 'albums' | 'songs', data: any) => {
|
|
||||||
set((state) => {
|
|
||||||
state[page] = { ...state[page], ...data };
|
|
||||||
});
|
|
||||||
},
|
|
||||||
setSidebar: (options) => {
|
setSidebar: (options) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.sidebar = { ...state.sidebar, ...options };
|
state.sidebar = { ...state.sidebar, ...options };
|
||||||
|
|
@ -123,24 +57,6 @@ export const useAppStore = create<AppSlice>()(
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
albums: {
|
|
||||||
list: {
|
|
||||||
advancedFilter: {
|
|
||||||
enabled: false,
|
|
||||||
filter: DEFAULT_ADVANCED_FILTERS,
|
|
||||||
},
|
|
||||||
display: CardDisplayType.CARD,
|
|
||||||
filter: {
|
|
||||||
musicFolderId: undefined,
|
|
||||||
sortBy: AlbumListSort.RECENTLY_ADDED,
|
|
||||||
sortOrder: SortOrder.ASC,
|
|
||||||
},
|
|
||||||
gridScrollOffset: 0,
|
|
||||||
listScrollOffset: 0,
|
|
||||||
size: 50,
|
|
||||||
type: 'grid',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
isReorderingQueue: false,
|
isReorderingQueue: false,
|
||||||
platform: Platform.WINDOWS,
|
platform: Platform.WINDOWS,
|
||||||
sidebar: {
|
sidebar: {
|
||||||
|
|
@ -150,24 +66,6 @@ export const useAppStore = create<AppSlice>()(
|
||||||
rightExpanded: false,
|
rightExpanded: false,
|
||||||
rightWidth: '400px',
|
rightWidth: '400px',
|
||||||
},
|
},
|
||||||
songs: {
|
|
||||||
list: {
|
|
||||||
advancedFilter: {
|
|
||||||
enabled: false,
|
|
||||||
filter: DEFAULT_ADVANCED_FILTERS,
|
|
||||||
},
|
|
||||||
display: CardDisplayType.CARD,
|
|
||||||
filter: {
|
|
||||||
musicFolderId: undefined,
|
|
||||||
sortBy: SongListSort.NAME,
|
|
||||||
sortOrder: SortOrder.ASC,
|
|
||||||
},
|
|
||||||
gridScrollOffset: 0,
|
|
||||||
listScrollOffset: 0,
|
|
||||||
size: 50,
|
|
||||||
type: 'grid',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
titlebar: {
|
titlebar: {
|
||||||
backgroundColor: '#000000',
|
backgroundColor: '#000000',
|
||||||
outOfView: false,
|
outOfView: false,
|
||||||
|
|
@ -187,10 +85,6 @@ export const useAppStore = create<AppSlice>()(
|
||||||
|
|
||||||
export const useAppStoreActions = () => useAppStore((state) => state.actions);
|
export const useAppStoreActions = () => useAppStore((state) => state.actions);
|
||||||
|
|
||||||
export const useAlbumRouteStore = () => useAppStore((state) => state.albums);
|
|
||||||
|
|
||||||
export const useSongRouteStore = () => useAppStore((state) => state.songs);
|
|
||||||
|
|
||||||
export const useSidebarStore = () => useAppStore((state) => state.sidebar);
|
export const useSidebarStore = () => useAppStore((state) => state.sidebar);
|
||||||
|
|
||||||
export const useSidebarRightExpanded = () => useAppStore((state) => state.sidebar.rightExpanded);
|
export const useSidebarRightExpanded = () => useAppStore((state) => state.sidebar.rightExpanded);
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import create from 'zustand';
|
||||||
import { devtools, persist } from 'zustand/middleware';
|
import { devtools, persist } from 'zustand/middleware';
|
||||||
import { immer } from 'zustand/middleware/immer';
|
import { immer } from 'zustand/middleware/immer';
|
||||||
import { AlbumListSort, SortOrder } from '/@/renderer/api/types';
|
import { AlbumListSort, SortOrder } from '/@/renderer/api/types';
|
||||||
import { useAppStore } from '/@/renderer/store/app.store';
|
import { useAlbumStore } from '/@/renderer/store/album.store';
|
||||||
import { ServerListItem } from '/@/renderer/types';
|
import { ServerListItem } from '/@/renderer/types';
|
||||||
|
|
||||||
export interface AuthState {
|
export interface AuthState {
|
||||||
|
|
@ -45,15 +45,10 @@ export const useAuthStore = create<AuthSlice>()(
|
||||||
state.currentServer = server;
|
state.currentServer = server;
|
||||||
|
|
||||||
if (server) {
|
if (server) {
|
||||||
useAppStore.getState().actions.setPage('albums', {
|
useAlbumStore.getState().actions.setFilters({
|
||||||
list: {
|
musicFolderId: undefined,
|
||||||
...useAppStore.getState().albums.list,
|
sortBy: AlbumListSort.RECENTLY_ADDED,
|
||||||
filter: {
|
sortOrder: SortOrder.ASC,
|
||||||
...useAppStore.getState().albums.list.filter,
|
|
||||||
sortBy: AlbumListSort.RECENTLY_ADDED,
|
|
||||||
sortOrder: SortOrder.ASC,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
export * from './auth.store';
|
export * from './auth.store';
|
||||||
export * from './player.store';
|
export * from './player.store';
|
||||||
export * from './app.store';
|
export * from './app.store';
|
||||||
|
export * from './album.store';
|
||||||
|
export * from './song.store';
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ import create from 'zustand';
|
||||||
import { devtools, persist } from 'zustand/middleware';
|
import { devtools, persist } from 'zustand/middleware';
|
||||||
import { immer } from 'zustand/middleware/immer';
|
import { immer } from 'zustand/middleware/immer';
|
||||||
import shallow from 'zustand/shallow';
|
import shallow from 'zustand/shallow';
|
||||||
import { Song } from '/@/renderer/api/types';
|
import { QueueSong, Song } from '/@/renderer/api/types';
|
||||||
import { QueueSong, PlayerStatus, PlayerRepeat, PlayerShuffle, Play } from '/@/renderer/types';
|
import { PlayerStatus, PlayerRepeat, PlayerShuffle, Play } from '/@/renderer/types';
|
||||||
|
|
||||||
export interface PlayerState {
|
export interface PlayerState {
|
||||||
current: {
|
current: {
|
||||||
|
|
|
||||||
106
src/renderer/store/song.store.ts
Normal file
106
src/renderer/store/song.store.ts
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
import merge from 'lodash/merge';
|
||||||
|
import create from 'zustand';
|
||||||
|
import { devtools, persist } from 'zustand/middleware';
|
||||||
|
import { immer } from 'zustand/middleware/immer';
|
||||||
|
import { SongListArgs, SongListSort, SortOrder } from '/@/renderer/api/types';
|
||||||
|
import { DataTableProps } from '/@/renderer/store/settings.store';
|
||||||
|
import { CardDisplayType, TableColumn } from '/@/renderer/types';
|
||||||
|
|
||||||
|
type TableProps = {
|
||||||
|
scrollOffset: number;
|
||||||
|
} & DataTableProps;
|
||||||
|
|
||||||
|
type ListProps<T> = {
|
||||||
|
display: CardDisplayType;
|
||||||
|
filter: T;
|
||||||
|
table: TableProps;
|
||||||
|
};
|
||||||
|
|
||||||
|
type AlbumListFilter = Omit<SongListArgs['query'], 'startIndex' | 'limit'>;
|
||||||
|
|
||||||
|
interface SongState {
|
||||||
|
list: ListProps<AlbumListFilter>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SongSlice extends SongState {
|
||||||
|
actions: {
|
||||||
|
setFilters: (data: Partial<AlbumListFilter>) => void;
|
||||||
|
setStore: (data: Partial<SongSlice>) => void;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useSongStore = create<SongSlice>()(
|
||||||
|
persist(
|
||||||
|
devtools(
|
||||||
|
immer((set, get) => ({
|
||||||
|
actions: {
|
||||||
|
setFilters: (data) => {
|
||||||
|
set((state) => {
|
||||||
|
state.list.filter = { ...state.list.filter, ...data };
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setStore: (data) => {
|
||||||
|
set({ ...get(), ...data });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
list: {
|
||||||
|
display: CardDisplayType.TABLE,
|
||||||
|
filter: {
|
||||||
|
musicFolderId: undefined,
|
||||||
|
sortBy: SongListSort.RECENTLY_ADDED,
|
||||||
|
sortOrder: SortOrder.ASC,
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
autoFit: true,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
column: TableColumn.ROW_INDEX,
|
||||||
|
width: 50,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
column: TableColumn.TITLE_COMBINED,
|
||||||
|
width: 500,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
column: TableColumn.DURATION,
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
column: TableColumn.ALBUM,
|
||||||
|
width: 300,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
column: TableColumn.ARTIST,
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
column: TableColumn.YEAR,
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
rowHeight: 60,
|
||||||
|
scrollOffset: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
{ name: 'store_song' },
|
||||||
|
),
|
||||||
|
{
|
||||||
|
merge: (persistedState, currentState) => {
|
||||||
|
return merge(currentState, persistedState);
|
||||||
|
},
|
||||||
|
name: 'store_song',
|
||||||
|
version: 1,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
export const useSongStoreActions = () => useSongStore((state) => state.actions);
|
||||||
|
|
||||||
|
export const useSetSongStore = () => useSongStore((state) => state.actions.setStore);
|
||||||
|
|
||||||
|
export const useSongFilters = () => {
|
||||||
|
return useSongStore((state) => [state.list.filter, state.actions.setFilters]);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useSongListStore = () => useSongStore((state) => state.list);
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { Song } from '/@/renderer/api/types';
|
|
||||||
import { AppRoute } from '/@/renderer/router/routes';
|
import { AppRoute } from '/@/renderer/router/routes';
|
||||||
|
|
||||||
export type RouteSlug = {
|
export type RouteSlug = {
|
||||||
|
|
@ -22,6 +21,7 @@ export type CardRow = {
|
||||||
export enum CardDisplayType {
|
export enum CardDisplayType {
|
||||||
CARD = 'card',
|
CARD = 'card',
|
||||||
POSTER = 'poster',
|
POSTER = 'poster',
|
||||||
|
TABLE = 'table',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ListDisplayType {
|
export enum ListDisplayType {
|
||||||
|
|
@ -150,8 +150,6 @@ export enum TableColumn {
|
||||||
YEAR = 'releaseYear',
|
YEAR = 'releaseYear',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type QueueSong = Song & UniqueId;
|
|
||||||
|
|
||||||
export type PlayQueueAddOptions = {
|
export type PlayQueueAddOptions = {
|
||||||
// byData?: any[];
|
// byData?: any[];
|
||||||
byItemType: {
|
byItemType: {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue