feat: v1.34.1 — fullscreen lyrics overlay, FsArt crossfade, lyrics toggle, contributor updates

- FullscreenPlayer: synced lyrics overlay (5-line rail, mask fade, click-to-seek)
- FullscreenPlayer: FsArt crossfade component with onLoad pattern, 300px art, next-track pre-fetch
- FullscreenPlayer: MicVocal lyrics toggle button next to heart (persisted in authStore)
- FullscreenPlayer: idle system — only close button auto-hides, cluster+seekbar always visible
- LyricsPane: refactored to use shared useLyrics hook (no double-fetch with FS overlay)
- authStore: showFullscreenLyrics field (default true)
- i18n: fsLyricsToggle key added to all 7 locales; ru2.ts removed (merged into ru.ts)
- Settings: Contributors updated (nisrael, cucadmuh, kilyabin); logout moved to Server tab as btn-danger
- theme.css: btn-danger style added

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Psychotoxical
2026-04-06 23:00:33 +02:00
parent 390e6e788d
commit d73f348339
17 changed files with 687 additions and 942 deletions
+10
View File
@@ -191,6 +191,16 @@ export async function invalidateCacheKey(cacheKey: string): Promise<void> {
}
}
/**
* Invalidates all cached sizes for a given cover art entity (artist, radio, playlist, album).
* Call this after uploading or deleting a cover image so the UI re-fetches from the server.
*/
export async function invalidateCoverArt(entityId: string): Promise<void> {
const serverId = useAuthStore.getState().getActiveServer()?.id ?? '_';
const sizes = [40, 64, 128, 200, 256, 300, 500, 2000];
await Promise.all(sizes.map(size => invalidateCacheKey(`${serverId}:cover:${entityId}:${size}`)));
}
/** Clears all entries from IndexedDB and revokes all in-memory object URLs. */
export async function clearImageCache(): Promise<void> {
for (const url of objectUrlCache.values()) {