mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 14:35:41 +00:00
refactor(auth): E.45 — extract seven settings factories (#610)
Seven small domain-eng factories peel ~53 trivial setters out of the authStore body: - `createCacheStorageActions` — disk caches (max cache MB, download folder, offline download dir, hot-cache enable/MB/debounce/dir). - `createDiscordSettingsActions` — rich presence, cover source, Bandsintown toggle, three template strings. - `createUiAppearanceActions` — visual chrome: tray, titlebar, sidebar toggles, fullscreen-lyrics rendering, changelog banner, seekbar style, queue collapse, kinetic scroll, mini-player preload. - `createLyricsSettingsActions` — lyrics fetch pipeline (server-first, netease enablement, source order, mode, static-only). - `createTrackPreviewActions` — preview enable + per-location + start ratio (clamped 0…0.9) + duration (clamped 5…120s). - `createDiscoveryActions` — mix min-rating filters (clamped 0…3), random-mix size (snapped to allowed bucket), lucky-mix visibility, random-nav mode, infinite-queue, preserve-play-next-order. - `createPlumbingSettingsActions` — logging mode, getNowPlaying toggle, preload mode + custom seconds, audiobook exclusion, genre blacklist. Pure code-move. authStore.ts: 428 → 384 LOC (−44).
This commit is contained in:
committed by
GitHub
parent
b8ddb09b78
commit
fe6acdaa4c
@@ -0,0 +1,26 @@
|
|||||||
|
import type { AuthState } from './authStoreTypes';
|
||||||
|
|
||||||
|
type SetState = (
|
||||||
|
partial: Partial<AuthState> | ((state: AuthState) => Partial<AuthState>),
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
export function createCacheStorageActions(set: SetState): Pick<
|
||||||
|
AuthState,
|
||||||
|
| 'setMaxCacheMb'
|
||||||
|
| 'setDownloadFolder'
|
||||||
|
| 'setOfflineDownloadDir'
|
||||||
|
| 'setHotCacheEnabled'
|
||||||
|
| 'setHotCacheMaxMb'
|
||||||
|
| 'setHotCacheDebounceSec'
|
||||||
|
| 'setHotCacheDownloadDir'
|
||||||
|
> {
|
||||||
|
return {
|
||||||
|
setMaxCacheMb: (v) => set({ maxCacheMb: v }),
|
||||||
|
setDownloadFolder: (v) => set({ downloadFolder: v }),
|
||||||
|
setOfflineDownloadDir: (v) => set({ offlineDownloadDir: v }),
|
||||||
|
setHotCacheEnabled: (v) => set({ hotCacheEnabled: v }),
|
||||||
|
setHotCacheMaxMb: (v) => set({ hotCacheMaxMb: v }),
|
||||||
|
setHotCacheDebounceSec: (v) => set({ hotCacheDebounceSec: v }),
|
||||||
|
setHotCacheDownloadDir: (v) => set({ hotCacheDownloadDir: v }),
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import type { AuthState } from './authStoreTypes';
|
||||||
|
|
||||||
|
type SetState = (
|
||||||
|
partial: Partial<AuthState> | ((state: AuthState) => Partial<AuthState>),
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
export function createDiscordSettingsActions(set: SetState): Pick<
|
||||||
|
AuthState,
|
||||||
|
| 'setDiscordRichPresence'
|
||||||
|
| 'setDiscordCoverSource'
|
||||||
|
| 'setEnableBandsintown'
|
||||||
|
| 'setDiscordTemplateDetails'
|
||||||
|
| 'setDiscordTemplateState'
|
||||||
|
| 'setDiscordTemplateLargeText'
|
||||||
|
> {
|
||||||
|
return {
|
||||||
|
setDiscordRichPresence: (v) => set({ discordRichPresence: v }),
|
||||||
|
setDiscordCoverSource: (v) => set({ discordCoverSource: v }),
|
||||||
|
setEnableBandsintown: (v) => set({ enableBandsintown: v }),
|
||||||
|
setDiscordTemplateDetails: (v) => set({ discordTemplateDetails: v }),
|
||||||
|
setDiscordTemplateState: (v) => set({ discordTemplateState: v }),
|
||||||
|
setDiscordTemplateLargeText: (v) => set({ discordTemplateLargeText: v }),
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import { clampMixFilterMinStars, clampRandomMixSize } from './authStoreHelpers';
|
||||||
|
import type { AuthState } from './authStoreTypes';
|
||||||
|
|
||||||
|
type SetState = (
|
||||||
|
partial: Partial<AuthState> | ((state: AuthState) => Partial<AuthState>),
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discovery + auto-queue settings: mix min-rating thresholds (each
|
||||||
|
* clamped to 0…3 stars), random-mix size (snapped to the allowed
|
||||||
|
* RANDOM_MIX_SIZE_OPTIONS bucket), lucky-mix sidebar visibility,
|
||||||
|
* random-nav style, infinite-queue + preserve-play-next-order
|
||||||
|
* toggles.
|
||||||
|
*/
|
||||||
|
export function createDiscoveryActions(set: SetState): Pick<
|
||||||
|
AuthState,
|
||||||
|
| 'setMixMinRatingFilterEnabled'
|
||||||
|
| 'setMixMinRatingSong'
|
||||||
|
| 'setMixMinRatingAlbum'
|
||||||
|
| 'setMixMinRatingArtist'
|
||||||
|
| 'setRandomMixSize'
|
||||||
|
| 'setShowLuckyMixMenu'
|
||||||
|
| 'setRandomNavMode'
|
||||||
|
| 'setInfiniteQueueEnabled'
|
||||||
|
| 'setPreservePlayNextOrder'
|
||||||
|
> {
|
||||||
|
return {
|
||||||
|
setMixMinRatingFilterEnabled: (v) => set({ mixMinRatingFilterEnabled: v }),
|
||||||
|
setMixMinRatingSong: (v) => set({ mixMinRatingSong: clampMixFilterMinStars(v) }),
|
||||||
|
setMixMinRatingAlbum: (v) => set({ mixMinRatingAlbum: clampMixFilterMinStars(v) }),
|
||||||
|
setMixMinRatingArtist: (v) => set({ mixMinRatingArtist: clampMixFilterMinStars(v) }),
|
||||||
|
setRandomMixSize: (v) => set({ randomMixSize: clampRandomMixSize(v) }),
|
||||||
|
setShowLuckyMixMenu: (v) => set({ showLuckyMixMenu: v }),
|
||||||
|
setRandomNavMode: (v) => set({ randomNavMode: v }),
|
||||||
|
setInfiniteQueueEnabled: (v) => set({ infiniteQueueEnabled: v }),
|
||||||
|
setPreservePlayNextOrder: (v) => set({ preservePlayNextOrder: v }),
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import type { AuthState } from './authStoreTypes';
|
||||||
|
|
||||||
|
type SetState = (
|
||||||
|
partial: Partial<AuthState> | ((state: AuthState) => Partial<AuthState>),
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lyrics fetch-pipeline settings: source order/enablement, mode
|
||||||
|
* (standard pipeline vs lyricsplus first), and the static-only
|
||||||
|
* rendering toggle. Visual lyrics chrome (rail vs apple,
|
||||||
|
* fullscreen show/hide) lives in `authUiAppearanceActions.ts`.
|
||||||
|
*/
|
||||||
|
export function createLyricsSettingsActions(set: SetState): Pick<
|
||||||
|
AuthState,
|
||||||
|
| 'setLyricsServerFirst'
|
||||||
|
| 'setEnableNeteaselyrics'
|
||||||
|
| 'setLyricsSources'
|
||||||
|
| 'setLyricsMode'
|
||||||
|
| 'setLyricsStaticOnly'
|
||||||
|
> {
|
||||||
|
return {
|
||||||
|
setLyricsServerFirst: (v) => set({ lyricsServerFirst: v }),
|
||||||
|
setEnableNeteaselyrics: (v) => set({ enableNeteaselyrics: v }),
|
||||||
|
setLyricsSources: (sources) => set({ lyricsSources: sources }),
|
||||||
|
setLyricsMode: (v) => set({ lyricsMode: v }),
|
||||||
|
setLyricsStaticOnly: (v) => set({ lyricsStaticOnly: v }),
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import type { AuthState } from './authStoreTypes';
|
||||||
|
|
||||||
|
type SetState = (
|
||||||
|
partial: Partial<AuthState> | ((state: AuthState) => Partial<AuthState>),
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persistent plumbing settings that don't fit a more specific domain:
|
||||||
|
* runtime logging level, Navidrome `getNowPlaying` toggle, preload
|
||||||
|
* mode + custom seconds, audiobook exclusion, genre blacklist.
|
||||||
|
*/
|
||||||
|
export function createPlumbingSettingsActions(set: SetState): Pick<
|
||||||
|
AuthState,
|
||||||
|
| 'setLoggingMode'
|
||||||
|
| 'setNowPlayingEnabled'
|
||||||
|
| 'setPreloadMode'
|
||||||
|
| 'setPreloadCustomSeconds'
|
||||||
|
| 'setExcludeAudiobooks'
|
||||||
|
| 'setCustomGenreBlacklist'
|
||||||
|
> {
|
||||||
|
return {
|
||||||
|
setLoggingMode: (v) => set({ loggingMode: v }),
|
||||||
|
setNowPlayingEnabled: (v) => set({ nowPlayingEnabled: v }),
|
||||||
|
setPreloadMode: (v) => set({ preloadMode: v }),
|
||||||
|
setPreloadCustomSeconds: (v) => set({ preloadCustomSeconds: v }),
|
||||||
|
setExcludeAudiobooks: (v) => set({ excludeAudiobooks: v }),
|
||||||
|
setCustomGenreBlacklist: (v) => set({ customGenreBlacklist: v }),
|
||||||
|
};
|
||||||
|
}
|
||||||
+14
-58
@@ -10,7 +10,14 @@ import {
|
|||||||
} from '../utils/loudnessPreAnalysisSlider';
|
} from '../utils/loudnessPreAnalysisSlider';
|
||||||
import { createAudioSettingsActions } from './authAudioSettingsActions';
|
import { createAudioSettingsActions } from './authAudioSettingsActions';
|
||||||
import { createAuthLastfmActions } from './authLastfmActions';
|
import { createAuthLastfmActions } from './authLastfmActions';
|
||||||
|
import { createCacheStorageActions } from './authCacheStorageActions';
|
||||||
|
import { createDiscordSettingsActions } from './authDiscordSettingsActions';
|
||||||
|
import { createDiscoveryActions } from './authDiscoveryActions';
|
||||||
|
import { createLyricsSettingsActions } from './authLyricsSettingsActions';
|
||||||
|
import { createPlumbingSettingsActions } from './authPlumbingActions';
|
||||||
import { createServerProfileActions } from './authServerProfileActions';
|
import { createServerProfileActions } from './authServerProfileActions';
|
||||||
|
import { createTrackPreviewActions } from './authTrackPreviewActions';
|
||||||
|
import { createUiAppearanceActions } from './authUiAppearanceActions';
|
||||||
import {
|
import {
|
||||||
DEFAULT_LOUDNESS_PRE_ANALYSIS_ATTENUATION_DB,
|
DEFAULT_LOUDNESS_PRE_ANALYSIS_ATTENUATION_DB,
|
||||||
DEFAULT_LYRICS_SOURCES,
|
DEFAULT_LYRICS_SOURCES,
|
||||||
@@ -129,56 +136,13 @@ export const useAuthStore = create<AuthState>()(
|
|||||||
...createServerProfileActions(set),
|
...createServerProfileActions(set),
|
||||||
...createAuthLastfmActions(set),
|
...createAuthLastfmActions(set),
|
||||||
...createAudioSettingsActions(set),
|
...createAudioSettingsActions(set),
|
||||||
|
...createCacheStorageActions(set),
|
||||||
setMaxCacheMb: (v) => set({ maxCacheMb: v }),
|
...createDiscordSettingsActions(set),
|
||||||
setDownloadFolder: (v) => set({ downloadFolder: v }),
|
...createUiAppearanceActions(set),
|
||||||
setOfflineDownloadDir: (v) => set({ offlineDownloadDir: v }),
|
...createLyricsSettingsActions(set),
|
||||||
setExcludeAudiobooks: (v) => set({ excludeAudiobooks: v }),
|
...createTrackPreviewActions(set),
|
||||||
setCustomGenreBlacklist: (v) => set({ customGenreBlacklist: v }),
|
...createDiscoveryActions(set),
|
||||||
setTrackPreviewsEnabled: (v) => set({ trackPreviewsEnabled: !!v }),
|
...createPlumbingSettingsActions(set),
|
||||||
setTrackPreviewLocation: (location, enabled) => set(state => ({
|
|
||||||
trackPreviewLocations: { ...state.trackPreviewLocations, [location]: !!enabled },
|
|
||||||
})),
|
|
||||||
setTrackPreviewStartRatio: (v) => set({ trackPreviewStartRatio: Math.max(0, Math.min(0.9, v)) }),
|
|
||||||
setTrackPreviewDurationSec: (v) => set({ trackPreviewDurationSec: Math.max(5, Math.min(120, Math.round(v))) }),
|
|
||||||
setPreloadMode: (v: 'off' | 'balanced' | 'early' | 'custom') => set({ preloadMode: v }),
|
|
||||||
setPreloadCustomSeconds: (v: number) => set({ preloadCustomSeconds: v }),
|
|
||||||
setInfiniteQueueEnabled: (v) => set({ infiniteQueueEnabled: v }),
|
|
||||||
setPreservePlayNextOrder: (v) => set({ preservePlayNextOrder: v }),
|
|
||||||
setShowArtistImages: (v) => set({ showArtistImages: v }),
|
|
||||||
setShowTrayIcon: (v) => set({ showTrayIcon: v }),
|
|
||||||
setMinimizeToTray: (v) => set({ minimizeToTray: v }),
|
|
||||||
setShowOrbitTrigger: (v) => set({ showOrbitTrigger: v }),
|
|
||||||
setDiscordRichPresence: (v) => set({ discordRichPresence: v }),
|
|
||||||
setDiscordCoverSource: (v) => set({ discordCoverSource: v }),
|
|
||||||
setEnableBandsintown: (v) => set({ enableBandsintown: v }),
|
|
||||||
setDiscordTemplateDetails: (v) => set({ discordTemplateDetails: v }),
|
|
||||||
setDiscordTemplateState: (v) => set({ discordTemplateState: v }),
|
|
||||||
setDiscordTemplateLargeText: (v) => set({ discordTemplateLargeText: v }),
|
|
||||||
setUseCustomTitlebar: (v) => set({ useCustomTitlebar: v }),
|
|
||||||
setPreloadMiniPlayer: (v) => set({ preloadMiniPlayer: v }),
|
|
||||||
setLinuxWebkitKineticScroll: (v) => set({ linuxWebkitKineticScroll: v }),
|
|
||||||
setLoggingMode: (v) => set({ loggingMode: v }),
|
|
||||||
setNowPlayingEnabled: (v) => set({ nowPlayingEnabled: v }),
|
|
||||||
setLyricsServerFirst: (v: boolean) => set({ lyricsServerFirst: v }),
|
|
||||||
setEnableNeteaselyrics: (v: boolean) => set({ enableNeteaselyrics: v }),
|
|
||||||
setLyricsSources: (sources) => set({ lyricsSources: sources }),
|
|
||||||
setLyricsMode: (v) => set({ lyricsMode: v }),
|
|
||||||
setLyricsStaticOnly: (v) => set({ lyricsStaticOnly: v }),
|
|
||||||
setShowFullscreenLyrics: (v: boolean) => set({ showFullscreenLyrics: v }),
|
|
||||||
setFsLyricsStyle: (v) => set({ fsLyricsStyle: v }),
|
|
||||||
setSidebarLyricsStyle: (v) => set({ sidebarLyricsStyle: v }),
|
|
||||||
setShowFsArtistPortrait: (v: boolean) => set({ showFsArtistPortrait: v }),
|
|
||||||
setFsPortraitDim: (v: number) => set({ fsPortraitDim: v }),
|
|
||||||
setShowChangelogOnUpdate: (v) => set({ showChangelogOnUpdate: v }),
|
|
||||||
setLastSeenChangelogVersion: (v) => set({ lastSeenChangelogVersion: v }),
|
|
||||||
|
|
||||||
setSeekbarStyle: (v) => set({ seekbarStyle: v }),
|
|
||||||
setQueueNowPlayingCollapsed: (v: boolean) => set({ queueNowPlayingCollapsed: v }),
|
|
||||||
setHotCacheEnabled: (v) => set({ hotCacheEnabled: v }),
|
|
||||||
setHotCacheMaxMb: (v) => set({ hotCacheMaxMb: v }),
|
|
||||||
setHotCacheDebounceSec: (v) => set({ hotCacheDebounceSec: v }),
|
|
||||||
setHotCacheDownloadDir: (v) => set({ hotCacheDownloadDir: v }),
|
|
||||||
|
|
||||||
setSkipStarOnManualSkipsEnabled: (v) =>
|
setSkipStarOnManualSkipsEnabled: (v) =>
|
||||||
set({
|
set({
|
||||||
@@ -213,14 +177,6 @@ export const useAuthStore = create<AuthState>()(
|
|||||||
set({ skipStarManualSkipCountsByKey: rest });
|
set({ skipStarManualSkipCountsByKey: rest });
|
||||||
},
|
},
|
||||||
|
|
||||||
setMixMinRatingFilterEnabled: (v) => set({ mixMinRatingFilterEnabled: v }),
|
|
||||||
setMixMinRatingSong: (v) => set({ mixMinRatingSong: clampMixFilterMinStars(v) }),
|
|
||||||
setMixMinRatingAlbum: (v) => set({ mixMinRatingAlbum: clampMixFilterMinStars(v) }),
|
|
||||||
setMixMinRatingArtist: (v) => set({ mixMinRatingArtist: clampMixFilterMinStars(v) }),
|
|
||||||
setRandomMixSize: (v) => set({ randomMixSize: clampRandomMixSize(v) }),
|
|
||||||
setShowLuckyMixMenu: (v) => set({ showLuckyMixMenu: v }),
|
|
||||||
setRandomNavMode: (v) => set({ randomNavMode: v }),
|
|
||||||
|
|
||||||
setMusicFolders: (folders) => {
|
setMusicFolders: (folders) => {
|
||||||
const sid = get().activeServerId;
|
const sid = get().activeServerId;
|
||||||
set(s => {
|
set(s => {
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import type { AuthState } from './authStoreTypes';
|
||||||
|
|
||||||
|
type SetState = (
|
||||||
|
partial: Partial<AuthState> | ((state: AuthState) => Partial<AuthState>),
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Track-preview settings. `setTrackPreviewStartRatio` clamps to
|
||||||
|
* 0…0.9 (preview window can't start past 90% of the track) and
|
||||||
|
* `setTrackPreviewDurationSec` clamps to 5…120 seconds.
|
||||||
|
*/
|
||||||
|
export function createTrackPreviewActions(set: SetState): Pick<
|
||||||
|
AuthState,
|
||||||
|
| 'setTrackPreviewsEnabled'
|
||||||
|
| 'setTrackPreviewLocation'
|
||||||
|
| 'setTrackPreviewStartRatio'
|
||||||
|
| 'setTrackPreviewDurationSec'
|
||||||
|
> {
|
||||||
|
return {
|
||||||
|
setTrackPreviewsEnabled: (v) => set({ trackPreviewsEnabled: !!v }),
|
||||||
|
setTrackPreviewLocation: (location, enabled) => set(state => ({
|
||||||
|
trackPreviewLocations: { ...state.trackPreviewLocations, [location]: !!enabled },
|
||||||
|
})),
|
||||||
|
setTrackPreviewStartRatio: (v) => set({ trackPreviewStartRatio: Math.max(0, Math.min(0.9, v)) }),
|
||||||
|
setTrackPreviewDurationSec: (v) => set({ trackPreviewDurationSec: Math.max(5, Math.min(120, Math.round(v))) }),
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import type { AuthState } from './authStoreTypes';
|
||||||
|
|
||||||
|
type SetState = (
|
||||||
|
partial: Partial<AuthState> | ((state: AuthState) => Partial<AuthState>),
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visual / chrome settings. Pure pass-through setters: tray, titlebar,
|
||||||
|
* sidebar toggles, fullscreen lyrics rendering options, changelog
|
||||||
|
* banner. No side effects.
|
||||||
|
*/
|
||||||
|
export function createUiAppearanceActions(set: SetState): Pick<
|
||||||
|
AuthState,
|
||||||
|
| 'setShowArtistImages'
|
||||||
|
| 'setShowTrayIcon'
|
||||||
|
| 'setMinimizeToTray'
|
||||||
|
| 'setShowOrbitTrigger'
|
||||||
|
| 'setUseCustomTitlebar'
|
||||||
|
| 'setPreloadMiniPlayer'
|
||||||
|
| 'setLinuxWebkitKineticScroll'
|
||||||
|
| 'setSeekbarStyle'
|
||||||
|
| 'setQueueNowPlayingCollapsed'
|
||||||
|
| 'setShowFullscreenLyrics'
|
||||||
|
| 'setFsLyricsStyle'
|
||||||
|
| 'setSidebarLyricsStyle'
|
||||||
|
| 'setShowFsArtistPortrait'
|
||||||
|
| 'setFsPortraitDim'
|
||||||
|
| 'setShowChangelogOnUpdate'
|
||||||
|
| 'setLastSeenChangelogVersion'
|
||||||
|
> {
|
||||||
|
return {
|
||||||
|
setShowArtistImages: (v) => set({ showArtistImages: v }),
|
||||||
|
setShowTrayIcon: (v) => set({ showTrayIcon: v }),
|
||||||
|
setMinimizeToTray: (v) => set({ minimizeToTray: v }),
|
||||||
|
setShowOrbitTrigger: (v) => set({ showOrbitTrigger: v }),
|
||||||
|
setUseCustomTitlebar: (v) => set({ useCustomTitlebar: v }),
|
||||||
|
setPreloadMiniPlayer: (v) => set({ preloadMiniPlayer: v }),
|
||||||
|
setLinuxWebkitKineticScroll: (v) => set({ linuxWebkitKineticScroll: v }),
|
||||||
|
setSeekbarStyle: (v) => set({ seekbarStyle: v }),
|
||||||
|
setQueueNowPlayingCollapsed: (v) => set({ queueNowPlayingCollapsed: v }),
|
||||||
|
setShowFullscreenLyrics: (v) => set({ showFullscreenLyrics: v }),
|
||||||
|
setFsLyricsStyle: (v) => set({ fsLyricsStyle: v }),
|
||||||
|
setSidebarLyricsStyle: (v) => set({ sidebarLyricsStyle: v }),
|
||||||
|
setShowFsArtistPortrait: (v) => set({ showFsArtistPortrait: v }),
|
||||||
|
setFsPortraitDim: (v) => set({ fsPortraitDim: v }),
|
||||||
|
setShowChangelogOnUpdate: (v) => set({ showChangelogOnUpdate: v }),
|
||||||
|
setLastSeenChangelogVersion: (v) => set({ lastSeenChangelogVersion: v }),
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user