mirror of
https://github.com/antebudimir/feishin.git
synced 2026-01-02 19:01:40 +00:00
restructure files onto electron-vite boilerplate
This commit is contained in:
parent
91ce2cd8a1
commit
1cf587bc8f
457 changed files with 9927 additions and 11705 deletions
|
|
@ -2,16 +2,16 @@ import { create } from 'zustand';
|
|||
import { devtools } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
|
||||
export interface AlbumArtistListDataState {
|
||||
itemData: any[];
|
||||
}
|
||||
|
||||
export interface AlbumArtistListDataSlice extends AlbumArtistListDataState {
|
||||
actions: {
|
||||
setItemData: (data: any[]) => void;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AlbumArtistListDataState {
|
||||
itemData: any[];
|
||||
}
|
||||
|
||||
export const useAlbumArtistListDataStore = create<AlbumArtistListDataSlice>()(
|
||||
devtools(
|
||||
immer((set) => ({
|
||||
|
|
|
|||
|
|
@ -1,15 +1,26 @@
|
|||
import { create } from 'zustand';
|
||||
import { devtools, persist } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
|
||||
import { AlbumArtistListArgs, AlbumArtistListSort, SortOrder } from '/@/renderer/api/types';
|
||||
import { DataTableProps } from '/@/renderer/store/settings.store';
|
||||
import { ListDisplayType, TableColumn, TablePagination } from '/@/renderer/types';
|
||||
import { mergeOverridingColumns } from '/@/renderer/store/utils';
|
||||
import { ListDisplayType, TableColumn, TablePagination } from '/@/renderer/types';
|
||||
|
||||
type TableProps = {
|
||||
pagination: TablePagination;
|
||||
scrollOffset: number;
|
||||
} & DataTableProps;
|
||||
export type AlbumArtistListFilter = Omit<AlbumArtistListArgs['query'], 'limit' | 'startIndex'>;
|
||||
|
||||
export interface AlbumArtistSlice extends AlbumArtistState {
|
||||
actions: {
|
||||
setFilters: (data: Partial<AlbumArtistListFilter>) => AlbumArtistListFilter;
|
||||
setStore: (data: Partial<AlbumArtistSlice>) => void;
|
||||
setTable: (data: Partial<TableProps>) => void;
|
||||
setTablePagination: (data: Partial<TableProps['pagination']>) => void;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AlbumArtistState {
|
||||
list: ListProps<AlbumArtistListFilter>;
|
||||
}
|
||||
|
||||
type ListProps<T> = {
|
||||
display: ListDisplayType;
|
||||
|
|
@ -21,20 +32,10 @@ type ListProps<T> = {
|
|||
table: TableProps;
|
||||
};
|
||||
|
||||
export type AlbumArtistListFilter = Omit<AlbumArtistListArgs['query'], 'startIndex' | 'limit'>;
|
||||
|
||||
export interface AlbumArtistState {
|
||||
list: ListProps<AlbumArtistListFilter>;
|
||||
}
|
||||
|
||||
export interface AlbumArtistSlice extends AlbumArtistState {
|
||||
actions: {
|
||||
setFilters: (data: Partial<AlbumArtistListFilter>) => AlbumArtistListFilter;
|
||||
setStore: (data: Partial<AlbumArtistSlice>) => void;
|
||||
setTable: (data: Partial<TableProps>) => void;
|
||||
setTablePagination: (data: Partial<TableProps['pagination']>) => void;
|
||||
};
|
||||
}
|
||||
type TableProps = DataTableProps & {
|
||||
pagination: TablePagination;
|
||||
scrollOffset: number;
|
||||
};
|
||||
|
||||
export const useAlbumArtistStore = create<AlbumArtistSlice>()(
|
||||
persist(
|
||||
|
|
|
|||
|
|
@ -2,10 +2,6 @@ import { create } from 'zustand';
|
|||
import { devtools } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
|
||||
export interface AlbumListDataState {
|
||||
itemData: any[];
|
||||
}
|
||||
|
||||
export interface AlbumListDataSlice extends AlbumListDataState {
|
||||
actions: {
|
||||
setItemData: (data: any[]) => void;
|
||||
|
|
@ -13,6 +9,10 @@ export interface AlbumListDataSlice extends AlbumListDataState {
|
|||
};
|
||||
}
|
||||
|
||||
export interface AlbumListDataState {
|
||||
itemData: any[];
|
||||
}
|
||||
|
||||
export const useAlbumListDataStore = create<AlbumListDataSlice>()(
|
||||
devtools(
|
||||
immer((set) => ({
|
||||
|
|
|
|||
|
|
@ -2,8 +2,32 @@ import merge from 'lodash/merge';
|
|||
import { create } from 'zustand';
|
||||
import { devtools, persist } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
|
||||
import { Platform } from '/@/renderer/types';
|
||||
|
||||
export interface AppSlice extends AppState {
|
||||
actions: {
|
||||
setAppStore: (data: Partial<AppSlice>) => void;
|
||||
setSideBar: (options: Partial<SidebarProps>) => void;
|
||||
setTitleBar: (options: Partial<TitlebarProps>) => void;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AppState {
|
||||
commandPalette: CommandPaletteProps;
|
||||
isReorderingQueue: boolean;
|
||||
platform: Platform;
|
||||
sidebar: SidebarProps;
|
||||
titlebar: TitlebarProps;
|
||||
}
|
||||
|
||||
type CommandPaletteProps = {
|
||||
close: () => void;
|
||||
open: () => void;
|
||||
opened: boolean;
|
||||
toggle: () => void;
|
||||
};
|
||||
|
||||
type SidebarProps = {
|
||||
collapsed: boolean;
|
||||
expanded: string[];
|
||||
|
|
@ -18,29 +42,6 @@ type TitlebarProps = {
|
|||
outOfView: boolean;
|
||||
};
|
||||
|
||||
type CommandPaletteProps = {
|
||||
close: () => void;
|
||||
open: () => void;
|
||||
opened: boolean;
|
||||
toggle: () => void;
|
||||
};
|
||||
|
||||
export interface AppState {
|
||||
commandPalette: CommandPaletteProps;
|
||||
isReorderingQueue: boolean;
|
||||
platform: Platform;
|
||||
sidebar: SidebarProps;
|
||||
titlebar: TitlebarProps;
|
||||
}
|
||||
|
||||
export interface AppSlice extends AppState {
|
||||
actions: {
|
||||
setAppStore: (data: Partial<AppSlice>) => void;
|
||||
setSideBar: (options: Partial<SidebarProps>) => void;
|
||||
setTitleBar: (options: Partial<TitlebarProps>) => void;
|
||||
};
|
||||
}
|
||||
|
||||
export const useAppStore = create<AppSlice>()(
|
||||
persist(
|
||||
devtools(
|
||||
|
|
|
|||
|
|
@ -3,27 +3,28 @@ import { nanoid } from 'nanoid/non-secure';
|
|||
import { create } from 'zustand';
|
||||
import { devtools, persist } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
|
||||
import { ServerListItem } from '/@/renderer/api/types';
|
||||
import { useAlbumArtistListDataStore } from '/@/renderer/store/album-artist-list-data.store';
|
||||
import { useAlbumListDataStore } from '/@/renderer/store/album-list-data.store';
|
||||
import { useListStore } from '/@/renderer/store/list.store';
|
||||
import { ServerListItem } from '/@/renderer/api/types';
|
||||
|
||||
export interface AuthState {
|
||||
currentServer: ServerListItem | null;
|
||||
deviceId: string;
|
||||
serverList: Record<string, ServerListItem>;
|
||||
}
|
||||
|
||||
export interface AuthSlice extends AuthState {
|
||||
actions: {
|
||||
addServer: (args: ServerListItem) => void;
|
||||
deleteServer: (id: string) => void;
|
||||
getServer: (id: string) => ServerListItem | null;
|
||||
setCurrentServer: (server: ServerListItem | null) => void;
|
||||
getServer: (id: string) => null | ServerListItem;
|
||||
setCurrentServer: (server: null | ServerListItem) => void;
|
||||
updateServer: (id: string, args: Partial<ServerListItem>) => void;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AuthState {
|
||||
currentServer: null | ServerListItem;
|
||||
deviceId: string;
|
||||
serverList: Record<string, ServerListItem>;
|
||||
}
|
||||
|
||||
export const useAuthStore = create<AuthSlice>()(
|
||||
persist(
|
||||
devtools(
|
||||
|
|
|
|||
|
|
@ -2,6 +2,19 @@ import { create } from 'zustand';
|
|||
import { devtools, subscribeWithSelector } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
|
||||
export interface EventSlice extends EventState {
|
||||
actions: {
|
||||
favorite: (ids: string[], favorite: boolean) => void;
|
||||
play: (id: string) => void;
|
||||
rate: (ids: string[], rating: null | number) => void;
|
||||
};
|
||||
}
|
||||
|
||||
export interface EventState {
|
||||
event: null | UserEvent;
|
||||
ids: string[];
|
||||
}
|
||||
|
||||
export type FavoriteEvent = {
|
||||
event: 'favorite';
|
||||
favorite: boolean;
|
||||
|
|
@ -14,24 +27,11 @@ export type PlayEvent = {
|
|||
|
||||
export type RatingEvent = {
|
||||
event: 'rating';
|
||||
rating: number | null;
|
||||
rating: null | number;
|
||||
};
|
||||
|
||||
export type UserEvent = FavoriteEvent | PlayEvent | RatingEvent;
|
||||
|
||||
export interface EventState {
|
||||
event: UserEvent | null;
|
||||
ids: string[];
|
||||
}
|
||||
|
||||
export interface EventSlice extends EventState {
|
||||
actions: {
|
||||
favorite: (ids: string[], favorite: boolean) => void;
|
||||
play: (id: string) => void;
|
||||
rate: (ids: string[], rating: number | null) => void;
|
||||
};
|
||||
}
|
||||
|
||||
export const useEventStore = create<EventSlice>()(
|
||||
subscribeWithSelector(
|
||||
devtools(
|
||||
|
|
|
|||
|
|
@ -3,8 +3,14 @@ import { create } from 'zustand';
|
|||
import { devtools, persist } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
|
||||
export interface FullScreenPlayerSlice extends FullScreenPlayerState {
|
||||
actions: {
|
||||
setStore: (data: Partial<FullScreenPlayerSlice>) => void;
|
||||
};
|
||||
}
|
||||
|
||||
interface FullScreenPlayerState {
|
||||
activeTab: string | 'queue' | 'related' | 'lyrics';
|
||||
activeTab: 'lyrics' | 'queue' | 'related' | string;
|
||||
dynamicBackground?: boolean;
|
||||
dynamicImageBlur: number;
|
||||
dynamicIsImage?: boolean;
|
||||
|
|
@ -13,12 +19,6 @@ interface FullScreenPlayerState {
|
|||
useImageAspectRatio: boolean;
|
||||
}
|
||||
|
||||
export interface FullScreenPlayerSlice extends FullScreenPlayerState {
|
||||
actions: {
|
||||
setStore: (data: Partial<FullScreenPlayerSlice>) => void;
|
||||
};
|
||||
}
|
||||
|
||||
export const useFullScreenPlayerStore = create<FullScreenPlayerSlice>()(
|
||||
persist(
|
||||
devtools(
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
export * from './auth.store';
|
||||
export * from './player.store';
|
||||
export * from './app.store';
|
||||
export * from './list.store';
|
||||
export * from './playlist.store';
|
||||
export * from './album-list-data.store';
|
||||
export * from './album-artist-list-data.store';
|
||||
export * from './album-list-data.store';
|
||||
export * from './app.store';
|
||||
export * from './auth.store';
|
||||
export * from './full-screen-player.store';
|
||||
export * from './list.store';
|
||||
export * from './player.store';
|
||||
export * from './playlist.store';
|
||||
export * from './settings.store';
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { create } from 'zustand';
|
|||
import { devtools, persist } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
import { shallow } from 'zustand/shallow';
|
||||
|
||||
import {
|
||||
AlbumArtistListArgs,
|
||||
AlbumArtistListSort,
|
||||
|
|
@ -18,33 +19,18 @@ import {
|
|||
SortOrder,
|
||||
} from '/@/renderer/api/types';
|
||||
import { DataTableProps, PersistedTableColumn } from '/@/renderer/store/settings.store';
|
||||
import { ListDisplayType, TableColumn, TablePagination } from '/@/renderer/types';
|
||||
import { mergeOverridingColumns } from '/@/renderer/store/utils';
|
||||
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 ArtistListFilter = Omit<ArtistListArgs['query'], 'startIndex' | 'limit'>;
|
||||
export type PlaylistListFilter = Omit<PlaylistListArgs['query'], 'startIndex' | 'limit'>;
|
||||
export type GenreListFilter = Omit<GenreListArgs['query'], 'startIndex' | 'limit'>;
|
||||
|
||||
type FilterType =
|
||||
| AlbumListFilter
|
||||
| SongListFilter
|
||||
| AlbumArtistListFilter
|
||||
| ArtistListFilter
|
||||
| PlaylistListFilter
|
||||
| GenreListFilter;
|
||||
|
||||
export type ListTableProps = {
|
||||
pagination: TablePagination;
|
||||
scrollOffset: number;
|
||||
} & DataTableProps;
|
||||
|
||||
export type AlbumArtistListFilter = Omit<AlbumArtistListArgs['query'], 'limit' | 'startIndex'>;
|
||||
export type AlbumListFilter = Omit<AlbumListArgs['query'], 'limit' | 'startIndex'>;
|
||||
export type ArtistListFilter = Omit<ArtistListArgs['query'], 'limit' | 'startIndex'>;
|
||||
export type GenreListFilter = Omit<GenreListArgs['query'], 'limit' | 'startIndex'>;
|
||||
export type ListDeterministicArgs = { key: ListKey };
|
||||
export type ListGridProps = {
|
||||
itemGap?: number;
|
||||
itemSize?: number;
|
||||
|
|
@ -59,6 +45,35 @@ export type ListItemProps<TFilter = any> = {
|
|||
table: ListTableProps;
|
||||
};
|
||||
|
||||
export type ListKey = keyof ListState['item'] | string;
|
||||
|
||||
export interface ListSlice extends ListState {
|
||||
_actions: {
|
||||
getFilter: (args: {
|
||||
customFilters?: Record<any, any>;
|
||||
id?: string;
|
||||
itemType: LibraryItem;
|
||||
key?: string;
|
||||
}) => FilterType;
|
||||
resetFilter: () => void;
|
||||
setDisplayType: (args: ListDeterministicArgs & { data: ListDisplayType }) => void;
|
||||
setFilter: (
|
||||
args: ListDeterministicArgs & {
|
||||
customFilters?: Record<any, any>;
|
||||
data: Partial<FilterType>;
|
||||
itemType: LibraryItem;
|
||||
},
|
||||
) => FilterType;
|
||||
setGrid: (args: ListDeterministicArgs & { data: Partial<ListGridProps> }) => void;
|
||||
setStore: (data: Partial<ListSlice>) => void;
|
||||
setTable: (args: ListDeterministicArgs & { data: Partial<ListTableProps> }) => void;
|
||||
setTableColumns: (args: ListDeterministicArgs & { data: PersistedTableColumn[] }) => void;
|
||||
setTablePagination: (
|
||||
args: ListDeterministicArgs & { data: Partial<TablePagination> },
|
||||
) => void;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ListState {
|
||||
detail: {
|
||||
[key: string]: Omit<ListItemProps<any>, 'display'>;
|
||||
|
|
@ -75,36 +90,22 @@ export interface ListState {
|
|||
};
|
||||
}
|
||||
|
||||
export type ListKey = keyof ListState['item'] | string;
|
||||
export type ListTableProps = DataTableProps & {
|
||||
pagination: TablePagination;
|
||||
scrollOffset: number;
|
||||
};
|
||||
|
||||
export type ListDeterministicArgs = { key: ListKey };
|
||||
export type PlaylistListFilter = Omit<PlaylistListArgs['query'], 'limit' | 'startIndex'>;
|
||||
|
||||
export interface ListSlice extends ListState {
|
||||
_actions: {
|
||||
getFilter: (args: {
|
||||
customFilters?: Record<any, any>;
|
||||
id?: string;
|
||||
itemType: LibraryItem;
|
||||
key?: string;
|
||||
}) => FilterType;
|
||||
resetFilter: () => void;
|
||||
setDisplayType: (args: { data: ListDisplayType } & ListDeterministicArgs) => void;
|
||||
setFilter: (
|
||||
args: {
|
||||
customFilters?: Record<any, any>;
|
||||
data: Partial<FilterType>;
|
||||
itemType: LibraryItem;
|
||||
} & ListDeterministicArgs,
|
||||
) => FilterType;
|
||||
setGrid: (args: { data: Partial<ListGridProps> } & ListDeterministicArgs) => void;
|
||||
setStore: (data: Partial<ListSlice>) => void;
|
||||
setTable: (args: { data: Partial<ListTableProps> } & ListDeterministicArgs) => void;
|
||||
setTableColumns: (args: { data: PersistedTableColumn[] } & ListDeterministicArgs) => void;
|
||||
setTablePagination: (
|
||||
args: { data: Partial<TablePagination> } & ListDeterministicArgs,
|
||||
) => void;
|
||||
};
|
||||
}
|
||||
export type SongListFilter = Omit<SongListArgs['query'], 'limit' | 'startIndex'>;
|
||||
|
||||
type FilterType =
|
||||
| AlbumArtistListFilter
|
||||
| AlbumListFilter
|
||||
| ArtistListFilter
|
||||
| GenreListFilter
|
||||
| PlaylistListFilter
|
||||
| SongListFilter;
|
||||
|
||||
export const useListStore = create<ListSlice>()(
|
||||
persist(
|
||||
|
|
@ -678,7 +679,7 @@ export const useListStoreByKey = <TFilter>(args: {
|
|||
};
|
||||
|
||||
export const useListFilterByKey = <TFilter>(args: {
|
||||
filter?: Partial<TFilter> | any;
|
||||
filter?: any | Partial<TFilter>;
|
||||
key: string;
|
||||
}): TFilter => {
|
||||
const key = args.key as keyof ListState['item'];
|
||||
|
|
|
|||
|
|
@ -6,34 +6,9 @@ import { create } from 'zustand';
|
|||
import { devtools, persist, subscribeWithSelector } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
import { shallow } from 'zustand/shallow';
|
||||
import { QueueSong } from '/@/renderer/api/types';
|
||||
import { PlayerStatus, PlayerRepeat, PlayerShuffle, Play } from '/@/renderer/types';
|
||||
|
||||
export interface PlayerState {
|
||||
current: {
|
||||
index: number;
|
||||
nextIndex: number;
|
||||
player: 1 | 2;
|
||||
previousIndex: number;
|
||||
seek: boolean;
|
||||
shuffledIndex: number;
|
||||
song?: QueueSong;
|
||||
status: PlayerStatus;
|
||||
time: number;
|
||||
};
|
||||
fallback: boolean | null;
|
||||
muted: boolean;
|
||||
queue: {
|
||||
default: QueueSong[];
|
||||
previousNode?: QueueSong;
|
||||
shuffled: string[];
|
||||
sorted: QueueSong[];
|
||||
};
|
||||
repeat: PlayerRepeat;
|
||||
shuffle: PlayerShuffle;
|
||||
speed: number;
|
||||
volume: number;
|
||||
}
|
||||
import { QueueSong } from '/@/renderer/api/types';
|
||||
import { Play, PlayerRepeat, PlayerShuffle, PlayerStatus } from '/@/renderer/types';
|
||||
|
||||
export interface PlayerData {
|
||||
current: {
|
||||
|
|
@ -50,13 +25,6 @@ export interface PlayerData {
|
|||
queue: QueueData;
|
||||
}
|
||||
|
||||
export interface QueueData {
|
||||
current?: QueueSong;
|
||||
length: number;
|
||||
next?: QueueSong;
|
||||
previous?: QueueSong;
|
||||
}
|
||||
|
||||
export interface PlayerSlice extends PlayerState {
|
||||
actions: {
|
||||
addToQueue: (args: {
|
||||
|
|
@ -90,7 +58,7 @@ export interface PlayerSlice extends PlayerState {
|
|||
setFallback: (fallback: boolean | null) => boolean;
|
||||
setFavorite: (ids: string[], favorite: boolean) => string[];
|
||||
setMuted: (muted: boolean) => void;
|
||||
setRating: (ids: string[], rating: number | null) => string[];
|
||||
setRating: (ids: string[], rating: null | number) => string[];
|
||||
setRepeat: (type: PlayerRepeat) => PlayerData;
|
||||
setShuffle: (type: PlayerShuffle) => PlayerData;
|
||||
setShuffledIndex: (index: number) => PlayerData;
|
||||
|
|
@ -100,6 +68,39 @@ export interface PlayerSlice extends PlayerState {
|
|||
};
|
||||
}
|
||||
|
||||
export interface PlayerState {
|
||||
current: {
|
||||
index: number;
|
||||
nextIndex: number;
|
||||
player: 1 | 2;
|
||||
previousIndex: number;
|
||||
seek: boolean;
|
||||
shuffledIndex: number;
|
||||
song?: QueueSong;
|
||||
status: PlayerStatus;
|
||||
time: number;
|
||||
};
|
||||
fallback: boolean | null;
|
||||
muted: boolean;
|
||||
queue: {
|
||||
default: QueueSong[];
|
||||
previousNode?: QueueSong;
|
||||
shuffled: string[];
|
||||
sorted: QueueSong[];
|
||||
};
|
||||
repeat: PlayerRepeat;
|
||||
shuffle: PlayerShuffle;
|
||||
speed: number;
|
||||
volume: number;
|
||||
}
|
||||
|
||||
export interface QueueData {
|
||||
current?: QueueSong;
|
||||
length: number;
|
||||
next?: QueueSong;
|
||||
previous?: QueueSong;
|
||||
}
|
||||
|
||||
export const usePlayerStore = create<PlayerSlice>()(
|
||||
subscribeWithSelector(
|
||||
persist(
|
||||
|
|
|
|||
|
|
@ -1,48 +1,12 @@
|
|||
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<T> = {
|
||||
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<PlaylistListFilter>;
|
||||
}
|
||||
import { ListDisplayType, TableColumn, TablePagination } from '/@/renderer/types';
|
||||
|
||||
export interface PlaylistSlice extends PlaylistState {
|
||||
actions: {
|
||||
|
|
@ -57,6 +21,43 @@ export interface PlaylistSlice extends PlaylistState {
|
|||
};
|
||||
}
|
||||
|
||||
type DetailPaginationProps = TablePagination & {
|
||||
scrollOffset: number;
|
||||
};
|
||||
|
||||
type DetailProps = {
|
||||
display: ListDisplayType;
|
||||
table: DetailTableProps;
|
||||
};
|
||||
|
||||
type DetailTableProps = DataTableProps & {
|
||||
id: {
|
||||
[key: string]: DetailPaginationProps & { filter: SongListFilter };
|
||||
};
|
||||
};
|
||||
|
||||
type ListGridProps = {
|
||||
itemsPerRow?: number;
|
||||
scrollOffset?: number;
|
||||
};
|
||||
|
||||
type ListProps<T> = {
|
||||
display: ListDisplayType;
|
||||
filter: T;
|
||||
table: TableProps;
|
||||
};
|
||||
|
||||
interface PlaylistState {
|
||||
detail: DetailProps;
|
||||
grid: ListGridProps;
|
||||
list: ListProps<PlaylistListFilter>;
|
||||
}
|
||||
|
||||
type TableProps = DataTableProps & {
|
||||
pagination: TablePagination;
|
||||
scrollOffset: number;
|
||||
};
|
||||
|
||||
export const usePlaylistStore = create<PlaylistSlice>()(
|
||||
persist(
|
||||
devtools(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-disable prefer-destructuring */
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import type { ContextMenuItemType } from '/@/renderer/features/context-menu';
|
||||
|
||||
import { ColDef } from '@ag-grid-community/core';
|
||||
import isElectron from 'is-electron';
|
||||
import { generatePath } from 'react-router';
|
||||
|
|
@ -7,26 +7,26 @@ import { create } from 'zustand';
|
|||
import { devtools, persist } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
import { shallow } from 'zustand/shallow';
|
||||
|
||||
import i18n from '/@/i18n/i18n';
|
||||
import { LibraryItem, LyricSource } from '/@/renderer/api/types';
|
||||
import { AppRoute } from '/@/renderer/router/routes';
|
||||
import { usePlayerStore } from '/@/renderer/store/player.store';
|
||||
import { mergeOverridingColumns } from '/@/renderer/store/utils';
|
||||
import { AppTheme } from '/@/renderer/themes/types';
|
||||
import {
|
||||
TableColumn,
|
||||
CrossfadeStyle,
|
||||
FontType,
|
||||
Platform,
|
||||
Play,
|
||||
PlaybackStyle,
|
||||
PlaybackType,
|
||||
TableColumn,
|
||||
TableType,
|
||||
Platform,
|
||||
FontType,
|
||||
} from '/@/renderer/types';
|
||||
import { randomString } from '/@/renderer/utils';
|
||||
import i18n from '/@/i18n/i18n';
|
||||
import { usePlayerStore } from '/@/renderer/store/player.store';
|
||||
import { mergeOverridingColumns } from '/@/renderer/store/utils';
|
||||
import type { ContextMenuItemType } from '/@/renderer/features/context-menu';
|
||||
|
||||
const utils = isElectron() ? window.electron.utils : null;
|
||||
const utils = isElectron() ? window.api.utils : null;
|
||||
|
||||
export type SidebarItemType = {
|
||||
disabled: boolean;
|
||||
|
|
@ -93,11 +93,6 @@ export const sidebarItems: SidebarItemType[] = [
|
|||
},
|
||||
];
|
||||
|
||||
export type SortableItem<T> = {
|
||||
disabled: boolean;
|
||||
id: T;
|
||||
};
|
||||
|
||||
export enum HomeItem {
|
||||
MOST_PLAYED = 'mostPlayed',
|
||||
RANDOM = 'random',
|
||||
|
|
@ -105,6 +100,11 @@ export enum HomeItem {
|
|||
RECENTLY_PLAYED = 'recentlyPlayed',
|
||||
}
|
||||
|
||||
export type SortableItem<T> = {
|
||||
disabled: boolean;
|
||||
id: T;
|
||||
};
|
||||
|
||||
const homeItems = Object.values(HomeItem).map((item) => ({
|
||||
disabled: false,
|
||||
id: item,
|
||||
|
|
@ -113,10 +113,10 @@ const homeItems = Object.values(HomeItem).map((item) => ({
|
|||
/* eslint-disable typescript-sort-keys/string-enum */
|
||||
export enum ArtistItem {
|
||||
BIOGRAPHY = 'biography',
|
||||
TOP_SONGS = 'topSongs',
|
||||
RECENT_ALBUMS = 'recentAlbums',
|
||||
COMPILATIONS = 'compilations',
|
||||
RECENT_ALBUMS = 'recentAlbums',
|
||||
SIMILAR_ARTISTS = 'similarArtists',
|
||||
TOP_SONGS = 'topSongs',
|
||||
}
|
||||
/* eslint-enable typescript-sort-keys/string-enum */
|
||||
|
||||
|
|
@ -125,32 +125,6 @@ const artistItems = Object.values(ArtistItem).map((item) => ({
|
|||
id: item,
|
||||
}));
|
||||
|
||||
export type PersistedTableColumn = {
|
||||
column: TableColumn;
|
||||
extraProps?: Partial<ColDef>;
|
||||
width: number;
|
||||
};
|
||||
|
||||
export type DataTableProps = {
|
||||
autoFit: boolean;
|
||||
columns: PersistedTableColumn[];
|
||||
followCurrentSong?: boolean;
|
||||
rowHeight: number;
|
||||
};
|
||||
|
||||
export type SideQueueType = 'sideQueue' | 'sideDrawerQueue';
|
||||
|
||||
type MpvSettings = {
|
||||
audioExclusiveMode: 'yes' | 'no';
|
||||
audioFormat?: 's16' | 's32' | 'float';
|
||||
audioSampleRateHz?: number;
|
||||
gaplessAudio: 'yes' | 'no' | 'weak';
|
||||
replayGainClip: boolean;
|
||||
replayGainFallbackDB?: number;
|
||||
replayGainMode: 'no' | 'track' | 'album';
|
||||
replayGainPreampDB?: number;
|
||||
};
|
||||
|
||||
export enum BindingActions {
|
||||
BROWSER_BACK = 'browserBack',
|
||||
BROWSER_FORWARD = 'browserForward',
|
||||
|
|
@ -192,12 +166,35 @@ export enum GenreTarget {
|
|||
TRACK = 'track',
|
||||
}
|
||||
|
||||
export type TranscodingConfig = {
|
||||
bitrate?: number;
|
||||
enabled: boolean;
|
||||
format?: string;
|
||||
export type DataTableProps = {
|
||||
autoFit: boolean;
|
||||
columns: PersistedTableColumn[];
|
||||
followCurrentSong?: boolean;
|
||||
rowHeight: number;
|
||||
};
|
||||
|
||||
export type PersistedTableColumn = {
|
||||
column: TableColumn;
|
||||
extraProps?: Partial<ColDef>;
|
||||
width: number;
|
||||
};
|
||||
|
||||
export interface SettingsSlice extends SettingsState {
|
||||
actions: {
|
||||
reset: () => void;
|
||||
resetSampleRate: () => void;
|
||||
setArtistItems: (item: SortableItem<ArtistItem>[]) => void;
|
||||
setGenreBehavior: (target: GenreTarget) => void;
|
||||
setHomeItems: (item: SortableItem<HomeItem>[]) => void;
|
||||
setSettings: (data: Partial<SettingsState>) => void;
|
||||
setSidebarItems: (items: SidebarItemType[]) => void;
|
||||
setTable: (type: TableType, data: DataTableProps) => void;
|
||||
setTranscodingConfig: (config: TranscodingConfig) => void;
|
||||
toggleContextMenuItem: (item: ContextMenuItemType) => void;
|
||||
toggleSidebarCollapseShare: () => void;
|
||||
};
|
||||
}
|
||||
|
||||
export interface SettingsState {
|
||||
css: {
|
||||
content: string;
|
||||
|
|
@ -205,21 +202,21 @@ export interface SettingsState {
|
|||
};
|
||||
discord: {
|
||||
clientId: string;
|
||||
enableIdle: boolean;
|
||||
enabled: boolean;
|
||||
enableIdle: boolean;
|
||||
showAsListening: boolean;
|
||||
showServerImage: boolean;
|
||||
updateInterval: number;
|
||||
};
|
||||
font: {
|
||||
builtIn: string;
|
||||
custom: string | null;
|
||||
system: string | null;
|
||||
custom: null | string;
|
||||
system: null | string;
|
||||
type: FontType;
|
||||
};
|
||||
general: {
|
||||
accent: string;
|
||||
albumArtRes?: number | null;
|
||||
albumArtRes?: null | number;
|
||||
albumBackground: boolean;
|
||||
albumBackgroundBlur: number;
|
||||
artistItems: SortableItem<ArtistItem>[];
|
||||
|
|
@ -239,11 +236,11 @@ export interface SettingsState {
|
|||
playerbarOpenDrawer: boolean;
|
||||
resume: boolean;
|
||||
showQueueDrawerButton: boolean;
|
||||
sideQueueType: SideQueueType;
|
||||
sidebarCollapseShared: boolean;
|
||||
sidebarCollapsedNavigation: boolean;
|
||||
sidebarCollapseShared: boolean;
|
||||
sidebarItems: SidebarItemType[];
|
||||
sidebarPlaylistList: boolean;
|
||||
sideQueueType: SideQueueType;
|
||||
skipButtons: {
|
||||
enabled: boolean;
|
||||
skipBackwardSeconds: number;
|
||||
|
|
@ -264,7 +261,7 @@ export interface SettingsState {
|
|||
globalMediaHotkeys: boolean;
|
||||
};
|
||||
lyrics: {
|
||||
alignment: 'left' | 'center' | 'right';
|
||||
alignment: 'center' | 'left' | 'right';
|
||||
delayMs: number;
|
||||
fetch: boolean;
|
||||
follow: boolean;
|
||||
|
|
@ -276,11 +273,11 @@ export interface SettingsState {
|
|||
showProvider: boolean;
|
||||
sources: LyricSource[];
|
||||
translationApiKey: string;
|
||||
translationApiProvider: string | null;
|
||||
translationTargetLanguage: string | null;
|
||||
translationApiProvider: null | string;
|
||||
translationTargetLanguage: null | string;
|
||||
};
|
||||
playback: {
|
||||
audioDeviceId?: string | null;
|
||||
audioDeviceId?: null | string;
|
||||
crossfadeDuration: number;
|
||||
crossfadeStyle: CrossfadeStyle;
|
||||
mpvExtraParameters: string[];
|
||||
|
|
@ -302,7 +299,7 @@ export interface SettingsState {
|
|||
port: number;
|
||||
username: string;
|
||||
};
|
||||
tab: 'general' | 'playback' | 'window' | 'hotkeys' | string;
|
||||
tab: 'general' | 'hotkeys' | 'playback' | 'window' | string;
|
||||
tables: {
|
||||
albumDetail: DataTableProps;
|
||||
fullScreen: DataTableProps;
|
||||
|
|
@ -321,21 +318,24 @@ export interface SettingsState {
|
|||
};
|
||||
}
|
||||
|
||||
export interface SettingsSlice extends SettingsState {
|
||||
actions: {
|
||||
reset: () => void;
|
||||
resetSampleRate: () => void;
|
||||
setArtistItems: (item: SortableItem<ArtistItem>[]) => void;
|
||||
setGenreBehavior: (target: GenreTarget) => void;
|
||||
setHomeItems: (item: SortableItem<HomeItem>[]) => void;
|
||||
setSettings: (data: Partial<SettingsState>) => void;
|
||||
setSidebarItems: (items: SidebarItemType[]) => void;
|
||||
setTable: (type: TableType, data: DataTableProps) => void;
|
||||
setTranscodingConfig: (config: TranscodingConfig) => void;
|
||||
toggleContextMenuItem: (item: ContextMenuItemType) => void;
|
||||
toggleSidebarCollapseShare: () => void;
|
||||
};
|
||||
}
|
||||
export type SideQueueType = 'sideDrawerQueue' | 'sideQueue';
|
||||
|
||||
export type TranscodingConfig = {
|
||||
bitrate?: number;
|
||||
enabled: boolean;
|
||||
format?: string;
|
||||
};
|
||||
|
||||
type MpvSettings = {
|
||||
audioExclusiveMode: 'no' | 'yes';
|
||||
audioFormat?: 'float' | 's16' | 's32';
|
||||
audioSampleRateHz?: number;
|
||||
gaplessAudio: 'no' | 'weak' | 'yes';
|
||||
replayGainClip: boolean;
|
||||
replayGainFallbackDB?: number;
|
||||
replayGainMode: 'album' | 'no' | 'track';
|
||||
replayGainPreampDB?: number;
|
||||
};
|
||||
|
||||
// Determines the default/initial windowBarStyle value based on the current platform.
|
||||
const getPlatformDefaultWindowBarStyle = (): Platform => {
|
||||
|
|
@ -351,8 +351,8 @@ const initialState: SettingsState = {
|
|||
},
|
||||
discord: {
|
||||
clientId: '1165957668758900787',
|
||||
enableIdle: false,
|
||||
enabled: false,
|
||||
enableIdle: false,
|
||||
showAsListening: false,
|
||||
showServerImage: false,
|
||||
updateInterval: 15,
|
||||
|
|
@ -385,11 +385,11 @@ const initialState: SettingsState = {
|
|||
playerbarOpenDrawer: false,
|
||||
resume: false,
|
||||
showQueueDrawerButton: false,
|
||||
sideQueueType: 'sideQueue',
|
||||
sidebarCollapseShared: false,
|
||||
sidebarCollapsedNavigation: true,
|
||||
sidebarCollapseShared: false,
|
||||
sidebarItems,
|
||||
sidebarPlaylistList: true,
|
||||
sideQueueType: 'sideQueue',
|
||||
skipButtons: {
|
||||
enabled: false,
|
||||
skipBackwardSeconds: 5,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue