restructure files onto electron-vite boilerplate

This commit is contained in:
jeffvli 2025-05-18 14:03:18 -07:00
parent 91ce2cd8a1
commit 1cf587bc8f
457 changed files with 9927 additions and 11705 deletions

View file

@ -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) => ({

View file

@ -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(

View file

@ -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) => ({

View file

@ -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(

View file

@ -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(

View file

@ -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(

View file

@ -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(

View file

@ -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';

View file

@ -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'];

View file

@ -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(

View file

@ -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(

View file

@ -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,