diff --git a/src/datasource/youtube/YouTubeMusicDataSource.ts b/src/datasource/youtube/YouTubeMusicDataSource.ts index dcb32ab7..971f34fe 100644 --- a/src/datasource/youtube/YouTubeMusicDataSource.ts +++ b/src/datasource/youtube/YouTubeMusicDataSource.ts @@ -4692,6 +4692,12 @@ export class YouTubeMusicDataSource extends DataSource { private async fetchSyncedLyrics(track: Track): Promise { logInternalInfo("YouTubeMusicDataSource.getLyrics start", { trackId: track.id }); + // Queue rows carry no duration, so an auto-advanced track used to skip both LRCLIB sources (#153). + if (!track.durationSec && track.source === "youtube") { + const durationSec = (await this.getTrack(track.id).catch(() => null))?.durationSec; + if (durationSec) track = { ...track, durationSec }; + } + const runners: Record Promise> = { "lrclib-exact": () => this.fetchLrcLibExactLyrics(track), betterlyrics: () => this.fetchBetterLyrics(track), diff --git a/src/internal/lyricsSourcePreference.ts b/src/internal/lyricsSourcePreference.ts index 65168f6c..64bf6bd7 100644 --- a/src/internal/lyricsSourcePreference.ts +++ b/src/internal/lyricsSourcePreference.ts @@ -1,4 +1,5 @@ import { useSyncExternalStore } from "react"; +import { getAppSetting, setAppSetting } from "./appSettings"; /** * Which lyric source the listener wants tried first. @@ -38,6 +39,14 @@ export function setPreferredLyricsSourceId(id: string): void { // Quota or a locked profile: the choice still applies for this session. } window.dispatchEvent(new Event(CHANGE_EVENT)); + void setAppSetting(STORAGE_KEY, id); +} + +/** Webview storage alone lost this on every restart for some Windows users (#153). */ +export async function hydratePreferredLyricsSourceId(): Promise { + const stored = await getAppSetting(STORAGE_KEY); + // No durable copy yet: backfill it from local storage. + setPreferredLyricsSourceId(typeof stored === "string" ? stored : getPreferredLyricsSourceId()); } function subscribe(listener: () => void): () => void { diff --git a/src/main.tsx b/src/main.tsx index bd1665c1..aba26df9 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -37,6 +37,7 @@ import { DiscordRpcService } from "./player/DiscordRPC"; import { hydratePlaybackSettings } from "./player/playbackSettings"; import { hydratePlayHistory } from "./player/playHistory"; import { hydrateSessionRestoreSetting } from "./ui/settings/sessionRestore"; +import { hydratePreferredLyricsSourceId } from "./internal/lyricsSourcePreference"; import { hydrateToolbarItemSettings } from "./ui/settings/toolbarItems"; import { hydrateHomeSectionSettings } from "./ui/settings/homeSections"; import { applyRenderEffects, hydrateRenderEffects } from "./ui/settings/renderEffects"; @@ -86,6 +87,7 @@ void Promise.all([ hydrateHomeSectionSettings(), hydratePlaybackSettings(), hydratePlayHistory(), + hydratePreferredLyricsSourceId(), // Read synchronously from local storage at boot, so this only backfills a machine whose // local storage was cleared — it takes effect from the next launch. hydrateSessionRestoreSetting(),