import { create } from 'zustand'; import { devtools, persist } from 'zustand/middleware'; import { immer } from 'zustand/middleware/immer'; import { PlaylistListSort, SortOrder } from '/@/renderer/api/types'; import { PlaylistListFilter, SongListFilter } from '/@/renderer/store/list.store'; import { DataTableProps } from '/@/renderer/store/settings.store'; import { ListDisplayType, TableColumn, TablePagination } from '/@/renderer/types'; import { mergeOverridingColumns } from '/@/renderer/store/utils'; type TableProps = { pagination: TablePagination; scrollOffset: number; } & DataTableProps; type ListProps = { display: ListDisplayType; filter: T; table: TableProps; }; type DetailPaginationProps = TablePagination & { scrollOffset: number; }; type DetailTableProps = DataTableProps & { id: { [key: string]: DetailPaginationProps & { filter: SongListFilter }; }; }; type DetailProps = { display: ListDisplayType; table: DetailTableProps; }; type ListGridProps = { itemsPerRow?: number; scrollOffset?: number; }; interface PlaylistState { detail: DetailProps; grid: ListGridProps; list: ListProps; } export interface PlaylistSlice extends PlaylistState { actions: { setDetailFilters: (id: string, data: Partial) => SongListFilter; setDetailTable: (data: Partial) => void; setDetailTablePagination: (id: string, data: Partial) => void; setFilters: (data: Partial) => PlaylistListFilter; setGrid: (args: { data: Partial }) => void; setStore: (data: Partial) => void; setTable: (data: Partial) => void; setTablePagination: (args: { data: Partial }) => void; }; } export const usePlaylistStore = create()( persist( devtools( immer((set, get) => ({ actions: { setDetailFilters: (id, data) => { set((state) => { state.detail.table.id[id] = { ...state.detail.table.id[id], filter: { ...state.detail.table.id[id].filter, ...data, }, }; }); return get().detail.table.id[id].filter; }, setDetailTable: (data) => { set((state) => { state.detail.table = { ...state.detail.table, ...data }; }); }, setDetailTablePagination: (id, data) => { set((state) => { state.detail.table.id[id] = { ...state.detail.table.id[id], ...data, }; }); }, setFilters: (data) => { set((state) => { state.list.filter = { ...state.list.filter, ...data }; }); return get().list.filter; }, setGrid: (args) => { set((state) => { state.grid = { ...state.grid, ...args.data, }; }); }, setStore: (data) => { set({ ...get(), ...data }); }, setTable: (data) => { set((state) => { state.list.table = { ...state.list.table, ...data }; }); }, setTablePagination: (args) => { set((state) => { state.list.table.pagination = { ...state.list.table.pagination, ...args.data, }; }); }, }, detail: { display: ListDisplayType.TABLE, 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, }, ], id: {}, rowHeight: 60, }, }, grid: { itemsPerRow: 5, scrollOffset: 0, }, list: { display: ListDisplayType.TABLE, filter: { musicFolderId: undefined, sortBy: PlaylistListSort.NAME, sortOrder: SortOrder.ASC, }, table: { autoFit: true, columns: [ { column: TableColumn.ROW_INDEX, width: 50, }, { column: TableColumn.TITLE, width: 500, }, { column: TableColumn.SONG_COUNT, width: 100, }, ], pagination: { currentPage: 1, itemsPerPage: 100, totalItems: 1, totalPages: 1, }, rowHeight: 40, scrollOffset: 0, }, }, })), { name: 'store_playlist' }, ), { merge: mergeOverridingColumns, name: 'store_playlist', version: 1, }, ), ); export const usePlaylistStoreActions = () => usePlaylistStore((state) => state.actions); export const useSetPlaylistStore = () => usePlaylistStore((state) => state.actions.setStore); export const useSetPlaylistFilters = () => usePlaylistStore((state) => state.actions.setFilters); export const usePlaylistFilters = () => { return usePlaylistStore((state) => [state.list.filter, state.actions.setFilters]); }; export const usePlaylistGridStore = () => usePlaylistStore((state) => state.grid); export const usePlaylistListStore = () => usePlaylistStore((state) => state.list); export const usePlaylistTablePagination = () => usePlaylistStore((state) => state.list.table.pagination); export const useSetPlaylistTablePagination = () => usePlaylistStore((state) => state.actions.setTablePagination); export const useSetPlaylistTable = () => usePlaylistStore((state) => state.actions.setTable); export const usePlaylistDetailStore = () => usePlaylistStore((state) => state.detail); export const usePlaylistDetailTablePagination = (id: string) => usePlaylistStore((state) => state.detail.table.id[id]); export const useSetPlaylistDetailTablePagination = () => usePlaylistStore((state) => state.actions.setDetailTablePagination); export const useSetPlaylistDetailTable = () => usePlaylistStore((state) => state.actions.setDetailTable); export const useSetPlaylistDetailFilters = () => usePlaylistStore((state) => state.actions.setDetailFilters);