mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-21 14:05:41 +00:00
70c2fdfbf9
* feat(linux): session GDK defaults, nvidia-quirk, optional x11-legacy wrap Ship PSYSONIC_ALLOW_NATIVE_GDK from Nix/AUR instead of pinning WEBKIT_DISABLE_* and GDK x11. Add flake psysonic-x11-legacy for the old wrap; alias gdk-session to psysonic. Startup uses webkit2gtk-nvidia-quirk and Wayland-aware compositing; refresh Help (a45) and nixos-install docs. * fix(linux): session GDK and nvidia-quirk only; drop wrapper env heuristics Remove PSYSONIC_ALLOW_NATIVE_GDK and devShell GDK/WEBKIT exports; stop synthesizing GDK/WebKit vars in main.rs. Update Nix/AUR wrappers, install docs, CHANGELOG, and help FAQ with practical user-facing workarounds. * fix(linux): X11-pinned GDK uses DMABUF quirk path, not Wayland explicit-sync When GDK_BACKEND is forced to x11 on a wayland user session, webkit2gtk-nvidia-quirk would still apply __NV_DISABLE_EXPLICIT_SYNC and gray out the webview. Map that case to WEBKIT_DISABLE_DMABUF_RENDERER like native X11. * fix(ui): stabilize WebKitGTK/Wayland hover paint for nav and media cards Sidebar nav links avoid transition:all and promote icons with translateZ(0). Artist rows and album/artist/song cards use compositing hints; card shadows and borders no longer interpolate so cover zoom can stay smooth without jitter. * fix(ui): isolate artist/album card text and cover paint on WebKitGTK Promote cover blocks with contain/paint and text stacks with translateZ(0); use artist-card-info on the artists grid for the same layout as other cards. * feat(artists): in-page overlay scroll and locked main viewport Move list/grid into an inner OverlayScrollArea, stop sticky toolbar from owning the route scroll, align the rail with the main panel edge, and skip the main-route overlay thumb when the viewport cannot scroll vertically. * feat(browse): extend in-page overlay scroll to more library routes Reuse the locked main viewport pattern from Artists for Albums, Composers, Lossless albums, and New releases; wire VirtualCardGrid and scroll chrome to the matching in-page viewport ids. * fix(linux): improve Wayland GPU compositing text clarity in WebKitGTK Use on-demand hardware acceleration on main and mini webviews when the session is Wayland and compositing stays on; gate subpixel body AA on the same conditions via new Tauri probes. Document PSYSONIC_SKIP_WAYLAND_FONT_TUNING for opt-out and changelog. * fix(rust): satisfy clippy needless_return in Linux webkit helpers * fix(linux): tune Wayland text rendering with HW policy env and CSS Allow PSYSONIC_WEBKIT_WAYLAND_HW_POLICY to select WebKit hardware acceleration policy (never/always vs default on-demand). Extend Wayland font CSS to #root with geometricPrecision and text-size-adjust on html. * feat(linux): Wayland text presets in settings, safe WebKit apply, CPU default Persist profile to app config; apply WebKit policy at startup/mini only to avoid WebKitGTK hangs on live toggles. UI + CSS preview stays live; default preset is sharp (CPU-friendly). * fix(linux): map Wayland sharp preset to OnDemand WebKit policy HardwareAccelerationPolicy::Never at startup broke main-viewport wheel scrolling on WebKitGTK+Wayland; sharp vs balanced remains a CSS AA path. Use PSYSONIC_WEBKIT_WAYLAND_HW_POLICY for a true Never policy. * fix(rust): gate Linux-only Wayland WebKit helpers for Windows builds Re-export startup helpers only under cfg(linux) and drop non-Linux stubs so Windows compiles without unused-import and dead-code warnings. * chore(release): CHANGELOG + credits for Linux session/WebKit work (PR #731) Consolidate scattered incremental changelog notes into two [1.47.0] entries with PR link; remove duplicate Linux blocks from [1.46.0] Fixed. Append settings credit line for cucadmuh.
165 lines
5.8 KiB
TypeScript
165 lines
5.8 KiB
TypeScript
import { create } from 'zustand';
|
|
import { persist, createJSONStorage } from 'zustand/middleware';
|
|
import { createAudioSettingsActions } from './authAudioSettingsActions';
|
|
import { createAuthLastfmActions } from './authLastfmActions';
|
|
import { createCacheStorageActions } from './authCacheStorageActions';
|
|
import { createDiscordSettingsActions } from './authDiscordSettingsActions';
|
|
import { createDiscoveryActions } from './authDiscoveryActions';
|
|
import { createLyricsSettingsActions } from './authLyricsSettingsActions';
|
|
import { createMusicLibraryActions } from './authMusicLibraryActions';
|
|
import { createPerServerCapabilityActions } from './authPerServerCapabilityActions';
|
|
import { createPlumbingSettingsActions } from './authPlumbingActions';
|
|
import { createServerProfileActions } from './authServerProfileActions';
|
|
import { createSkipStarActions } from './authSkipStarActions';
|
|
import { createTrackPreviewActions } from './authTrackPreviewActions';
|
|
import { createUiAppearanceActions } from './authUiAppearanceActions';
|
|
import {
|
|
DEFAULT_LOUDNESS_PRE_ANALYSIS_ATTENUATION_DB,
|
|
DEFAULT_LYRICS_SOURCES,
|
|
DEFAULT_TRACK_PREVIEW_LOCATIONS,
|
|
DEFAULT_LIBRARY_GRID_MAX_COLUMNS,
|
|
} from './authStoreDefaults';
|
|
import { computeAuthStoreRehydration } from './authStoreRehydrate';
|
|
import type { AuthState } from './authStoreTypes';
|
|
|
|
|
|
|
|
export const useAuthStore = create<AuthState>()(
|
|
persist(
|
|
(set, get) => ({
|
|
servers: [],
|
|
activeServerId: null,
|
|
lastfmApiKey: '',
|
|
lastfmApiSecret: '',
|
|
lastfmSessionKey: '',
|
|
lastfmUsername: '',
|
|
scrobblingEnabled: true,
|
|
maxCacheMb: 500,
|
|
downloadFolder: '',
|
|
offlineDownloadDir: '',
|
|
excludeAudiobooks: false,
|
|
customGenreBlacklist: [],
|
|
replayGainEnabled: false,
|
|
normalizationEngine: 'off',
|
|
loudnessTargetLufs: -12,
|
|
loudnessPreAnalysisAttenuationDb: DEFAULT_LOUDNESS_PRE_ANALYSIS_ATTENUATION_DB,
|
|
loudnessPreIsRefV1: true,
|
|
replayGainMode: 'auto',
|
|
replayGainPreGainDb: 0,
|
|
replayGainFallbackDb: 0,
|
|
crossfadeEnabled: false,
|
|
crossfadeSecs: 3,
|
|
gaplessEnabled: false,
|
|
trackPreviewsEnabled: true,
|
|
trackPreviewLocations: { ...DEFAULT_TRACK_PREVIEW_LOCATIONS },
|
|
trackPreviewStartRatio: 0.33,
|
|
trackPreviewDurationSec: 30,
|
|
preloadMode: 'balanced',
|
|
preloadCustomSeconds: 30,
|
|
infiniteQueueEnabled: false,
|
|
preservePlayNextOrder: false,
|
|
showArtistImages: false,
|
|
libraryGridMaxColumns: DEFAULT_LIBRARY_GRID_MAX_COLUMNS,
|
|
showTrayIcon: true,
|
|
minimizeToTray: false,
|
|
clockFormat: 'auto',
|
|
showOrbitTrigger: true,
|
|
discordRichPresence: false,
|
|
discordCoverSource: 'server',
|
|
enableBandsintown: false,
|
|
discordTemplateDetails: '{artist}',
|
|
discordTemplateState: '{title}',
|
|
discordTemplateLargeText: '{album}',
|
|
useCustomTitlebar: false,
|
|
preloadMiniPlayer: false,
|
|
linuxWebkitKineticScroll: true,
|
|
linuxWaylandTextRenderProfile: 'sharp',
|
|
loggingMode: 'normal',
|
|
nowPlayingEnabled: false,
|
|
lyricsServerFirst: true,
|
|
enableNeteaselyrics: false,
|
|
lyricsSources: DEFAULT_LYRICS_SOURCES,
|
|
lyricsMode: 'standard',
|
|
lyricsStaticOnly: false,
|
|
showFullscreenLyrics: true,
|
|
fsLyricsStyle: 'rail',
|
|
sidebarLyricsStyle: 'classic',
|
|
showFsArtistPortrait: true,
|
|
fsPortraitDim: 28,
|
|
showChangelogOnUpdate: true,
|
|
lastSeenChangelogVersion: '',
|
|
advancedSettingsEnabled: false,
|
|
seekbarStyle: 'truewave',
|
|
queueNowPlayingCollapsed: false,
|
|
queueDurationDisplayMode: 'total',
|
|
enableHiRes: false,
|
|
audioOutputDevice: null,
|
|
hotCacheEnabled: false,
|
|
hotCacheMaxMb: 256,
|
|
hotCacheDebounceSec: 30,
|
|
hotCacheDownloadDir: '',
|
|
skipStarOnManualSkipsEnabled: false,
|
|
skipStarManualSkipThreshold: 3,
|
|
skipStarManualSkipCountsByKey: {},
|
|
mixMinRatingFilterEnabled: false,
|
|
mixMinRatingSong: 0,
|
|
mixMinRatingAlbum: 0,
|
|
mixMinRatingArtist: 0,
|
|
randomMixSize: 50,
|
|
showLuckyMixMenu: true,
|
|
randomNavMode: 'hub',
|
|
musicFolders: [],
|
|
musicLibraryFilterByServer: {},
|
|
musicLibraryFilterVersion: 0,
|
|
entityRatingSupportByServer: {},
|
|
audiomuseNavidromeByServer: {},
|
|
subsonicServerIdentityByServer: {},
|
|
audiomuseNavidromeIssueByServer: {},
|
|
instantMixProbeByServer: {},
|
|
isLoggedIn: false,
|
|
isConnecting: false,
|
|
connectionError: null,
|
|
lastfmSessionError: false,
|
|
|
|
...createServerProfileActions(set),
|
|
...createAuthLastfmActions(set),
|
|
...createAudioSettingsActions(set),
|
|
...createCacheStorageActions(set),
|
|
...createDiscordSettingsActions(set),
|
|
...createUiAppearanceActions(set),
|
|
...createLyricsSettingsActions(set),
|
|
...createTrackPreviewActions(set),
|
|
...createDiscoveryActions(set),
|
|
...createPlumbingSettingsActions(set),
|
|
...createSkipStarActions(set, get),
|
|
...createMusicLibraryActions(set, get),
|
|
...createPerServerCapabilityActions(set),
|
|
|
|
getBaseUrl: () => {
|
|
const s = get();
|
|
const server = s.servers.find(srv => srv.id === s.activeServerId);
|
|
if (!server?.url) return '';
|
|
const base = server.url.startsWith('http') ? server.url : `http://${server.url}`;
|
|
return base.replace(/\/$/, '');
|
|
},
|
|
|
|
getActiveServer: () => {
|
|
const s = get();
|
|
return s.servers.find(srv => srv.id === s.activeServerId);
|
|
},
|
|
}),
|
|
{
|
|
name: 'psysonic-auth',
|
|
storage: createJSONStorage(() => localStorage),
|
|
partialize: state => {
|
|
const { musicFolders: _mf, musicLibraryFilterVersion: _fv, ...rest } = state;
|
|
return rest;
|
|
},
|
|
onRehydrateStorage: () => (state, error) => {
|
|
if (error || !state) return;
|
|
useAuthStore.setState(computeAuthStoreRehydration(state));
|
|
},
|
|
}
|
|
)
|
|
);
|