mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 07:15:47 +00:00
feat(lyrics): make lyrics fully disablable (independent YouLyPlus toggle) (#855)
* feat(lyrics): independent YouLyPlus toggle + all-sources-off state
Replace the binary lyricsMode ('standard' | 'lyricsplus') with an
independent youLyPlusEnabled flag so YouLyPlus and the standard sources
are no longer mutually exclusive — turning one off no longer forces the
other on. YouLyPlus (when on) is tried first with the enabled sources as
fallback; off uses only the enabled sources. When YouLyPlus is off and no
source is enabled, useLyrics fetches nothing (issue #810).
Fresh installs ship with every source off; the rehydrate migration only
restores the old on-by-default set for genuine upgrades, not new installs.
* feat(lyrics): YouLyPlus toggle UI + queue 'no sources' hint
Settings: single YouLyPlus toggle replacing the two mutually exclusive
mode switches; the source list is always visible with a context hint
(fallback vs primary). Queue lyric tab shows a hint when no source is
active. en + de strings; other locales fall back to en.
* docs(changelog): lyrics fully disablable (#855)
This commit is contained in:
committed by
GitHub
parent
cb4d331f99
commit
02b2df1589
+23
-8
@@ -71,11 +71,13 @@ export interface UseLyricsResult {
|
||||
}
|
||||
|
||||
export function useLyrics(currentTrack: Track | null): UseLyricsResult {
|
||||
const cached = currentTrack ? lyricsCache.get(currentTrack.id) : undefined;
|
||||
const { lyricsSources, lyricsMode } = useAuthStore(useShallow(s => ({
|
||||
const { lyricsSources, youLyPlusEnabled } = useAuthStore(useShallow(s => ({
|
||||
lyricsSources: s.lyricsSources,
|
||||
lyricsMode: s.lyricsMode,
|
||||
youLyPlusEnabled: s.youLyPlusEnabled,
|
||||
})));
|
||||
// Lyrics are fully off when YouLyPlus is off and no source is enabled.
|
||||
const lyricsActive = youLyPlusEnabled || lyricsSources.some(s => s.enabled);
|
||||
const cached = (currentTrack && lyricsActive) ? lyricsCache.get(currentTrack.id) : undefined;
|
||||
|
||||
const [loading, setLoading] = useState(!cached && !!currentTrack);
|
||||
const [syncedLines, setSyncedLines] = useState<LrcLine[] | null>(cached?.syncedLines ?? null);
|
||||
@@ -87,6 +89,19 @@ export function useLyrics(currentTrack: Track | null): UseLyricsResult {
|
||||
useEffect(() => {
|
||||
if (!currentTrack) return;
|
||||
|
||||
// Lyrics fully disabled (YouLyPlus off + every source off): fetch nothing,
|
||||
// show nothing — not even embedded/cache (issue #810). LyricsPane surfaces
|
||||
// the "no sources selected" hint.
|
||||
if (!lyricsActive) {
|
||||
setSyncedLines(null);
|
||||
setWordLines(null);
|
||||
setPlainLyrics(null);
|
||||
setSource(null);
|
||||
setNotFound(false);
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const hit = lyricsCache.get(currentTrack.id);
|
||||
if (hit) {
|
||||
setSyncedLines(hit.syncedLines);
|
||||
@@ -200,7 +215,7 @@ export function useLyrics(currentTrack: Track | null): UseLyricsResult {
|
||||
|
||||
/**
|
||||
* lyricsplus (YouLyPlus). Silent miss → caller falls back to the standard
|
||||
* pipeline. Only consumed when `lyricsMode === 'lyricsplus'`.
|
||||
* pipeline. Only consumed when `youLyPlusEnabled`.
|
||||
*/
|
||||
const fetchLyricsPlusFn = async (): Promise<boolean> => {
|
||||
try {
|
||||
@@ -258,7 +273,7 @@ export function useLyrics(currentTrack: Track | null): UseLyricsResult {
|
||||
// Skip for 'lyricsplus' mode since the persisted entry might be from
|
||||
// the standard pipeline (no word-level sync) and the user explicitly
|
||||
// wants a fresh lyricsplus attempt.
|
||||
if (lyricsMode !== 'lyricsplus') {
|
||||
if (!youLyPlusEnabled) {
|
||||
const serverId = useAuthStore.getState().activeServerId ?? '';
|
||||
const persisted = await getCachedLyrics(lyricsCacheKey(serverId, currentTrack.id));
|
||||
if (cancelled) return;
|
||||
@@ -270,8 +285,8 @@ export function useLyrics(currentTrack: Track | null): UseLyricsResult {
|
||||
}
|
||||
}
|
||||
|
||||
// YouLyPlus mode: try lyricsplus first, silent fallback to standard.
|
||||
if (lyricsMode === 'lyricsplus') {
|
||||
// YouLyPlus on: try lyricsplus first, silent fallback to enabled sources.
|
||||
if (youLyPlusEnabled) {
|
||||
if (cancelled) return;
|
||||
if (await fetchLyricsPlusFn()) return;
|
||||
}
|
||||
@@ -288,7 +303,7 @@ export function useLyrics(currentTrack: Track | null): UseLyricsResult {
|
||||
})();
|
||||
|
||||
return () => { cancelled = true; };
|
||||
}, [currentTrack?.id, lyricsSources, lyricsMode]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
}, [currentTrack?.id, lyricsSources, youLyPlusEnabled]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
return { syncedLines, wordLines, plainLyrics, source, loading, notFound };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user