mirror of
https://github.com/antebudimir/feishin.git
synced 2026-01-01 10:23:33 +00:00
Begin normalizing list stores
This commit is contained in:
parent
918b77eebb
commit
ae292e3a5f
22 changed files with 1057 additions and 764 deletions
|
|
@ -1,138 +0,0 @@
|
|||
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 { DataTableProps } from '/@/renderer/store/settings.store';
|
||||
import { ListDisplayType, TableColumn, TablePagination } from '/@/renderer/types';
|
||||
|
||||
type TableProps = {
|
||||
pagination: TablePagination;
|
||||
scrollOffset: number;
|
||||
} & DataTableProps;
|
||||
|
||||
type ListProps<T> = {
|
||||
display: ListDisplayType;
|
||||
filter: T;
|
||||
grid: {
|
||||
scrollOffset: number;
|
||||
size: number;
|
||||
};
|
||||
table: TableProps;
|
||||
};
|
||||
|
||||
export type AlbumListFilter = Omit<AlbumListArgs['query'], 'startIndex' | 'limit'>;
|
||||
|
||||
export interface AlbumState {
|
||||
list: ListProps<AlbumListFilter>;
|
||||
}
|
||||
|
||||
export interface AlbumSlice extends AlbumState {
|
||||
actions: {
|
||||
setFilters: (data: Partial<AlbumListFilter>) => AlbumListFilter;
|
||||
setStore: (data: Partial<AlbumSlice>) => void;
|
||||
setTable: (data: Partial<TableProps>) => void;
|
||||
setTablePagination: (data: Partial<TableProps['pagination']>) => void;
|
||||
};
|
||||
}
|
||||
|
||||
export const useAlbumStore = create<AlbumSlice>()(
|
||||
persist(
|
||||
devtools(
|
||||
immer((set, get) => ({
|
||||
actions: {
|
||||
setFilters: (data) => {
|
||||
set((state) => {
|
||||
state.list.filter = { ...state.list.filter, ...data };
|
||||
});
|
||||
|
||||
return get().list.filter;
|
||||
},
|
||||
setStore: (data) => {
|
||||
set({ ...get(), ...data });
|
||||
},
|
||||
setTable: (data) => {
|
||||
set((state) => {
|
||||
state.list.table = { ...state.list.table, ...data };
|
||||
});
|
||||
},
|
||||
setTablePagination: (data) => {
|
||||
set((state) => {
|
||||
state.list.table.pagination = { ...state.list.table.pagination, ...data };
|
||||
});
|
||||
},
|
||||
},
|
||||
list: {
|
||||
display: ListDisplayType.CARD,
|
||||
filter: {
|
||||
musicFolderId: undefined,
|
||||
sortBy: AlbumListSort.RECENTLY_ADDED,
|
||||
sortOrder: SortOrder.ASC,
|
||||
},
|
||||
grid: {
|
||||
scrollOffset: 0,
|
||||
size: 50,
|
||||
},
|
||||
table: {
|
||||
autoFit: true,
|
||||
columns: [
|
||||
{
|
||||
column: TableColumn.ROW_INDEX,
|
||||
width: 50,
|
||||
},
|
||||
{
|
||||
column: TableColumn.TITLE_COMBINED,
|
||||
width: 500,
|
||||
},
|
||||
{
|
||||
column: TableColumn.DURATION,
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
column: TableColumn.ALBUM_ARTIST,
|
||||
width: 300,
|
||||
},
|
||||
{
|
||||
column: TableColumn.YEAR,
|
||||
width: 100,
|
||||
},
|
||||
],
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
itemsPerPage: 100,
|
||||
totalItems: 1,
|
||||
totalPages: 1,
|
||||
},
|
||||
rowHeight: 60,
|
||||
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);
|
||||
|
||||
export const useAlbumListFilters = () => useAlbumStore((state) => state.list.filter);
|
||||
|
||||
export const useAlbumTablePagination = () => useAlbumStore((state) => state.list.table.pagination);
|
||||
|
||||
export const useSetAlbumTablePagination = () =>
|
||||
useAlbumStore((state) => state.actions.setTablePagination);
|
||||
|
||||
export const useSetAlbumTable = () => useAlbumStore((state) => state.actions.setTable);
|
||||
|
|
@ -3,11 +3,9 @@ import { nanoid } from 'nanoid/non-secure';
|
|||
import create from 'zustand';
|
||||
import { devtools, persist } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
import { AlbumListSort, SongListSort, SortOrder } from '/@/renderer/api/types';
|
||||
import { useAlbumArtistListDataStore } from '/@/renderer/store/album-artist-list-data.store';
|
||||
import { useAlbumListDataStore } from '/@/renderer/store/album-list-data.store';
|
||||
import { useAlbumStore } from '/@/renderer/store/album.store';
|
||||
import { useSongStore } from '/@/renderer/store/song.store';
|
||||
import { useListStore } from '/@/renderer/store/list.store';
|
||||
import { ServerListItem } from '/@/renderer/types';
|
||||
|
||||
export interface AuthState {
|
||||
|
|
@ -52,16 +50,8 @@ export const useAuthStore = create<AuthSlice>()(
|
|||
state.currentServer = server;
|
||||
|
||||
if (server) {
|
||||
useAlbumStore.getState().actions.setFilters({
|
||||
musicFolderId: undefined,
|
||||
sortBy: AlbumListSort.RECENTLY_ADDED,
|
||||
sortOrder: SortOrder.DESC,
|
||||
});
|
||||
useSongStore.getState().actions.setFilters({
|
||||
musicFolderId: undefined,
|
||||
sortBy: SongListSort.RECENTLY_ADDED,
|
||||
sortOrder: SortOrder.DESC,
|
||||
});
|
||||
// Reset list filters
|
||||
useListStore.getState()._actions.resetFilter();
|
||||
|
||||
// Reset persisted grid list stores
|
||||
useAlbumListDataStore.getState().actions.setItemData([]);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
export * from './auth.store';
|
||||
export * from './player.store';
|
||||
export * from './app.store';
|
||||
export * from './album.store';
|
||||
export * from './song.store';
|
||||
export * from './album-artist.store';
|
||||
export * from './playlist.store';
|
||||
export * from './list.store';
|
||||
export * from './album-list-data.store';
|
||||
export * from './album-artist-list-data.store';
|
||||
|
|
|
|||
482
src/renderer/store/list.store.ts
Normal file
482
src/renderer/store/list.store.ts
Normal file
|
|
@ -0,0 +1,482 @@
|
|||
import merge from 'lodash/merge';
|
||||
import create from 'zustand';
|
||||
import { devtools, persist } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
import shallow from 'zustand/shallow';
|
||||
import {
|
||||
AlbumArtistListArgs,
|
||||
AlbumArtistListSort,
|
||||
AlbumListArgs,
|
||||
AlbumListSort,
|
||||
PlaylistListArgs,
|
||||
PlaylistListSort,
|
||||
SongListArgs,
|
||||
SongListSort,
|
||||
SortOrder,
|
||||
} from '/@/renderer/api/types';
|
||||
import { DataTableProps, PersistedTableColumn } from '/@/renderer/store/settings.store';
|
||||
import { ListDisplayType, TableColumn, TablePagination } from '/@/renderer/types';
|
||||
|
||||
export const generatePageKey = (page: string, id?: string) => {
|
||||
return id ? `${page}_${id}` : page;
|
||||
};
|
||||
|
||||
export type AlbumListFilter = Omit<AlbumListArgs['query'], 'startIndex' | 'limit'>;
|
||||
export type SongListFilter = Omit<SongListArgs['query'], 'startIndex' | 'limit'>;
|
||||
export type AlbumArtistListFilter = Omit<AlbumArtistListArgs['query'], 'startIndex' | 'limit'>;
|
||||
export type PlaylistListFilter = Omit<PlaylistListArgs['query'], 'startIndex' | 'limit'>;
|
||||
|
||||
export type ListKey = keyof ListState['item'] | string;
|
||||
|
||||
type FilterType = AlbumListFilter | SongListFilter | AlbumArtistListFilter | PlaylistListFilter;
|
||||
|
||||
type ListTableProps = {
|
||||
pagination: TablePagination;
|
||||
scrollOffset: number;
|
||||
} & DataTableProps;
|
||||
|
||||
type ListGridProps = {
|
||||
scrollOffset?: number;
|
||||
size?: number;
|
||||
};
|
||||
|
||||
type ItemProps<TFilter = any> = {
|
||||
display: ListDisplayType;
|
||||
filter: TFilter;
|
||||
grid?: ListGridProps;
|
||||
table: ListTableProps;
|
||||
};
|
||||
|
||||
export interface ListState {
|
||||
detail: {
|
||||
[key: string]: Omit<ItemProps<any>, 'display' | 'grid'>;
|
||||
};
|
||||
item: {
|
||||
album: ItemProps<AlbumListFilter>;
|
||||
albumArtist: ItemProps<AlbumArtistListFilter>;
|
||||
albumDetail: ItemProps<any>;
|
||||
playlist: ItemProps<PlaylistListFilter>;
|
||||
song: ItemProps<SongListFilter>;
|
||||
};
|
||||
}
|
||||
|
||||
type DeterministicArgs = { key: ListKey };
|
||||
|
||||
export interface ListSlice extends ListState {
|
||||
_actions: {
|
||||
getFilter: (args: { id?: string; key?: string }) => FilterType;
|
||||
resetFilter: () => void;
|
||||
setDisplayType: (args: { data: ListDisplayType } & DeterministicArgs) => void;
|
||||
setFilter: (args: { data: Partial<FilterType> } & DeterministicArgs) => FilterType;
|
||||
setGrid: (args: { data: Partial<ListGridProps> } & DeterministicArgs) => void;
|
||||
setStore: (data: Partial<ListSlice>) => void;
|
||||
setTable: (args: { data: Partial<ListTableProps> } & DeterministicArgs) => void;
|
||||
setTableColumns: (args: { data: PersistedTableColumn[] } & DeterministicArgs) => void;
|
||||
setTablePagination: (args: { data: Partial<TablePagination> } & DeterministicArgs) => void;
|
||||
};
|
||||
}
|
||||
|
||||
export const useListStore = create<ListSlice>()(
|
||||
persist(
|
||||
devtools(
|
||||
immer((set, get) => ({
|
||||
_actions: {
|
||||
getFilter: (args) => {
|
||||
const state = get();
|
||||
|
||||
if (args.id && args.key) {
|
||||
return {
|
||||
artistIds: [args.id],
|
||||
...state.item.song.filter,
|
||||
...state.detail[args.key]?.filter,
|
||||
jfParams: {
|
||||
...state.detail[args.key]?.filter.jfParams,
|
||||
includeItemTypes: 'Audio',
|
||||
},
|
||||
ndParams: {
|
||||
...state.detail[args.key]?.filter.ndParams,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (args.key) {
|
||||
return state.item[args.key as keyof ListState['item']].filter;
|
||||
}
|
||||
|
||||
return state.item.song.filter;
|
||||
},
|
||||
resetFilter: () => {
|
||||
set((state) => {
|
||||
state.item.album.filter = {
|
||||
musicFolderId: undefined,
|
||||
sortBy: AlbumListSort.RECENTLY_ADDED,
|
||||
sortOrder: SortOrder.DESC,
|
||||
} as AlbumListFilter;
|
||||
|
||||
state.item.song.filter = {
|
||||
musicFolderId: undefined,
|
||||
sortBy: SongListSort.RECENTLY_ADDED,
|
||||
sortOrder: SortOrder.DESC,
|
||||
} as SongListFilter;
|
||||
});
|
||||
},
|
||||
setDisplayType: (args) => {
|
||||
set((state) => {
|
||||
const [page] = args.key.split('_');
|
||||
state.item[page as keyof ListState['item']].display = args.data;
|
||||
});
|
||||
},
|
||||
setFilter: (args) => {
|
||||
const [, id] = args.key.split('_');
|
||||
console.log('args', args);
|
||||
|
||||
set((state) => {
|
||||
if (id) {
|
||||
if (!state.detail[args.key]) {
|
||||
state.detail[args.key] = {
|
||||
filter: {} as FilterType,
|
||||
table: {
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
itemsPerPage: 100,
|
||||
totalItems: 0,
|
||||
totalPages: 0,
|
||||
},
|
||||
} as ListTableProps,
|
||||
};
|
||||
}
|
||||
|
||||
state.detail[args.key].filter = {
|
||||
...state.detail[args.key as keyof ListState['item']].filter,
|
||||
...args.data,
|
||||
} as FilterType;
|
||||
} else {
|
||||
state.item[args.key as keyof ListState['item']].filter = {
|
||||
...state.item[args.key as keyof ListState['item']].filter,
|
||||
...args.data,
|
||||
} as FilterType;
|
||||
}
|
||||
});
|
||||
|
||||
return get()._actions.getFilter({ id, key: args.key });
|
||||
},
|
||||
setGrid: (args) => {
|
||||
set((state) => {
|
||||
if (state.item[args.key as keyof ListState['item']].grid) {
|
||||
state.item[args.key as keyof ListState['item']].grid = {
|
||||
...state.item[args.key as keyof ListState['item']]?.grid,
|
||||
...args.data,
|
||||
};
|
||||
}
|
||||
});
|
||||
},
|
||||
setStore: (data) => {
|
||||
set({ ...get(), ...data });
|
||||
},
|
||||
setTable: (args) => {
|
||||
set((state) => {
|
||||
const [page, id] = args.key.split('_');
|
||||
|
||||
if (id) {
|
||||
if (!state.detail[args.key]) {
|
||||
state.detail[args.key] = {
|
||||
filter: {} as FilterType,
|
||||
table: {
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
itemsPerPage: 100,
|
||||
totalItems: 0,
|
||||
totalPages: 0,
|
||||
},
|
||||
} as ListTableProps,
|
||||
};
|
||||
}
|
||||
|
||||
if (!state.detail[args.key]?.table) {
|
||||
state.detail[args.key].table = {
|
||||
...state.item[page as keyof ListState['item']].table,
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
itemsPerPage: 100,
|
||||
totalItems: 0,
|
||||
totalPages: 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (!state.detail[args.key]?.filter) {
|
||||
state.detail[args.key].filter = {
|
||||
...state.item[page as keyof ListState['item']].filter,
|
||||
jfParams: {},
|
||||
ndParams: {},
|
||||
};
|
||||
}
|
||||
} else {
|
||||
state.item[page as keyof ListState['item']].table = {
|
||||
...state.item[page as keyof ListState['item']].table,
|
||||
...args.data,
|
||||
};
|
||||
}
|
||||
});
|
||||
},
|
||||
setTableColumns: (args) => {
|
||||
set((state) => {
|
||||
state.item[args.key as keyof ListState['item']].table.columns = {
|
||||
...state.item[args.key as keyof ListState['item']].table.columns,
|
||||
...args.data,
|
||||
};
|
||||
});
|
||||
},
|
||||
setTablePagination: (args) => {
|
||||
set((state) => {
|
||||
const [, id] = args.key.split('_');
|
||||
|
||||
if (id) {
|
||||
if (!state.detail[args.key]) {
|
||||
state.detail[args.key] = {
|
||||
filter: {} as FilterType,
|
||||
table: {
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
itemsPerPage: 100,
|
||||
totalItems: 0,
|
||||
totalPages: 0,
|
||||
},
|
||||
} as ListTableProps,
|
||||
};
|
||||
}
|
||||
|
||||
state.detail[args.key as keyof ListState['item']].table.pagination = {
|
||||
...state.detail[args.key as keyof ListState['item']].table.pagination,
|
||||
...args.data,
|
||||
};
|
||||
} else {
|
||||
state.item[args.key as keyof ListState['item']].table.pagination = {
|
||||
...state.item[args.key as keyof ListState['item']].table.pagination,
|
||||
...args.data,
|
||||
};
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
detail: {},
|
||||
item: {
|
||||
album: {
|
||||
display: ListDisplayType.CARD,
|
||||
filter: {
|
||||
sortBy: AlbumListSort.RECENTLY_ADDED,
|
||||
sortOrder: SortOrder.DESC,
|
||||
},
|
||||
grid: { scrollOffset: 0, size: 0 },
|
||||
table: {
|
||||
autoFit: true,
|
||||
columns: [
|
||||
{
|
||||
column: TableColumn.ROW_INDEX,
|
||||
width: 50,
|
||||
},
|
||||
{
|
||||
column: TableColumn.TITLE_COMBINED,
|
||||
width: 500,
|
||||
},
|
||||
{
|
||||
column: TableColumn.DURATION,
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
column: TableColumn.ALBUM_ARTIST,
|
||||
width: 300,
|
||||
},
|
||||
{
|
||||
column: TableColumn.YEAR,
|
||||
width: 100,
|
||||
},
|
||||
],
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
itemsPerPage: 100,
|
||||
totalItems: 1,
|
||||
totalPages: 1,
|
||||
},
|
||||
rowHeight: 60,
|
||||
scrollOffset: 0,
|
||||
},
|
||||
},
|
||||
albumArtist: {
|
||||
display: ListDisplayType.CARD,
|
||||
filter: {
|
||||
sortBy: AlbumArtistListSort.NAME,
|
||||
sortOrder: SortOrder.DESC,
|
||||
},
|
||||
grid: { scrollOffset: 0, size: 0 },
|
||||
table: {
|
||||
autoFit: true,
|
||||
columns: [
|
||||
{
|
||||
column: TableColumn.ROW_INDEX,
|
||||
width: 50,
|
||||
},
|
||||
{
|
||||
column: TableColumn.TITLE_COMBINED,
|
||||
width: 500,
|
||||
},
|
||||
],
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
itemsPerPage: 100,
|
||||
totalItems: 1,
|
||||
totalPages: 1,
|
||||
},
|
||||
rowHeight: 60,
|
||||
scrollOffset: 0,
|
||||
},
|
||||
},
|
||||
albumDetail: {
|
||||
display: ListDisplayType.TABLE,
|
||||
filter: {
|
||||
sortBy: SongListSort.ALBUM,
|
||||
sortOrder: SortOrder.ASC,
|
||||
},
|
||||
table: {
|
||||
autoFit: true,
|
||||
columns: [],
|
||||
followCurrentSong: false,
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
itemsPerPage: 100,
|
||||
totalItems: 1,
|
||||
totalPages: 1,
|
||||
},
|
||||
rowHeight: 60,
|
||||
scrollOffset: 0,
|
||||
},
|
||||
},
|
||||
playlist: {
|
||||
display: ListDisplayType.CARD,
|
||||
filter: {
|
||||
sortBy: PlaylistListSort.NAME,
|
||||
sortOrder: SortOrder.DESC,
|
||||
},
|
||||
grid: { scrollOffset: 0, size: 0 },
|
||||
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: 500,
|
||||
},
|
||||
],
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
itemsPerPage: 100,
|
||||
totalItems: 1,
|
||||
totalPages: 1,
|
||||
},
|
||||
rowHeight: 60,
|
||||
scrollOffset: 0,
|
||||
},
|
||||
},
|
||||
song: {
|
||||
display: ListDisplayType.CARD,
|
||||
filter: {
|
||||
sortBy: SongListSort.RECENTLY_ADDED,
|
||||
sortOrder: SortOrder.DESC,
|
||||
},
|
||||
grid: { scrollOffset: 0, size: 0 },
|
||||
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,
|
||||
},
|
||||
{
|
||||
column: TableColumn.DATE_ADDED,
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
column: TableColumn.PLAY_COUNT,
|
||||
width: 100,
|
||||
},
|
||||
],
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
itemsPerPage: 100,
|
||||
totalItems: 1,
|
||||
totalPages: 1,
|
||||
},
|
||||
rowHeight: 60,
|
||||
scrollOffset: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
})),
|
||||
{ name: 'store_list' },
|
||||
),
|
||||
{
|
||||
merge: (persistedState, currentState) => {
|
||||
return merge(currentState, persistedState);
|
||||
},
|
||||
name: 'store_list',
|
||||
partialize: (state) => {
|
||||
return Object.fromEntries(
|
||||
Object.entries(state).filter(([key]) => !['detail'].includes(key)),
|
||||
);
|
||||
},
|
||||
version: 1,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
export const useListStoreActions = () => useListStore((state) => state._actions);
|
||||
|
||||
export const useAlbumListStore = () => useListStore((state) => state.item.album, shallow);
|
||||
|
||||
export const useAlbumArtistListStore = () =>
|
||||
useListStore((state) => state.item.albumArtist, shallow);
|
||||
|
||||
export const useSongListStore = () => useListStore((state) => state.item.song, shallow);
|
||||
|
||||
export const useSongListFilter = (args: { id?: string; key?: string }) =>
|
||||
useListStore((state) => {
|
||||
return state._actions.getFilter({ id: args.id, key: args.key }) as SongListFilter;
|
||||
}, shallow);
|
||||
|
||||
export const useAlbumListFilter = (args: { id?: string; key?: string }) =>
|
||||
useListStore((state) => {
|
||||
return state._actions.getFilter({ id: args.id, key: args.key }) as AlbumListFilter;
|
||||
}, shallow);
|
||||
|
||||
export const useListDetail = (key: string) => useListStore((state) => state.detail[key], shallow);
|
||||
|
|
@ -1,146 +0,0 @@
|
|||
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 { ListDisplayType, TableColumn, TablePagination } from '/@/renderer/types';
|
||||
|
||||
type TableProps = {
|
||||
pagination: TablePagination;
|
||||
scrollOffset: number;
|
||||
} & DataTableProps;
|
||||
|
||||
type ListProps<T> = {
|
||||
display: ListDisplayType;
|
||||
filter: T;
|
||||
table: TableProps;
|
||||
};
|
||||
|
||||
export type SongListFilter = Omit<SongListArgs['query'], 'startIndex' | 'limit'>;
|
||||
|
||||
interface SongState {
|
||||
list: ListProps<SongListFilter>;
|
||||
}
|
||||
|
||||
export interface SongSlice extends SongState {
|
||||
actions: {
|
||||
setFilters: (data: Partial<SongListFilter>) => SongListFilter;
|
||||
setStore: (data: Partial<SongSlice>) => void;
|
||||
setTable: (data: Partial<TableProps>) => void;
|
||||
setTablePagination: (data: Partial<TableProps['pagination']>) => void;
|
||||
};
|
||||
}
|
||||
|
||||
export const useSongStore = create<SongSlice>()(
|
||||
persist(
|
||||
devtools(
|
||||
immer((set, get) => ({
|
||||
actions: {
|
||||
setFilters: (data) => {
|
||||
set((state) => {
|
||||
state.list.filter = { ...state.list.filter, ...data };
|
||||
});
|
||||
|
||||
return get().list.filter;
|
||||
},
|
||||
setStore: (data) => {
|
||||
set({ ...get(), ...data });
|
||||
},
|
||||
setTable: (data) => {
|
||||
set((state) => {
|
||||
state.list.table = { ...state.list.table, ...data };
|
||||
});
|
||||
},
|
||||
setTablePagination: (data) => {
|
||||
set((state) => {
|
||||
state.list.table.pagination = { ...state.list.table.pagination, ...data };
|
||||
});
|
||||
},
|
||||
},
|
||||
list: {
|
||||
display: ListDisplayType.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,
|
||||
},
|
||||
{
|
||||
column: TableColumn.DATE_ADDED,
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
column: TableColumn.PLAY_COUNT,
|
||||
width: 100,
|
||||
},
|
||||
],
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
itemsPerPage: 100,
|
||||
totalItems: 1,
|
||||
totalPages: 1,
|
||||
},
|
||||
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 useSetSongFilters = () => useSongStore((state) => state.actions.setFilters);
|
||||
|
||||
export const useSongFilters = () => {
|
||||
return useSongStore((state) => [state.list.filter, state.actions.setFilters]);
|
||||
};
|
||||
|
||||
export const useSongListFilters = () => useSongStore((state) => state.list.filter);
|
||||
|
||||
export const useSongListStore = () => useSongStore((state) => state.list);
|
||||
|
||||
export const useSongTablePagination = () => useSongStore((state) => state.list.table.pagination);
|
||||
|
||||
export const useSetSongTablePagination = () =>
|
||||
useSongStore((state) => state.actions.setTablePagination);
|
||||
|
||||
export const useSetSongTable = () => useSongStore((state) => state.actions.setTable);
|
||||
Loading…
Add table
Add a link
Reference in a new issue