mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-10 04:30:25 +02:00
fix lyrics fetch and clear (#1342)
- split server and remote lyrics into separate queries - lyrics cache now always contain server lyrics, override will use separate remote query - clear button is reverted to only clear the override query, and back to server
This commit is contained in:
@@ -383,6 +383,14 @@ export const queryKeys: Record<
|
|||||||
lyricsByRemoteId: (searchQuery: { remoteSongId: string; remoteSource: LyricSource }) => {
|
lyricsByRemoteId: (searchQuery: { remoteSongId: string; remoteSource: LyricSource }) => {
|
||||||
return ['song', 'lyrics', 'remote', searchQuery] as const;
|
return ['song', 'lyrics', 'remote', searchQuery] as const;
|
||||||
},
|
},
|
||||||
|
remoteLyrics: (serverId: string, query?: LyricsQuery) => {
|
||||||
|
if (query) return [serverId, 'song', 'lyrics', 'remote', query] as const;
|
||||||
|
return [serverId, 'song', 'lyrics', 'remote'] as const;
|
||||||
|
},
|
||||||
|
serverLyrics: (serverId: string, query?: LyricsQuery) => {
|
||||||
|
if (query) return [serverId, 'song', 'lyrics', 'server', query] as const;
|
||||||
|
return [serverId, 'song', 'lyrics', 'server'] as const;
|
||||||
|
},
|
||||||
lyricsSearch: (query?: LyricSearchQuery) => {
|
lyricsSearch: (query?: LyricSearchQuery) => {
|
||||||
if (query) return ['lyrics', 'search', query] as const;
|
if (query) return ['lyrics', 'search', query] as const;
|
||||||
return ['lyrics', 'search'] as const;
|
return ['lyrics', 'search'] as const;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import isElectron from 'is-electron';
|
|||||||
|
|
||||||
import { api } from '/@/renderer/api';
|
import { api } from '/@/renderer/api';
|
||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
import { queryClient, QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||||
import { getServerById, useSettingsStore } from '/@/renderer/store';
|
import { getServerById, useSettingsStore } from '/@/renderer/store';
|
||||||
import { hasFeature } from '/@/shared/api/utils';
|
import { hasFeature } from '/@/shared/api/utils';
|
||||||
import {
|
import {
|
||||||
@@ -14,7 +14,6 @@ import {
|
|||||||
LyricSearchQuery,
|
LyricSearchQuery,
|
||||||
LyricsQuery,
|
LyricsQuery,
|
||||||
QueueSong,
|
QueueSong,
|
||||||
ServerType,
|
|
||||||
StructuredLyric,
|
StructuredLyric,
|
||||||
SynchronizedLyricsArray,
|
SynchronizedLyricsArray,
|
||||||
} from '/@/shared/types/domain-types';
|
} from '/@/shared/types/domain-types';
|
||||||
@@ -65,6 +64,34 @@ const formatLyrics = (lyrics: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const lyricsQueries = {
|
export const lyricsQueries = {
|
||||||
|
remoteLyrics: (args: QueryHookArgs<LyricsQuery>, song: QueueSong | undefined) => {
|
||||||
|
return queryOptions({
|
||||||
|
gcTime: Infinity,
|
||||||
|
queryFn: async (): Promise<FullLyricsMetadata | null> => {
|
||||||
|
if (!song) return null;
|
||||||
|
|
||||||
|
const { fetch } = useSettingsStore.getState().lyrics;
|
||||||
|
|
||||||
|
if (!fetch) return null;
|
||||||
|
|
||||||
|
const remoteLyricsResult: InternetProviderLyricResponse | null =
|
||||||
|
await lyricsIpc?.getRemoteLyricsBySong(song);
|
||||||
|
|
||||||
|
if (remoteLyricsResult) {
|
||||||
|
return {
|
||||||
|
...remoteLyricsResult,
|
||||||
|
lyrics: formatLyrics(remoteLyricsResult.lyrics),
|
||||||
|
remote: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
queryKey: queryKeys.songs.remoteLyrics(args.serverId, args.query),
|
||||||
|
staleTime: Infinity,
|
||||||
|
...args.options,
|
||||||
|
});
|
||||||
|
},
|
||||||
search: (args: Omit<QueryHookArgs<LyricSearchQuery>, 'serverId'>) => {
|
search: (args: Omit<QueryHookArgs<LyricSearchQuery>, 'serverId'>) => {
|
||||||
return queryOptions({
|
return queryOptions({
|
||||||
gcTime: 1000 * 60 * 1,
|
gcTime: 1000 * 60 * 1,
|
||||||
@@ -79,34 +106,15 @@ export const lyricsQueries = {
|
|||||||
...args.options,
|
...args.options,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
serverLyrics: (args: QueryHookArgs<LyricsQuery>) => {
|
serverLyrics: (args: QueryHookArgs<LyricsQuery>, song: QueueSong | undefined) => {
|
||||||
return queryOptions({
|
|
||||||
queryFn: ({ signal }) => {
|
|
||||||
const server = getServerById(args.serverId);
|
|
||||||
if (!server) throw new Error('Server not found');
|
|
||||||
// This should only be called for Jellyfin. Return null to ignore errors
|
|
||||||
if (server.type !== ServerType.JELLYFIN) return null;
|
|
||||||
return api.controller.getLyrics({
|
|
||||||
apiClientProps: { serverId: args.serverId, signal },
|
|
||||||
query: args.query,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
queryKey: queryKeys.songs.lyrics(args.serverId, args.query),
|
|
||||||
...args.options,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
songLyrics: (args: QueryHookArgs<LyricsQuery>, song: QueueSong | undefined) => {
|
|
||||||
return queryOptions({
|
return queryOptions({
|
||||||
gcTime: Infinity,
|
gcTime: Infinity,
|
||||||
queryFn: async ({ signal }): Promise<FullLyricsMetadata | null | StructuredLyric[]> => {
|
queryFn: async ({ signal }): Promise<FullLyricsMetadata | null | StructuredLyric[]> => {
|
||||||
const server = getServerById(song?._serverId);
|
const server = getServerById(args.serverId);
|
||||||
if (!server) throw new Error('Server not found');
|
if (!server) throw new Error('Server not found');
|
||||||
if (!song) return null;
|
if (!song) return null;
|
||||||
|
|
||||||
const { preferLocalLyrics } = useSettingsStore.getState().lyrics;
|
|
||||||
|
|
||||||
let localLyrics: FullLyricsMetadata | null | StructuredLyric[] = null;
|
let localLyrics: FullLyricsMetadata | null | StructuredLyric[] = null;
|
||||||
let remoteLyrics: FullLyricsMetadata | null | StructuredLyric[] = null;
|
|
||||||
|
|
||||||
if (hasFeature(server, ServerFeature.LYRICS_MULTIPLE_STRUCTURED)) {
|
if (hasFeature(server, ServerFeature.LYRICS_MULTIPLE_STRUCTURED)) {
|
||||||
const subsonicLyrics = await api.controller
|
const subsonicLyrics = await api.controller
|
||||||
@@ -146,34 +154,33 @@ export const lyricsQueries = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preferLocalLyrics && localLyrics) {
|
|
||||||
return localLyrics;
|
return localLyrics;
|
||||||
}
|
},
|
||||||
|
queryKey: queryKeys.songs.serverLyrics(args.serverId, args.query),
|
||||||
|
staleTime: Infinity,
|
||||||
|
...args.options,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
songLyrics: (args: QueryHookArgs<LyricsQuery>, song: QueueSong | undefined) => {
|
||||||
|
return queryOptions({
|
||||||
|
gcTime: Infinity,
|
||||||
|
queryFn: async ({ signal }): Promise<FullLyricsMetadata | null | StructuredLyric[]> => {
|
||||||
|
if (!song) return null;
|
||||||
|
|
||||||
const { fetch } = useSettingsStore.getState().lyrics;
|
const serverLyricsQuery = lyricsQueries.serverLyrics(args, song);
|
||||||
|
const serverLyrics = await queryClient.fetchQuery({
|
||||||
|
...serverLyricsQuery,
|
||||||
|
queryFn: async (context) => {
|
||||||
|
return (
|
||||||
|
serverLyricsQuery.queryFn?.({
|
||||||
|
...context,
|
||||||
|
signal,
|
||||||
|
}) ?? null
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (fetch) {
|
return serverLyrics;
|
||||||
const remoteLyricsResult: InternetProviderLyricResponse | null =
|
|
||||||
await lyricsIpc?.getRemoteLyricsBySong(song);
|
|
||||||
|
|
||||||
if (remoteLyricsResult) {
|
|
||||||
remoteLyrics = {
|
|
||||||
...remoteLyricsResult,
|
|
||||||
lyrics: formatLyrics(remoteLyricsResult.lyrics),
|
|
||||||
remote: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remoteLyrics) {
|
|
||||||
return remoteLyrics;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (localLyrics) {
|
|
||||||
return localLyrics;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
},
|
},
|
||||||
queryKey: queryKeys.songs.lyrics(args.serverId, args.query),
|
queryKey: queryKeys.songs.lyrics(args.serverId, args.query),
|
||||||
staleTime: Infinity,
|
staleTime: Infinity,
|
||||||
@@ -182,6 +189,7 @@ export const lyricsQueries = {
|
|||||||
},
|
},
|
||||||
songLyricsByRemoteId: (args: QueryHookArgs<Partial<LyricGetQuery>>) => {
|
songLyricsByRemoteId: (args: QueryHookArgs<Partial<LyricGetQuery>>) => {
|
||||||
return queryOptions({
|
return queryOptions({
|
||||||
|
gcTime: Infinity,
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const remoteLyricsResult = await lyricsIpc?.getRemoteLyricsByRemoteId(
|
const remoteLyricsResult = await lyricsIpc?.getRemoteLyricsByRemoteId(
|
||||||
args.query as any,
|
args.query as any,
|
||||||
@@ -194,6 +202,7 @@ export const lyricsQueries = {
|
|||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
queryKey: queryKeys.songs.lyricsByRemoteId(args.query),
|
queryKey: queryKeys.songs.lyricsByRemoteId(args.query),
|
||||||
|
staleTime: Infinity,
|
||||||
...args.options,
|
...args.options,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -62,7 +62,12 @@ export const LyricsActions = ({
|
|||||||
value={index.toString()}
|
value={index.toString()}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Button onClick={onExportLyrics} uppercase variant="subtle">
|
<Button
|
||||||
|
onClick={onExportLyrics}
|
||||||
|
size="compact-sm"
|
||||||
|
uppercase
|
||||||
|
variant="subtle"
|
||||||
|
>
|
||||||
{t('form.lyricsExport.export', { postProcess: 'sentenceCase ' })}
|
{t('form.lyricsExport.export', { postProcess: 'sentenceCase ' })}
|
||||||
</Button>
|
</Button>
|
||||||
</Center>
|
</Center>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import { openLyricsSettingsModal } from '/@/renderer/features/lyrics/utils/open-
|
|||||||
import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/use-player-events';
|
import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/use-player-events';
|
||||||
import { ComponentErrorBoundary } from '/@/renderer/features/shared/components/component-error-boundary';
|
import { ComponentErrorBoundary } from '/@/renderer/features/shared/components/component-error-boundary';
|
||||||
import { queryClient } from '/@/renderer/lib/react-query';
|
import { queryClient } from '/@/renderer/lib/react-query';
|
||||||
import { useLyricsSettings, usePlayerSong } from '/@/renderer/store';
|
import { useLyricsSettings, usePlayerSong, useSettingsStore } from '/@/renderer/store';
|
||||||
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
|
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
|
||||||
import { Center } from '/@/shared/components/center/center';
|
import { Center } from '/@/shared/components/center/center';
|
||||||
import { Group } from '/@/shared/components/group/group';
|
import { Group } from '/@/shared/components/group/group';
|
||||||
@@ -44,6 +44,7 @@ export const Lyrics = ({ fadeOutNoLyricsMessage = true, settingsKey = 'default'
|
|||||||
const currentSong = usePlayerSong();
|
const currentSong = usePlayerSong();
|
||||||
const {
|
const {
|
||||||
enableAutoTranslation,
|
enableAutoTranslation,
|
||||||
|
preferLocalLyrics,
|
||||||
translationApiKey,
|
translationApiKey,
|
||||||
translationApiProvider,
|
translationApiProvider,
|
||||||
translationTargetLanguage,
|
translationTargetLanguage,
|
||||||
@@ -98,11 +99,68 @@ export const Lyrics = ({ fadeOutNoLyricsMessage = true, settingsKey = 'default'
|
|||||||
);
|
);
|
||||||
|
|
||||||
const [override, setOverride] = useState<LyricsOverride | undefined>(undefined);
|
const [override, setOverride] = useState<LyricsOverride | undefined>(undefined);
|
||||||
|
const [autoRemoteLyrics, setAutoRemoteLyrics] = useState<FullLyricsMetadata | null>(null);
|
||||||
|
const clearedOverrideRef = useRef<string | undefined>(undefined);
|
||||||
|
|
||||||
|
// Fetch remote lyrics automatically (but not if we've explicitly cleared the override)
|
||||||
|
const { data: remoteLyricsData } = useQuery(
|
||||||
|
lyricsQueries.remoteLyrics(
|
||||||
|
{
|
||||||
|
options: {
|
||||||
|
enabled:
|
||||||
|
!!pendingSongId &&
|
||||||
|
pendingSongId === currentSong?.id &&
|
||||||
|
!override &&
|
||||||
|
clearedOverrideRef.current !== currentSong?.id &&
|
||||||
|
useSettingsStore.getState().lyrics.fetch,
|
||||||
|
},
|
||||||
|
query: { songId: currentSong?.id || '' },
|
||||||
|
serverId: currentSong?._serverId || '',
|
||||||
|
},
|
||||||
|
currentSong,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Automatically set remote lyrics as override when fetched
|
||||||
|
// Only auto-apply if preferLocalLyrics is disabled OR if local lyrics are not available
|
||||||
|
useEffect(() => {
|
||||||
|
// Don't auto-set if we've explicitly cleared the override for this song
|
||||||
|
if (
|
||||||
|
remoteLyricsData &&
|
||||||
|
!override &&
|
||||||
|
currentSong &&
|
||||||
|
clearedOverrideRef.current !== currentSong.id
|
||||||
|
) {
|
||||||
|
// If preferLocalLyrics is enabled, wait for local lyrics to finish loading
|
||||||
|
if (preferLocalLyrics && isInitialLoading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if local lyrics are available
|
||||||
|
const hasLocalLyrics =
|
||||||
|
(Array.isArray(data) && data.length > 0) ||
|
||||||
|
(data && !Array.isArray(data) && data.lyrics);
|
||||||
|
|
||||||
|
// Only auto-apply remote lyrics if:
|
||||||
|
// 1. preferLocalLyrics is disabled, OR
|
||||||
|
// 2. preferLocalLyrics is enabled but no local lyrics are available
|
||||||
|
if (!preferLocalLyrics || !hasLocalLyrics) {
|
||||||
|
// Store the remote lyrics data directly (it already contains the lyrics)
|
||||||
|
setAutoRemoteLyrics(remoteLyricsData);
|
||||||
|
} else {
|
||||||
|
// Clear auto remote lyrics if local lyrics are preferred and available
|
||||||
|
setAutoRemoteLyrics(null);
|
||||||
|
}
|
||||||
|
} else if (!remoteLyricsData || override) {
|
||||||
|
// Clear auto remote lyrics if override is set or remote lyrics are cleared
|
||||||
|
setAutoRemoteLyrics(null);
|
||||||
|
}
|
||||||
|
}, [remoteLyricsData, override, currentSong, preferLocalLyrics, data, isInitialLoading]);
|
||||||
|
|
||||||
const { data: overrideData, isInitialLoading: isOverrideLoading } = useQuery(
|
const { data: overrideData, isInitialLoading: isOverrideLoading } = useQuery(
|
||||||
lyricsQueries.songLyricsByRemoteId({
|
lyricsQueries.songLyricsByRemoteId({
|
||||||
options: {
|
options: {
|
||||||
enabled: !!override,
|
enabled: !!override && !!override.id,
|
||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
remoteSongId: override?.id,
|
remoteSongId: override?.id,
|
||||||
@@ -127,8 +185,8 @@ export const Lyrics = ({ fadeOutNoLyricsMessage = true, settingsKey = 'default'
|
|||||||
}, [data, index]);
|
}, [data, index]);
|
||||||
|
|
||||||
const [lyrics, synced] = useMemo(() => {
|
const [lyrics, synced] = useMemo(() => {
|
||||||
// If override data is available, use it
|
// If override data is available, use it (manual override always takes priority)
|
||||||
if (override && overrideData) {
|
if (override && overrideData && override.id) {
|
||||||
const overrideLyrics: FullLyricsMetadata = {
|
const overrideLyrics: FullLyricsMetadata = {
|
||||||
artist: override.artist,
|
artist: override.artist,
|
||||||
lyrics: overrideData,
|
lyrics: overrideData,
|
||||||
@@ -137,21 +195,42 @@ export const Lyrics = ({ fadeOutNoLyricsMessage = true, settingsKey = 'default'
|
|||||||
remote: override.remote ?? true,
|
remote: override.remote ?? true,
|
||||||
source: override.source,
|
source: override.source,
|
||||||
};
|
};
|
||||||
return [overrideLyrics, Array.isArray(overrideData)];
|
return [overrideLyrics, Array.isArray(overrideData), 'override'] as const;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, use the regular data
|
// Check if local lyrics are available
|
||||||
|
const hasLocalLyrics =
|
||||||
|
(Array.isArray(data) && data.length > 0) ||
|
||||||
|
(data && !Array.isArray(data) && data.lyrics);
|
||||||
|
|
||||||
|
// If preferLocalLyrics is enabled and local lyrics are available, prioritize them
|
||||||
|
if (preferLocalLyrics && hasLocalLyrics) {
|
||||||
|
if (Array.isArray(data)) {
|
||||||
|
const selectedLyric = data[Math.min(index, data.length - 1)];
|
||||||
|
return [selectedLyric, selectedLyric.synced, 'server'] as const;
|
||||||
|
} else if (data?.lyrics) {
|
||||||
|
return [data, Array.isArray(data.lyrics), 'server'] as const;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If auto-fetched remote lyrics are available, use them
|
||||||
|
// (This will only be set if preferLocalLyrics is disabled OR no local lyrics exist)
|
||||||
|
if (autoRemoteLyrics) {
|
||||||
|
return [autoRemoteLyrics, Array.isArray(autoRemoteLyrics.lyrics), 'override'] as const;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, use the server-side lyrics data
|
||||||
if (Array.isArray(data)) {
|
if (Array.isArray(data)) {
|
||||||
if (data.length > 0) {
|
if (data.length > 0) {
|
||||||
const selectedLyric = data[Math.min(index, data.length - 1)];
|
const selectedLyric = data[Math.min(index, data.length - 1)];
|
||||||
return [selectedLyric, selectedLyric.synced];
|
return [selectedLyric, selectedLyric.synced, 'server'] as const;
|
||||||
}
|
}
|
||||||
} else if (data?.lyrics) {
|
} else if (data?.lyrics) {
|
||||||
return [data, Array.isArray(data.lyrics)];
|
return [data, Array.isArray(data.lyrics), 'server'] as const;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [undefined, false];
|
return [undefined, false, 'server'] as const;
|
||||||
}, [data, index, override, overrideData, currentOffsetMs]);
|
}, [data, index, override, overrideData, autoRemoteLyrics, currentOffsetMs, preferLocalLyrics]);
|
||||||
|
|
||||||
const handleOnSearchOverride = useCallback((params: LyricsOverride) => {
|
const handleOnSearchOverride = useCallback((params: LyricsOverride) => {
|
||||||
setOverride(params);
|
setOverride(params);
|
||||||
@@ -159,7 +238,7 @@ export const Lyrics = ({ fadeOutNoLyricsMessage = true, settingsKey = 'default'
|
|||||||
|
|
||||||
// Persist override lyrics to cache with current offset
|
// Persist override lyrics to cache with current offset
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (override && overrideData && currentSong) {
|
if (override && overrideData && currentSong && override.id) {
|
||||||
const persistedLyrics: FullLyricsMetadata = {
|
const persistedLyrics: FullLyricsMetadata = {
|
||||||
artist: override.artist,
|
artist: override.artist,
|
||||||
lyrics: overrideData,
|
lyrics: overrideData,
|
||||||
@@ -211,46 +290,58 @@ export const Lyrics = ({ fadeOutNoLyricsMessage = true, settingsKey = 'default'
|
|||||||
[currentSong, index],
|
[currentSong, index],
|
||||||
);
|
);
|
||||||
|
|
||||||
// const handleOnResetLyric = useCallback(() => {
|
const handleOnRemoveLyric = useCallback(async () => {
|
||||||
// setOverride(undefined);
|
if (!currentSong) return;
|
||||||
// queryClient.invalidateQueries({
|
|
||||||
// exact: true,
|
|
||||||
// queryKey: queryKeys.songs.lyrics(currentSong?._serverId, { songId: currentSong?.id }),
|
|
||||||
// });
|
|
||||||
// }, [currentSong?.id, currentSong?._serverId]);
|
|
||||||
|
|
||||||
const handleOnRemoveLyric = useCallback(() => {
|
const currentOverride = override;
|
||||||
|
clearedOverrideRef.current = currentSong.id;
|
||||||
|
|
||||||
|
// Clear the override state and auto remote lyrics
|
||||||
setOverride(undefined);
|
setOverride(undefined);
|
||||||
|
setAutoRemoteLyrics(null);
|
||||||
// Clear the main lyrics query cache
|
|
||||||
queryClient.setQueryData(
|
|
||||||
queryKeys.songs.lyrics(currentSong?._serverId, { songId: currentSong?.id }),
|
|
||||||
(prev: FullLyricsMetadata | StructuredLyric[] | undefined) => {
|
|
||||||
if (!prev) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(prev)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
...prev,
|
|
||||||
lyrics: '',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// Clear the override query cache if it exists
|
// Clear the override query cache if it exists
|
||||||
if (override) {
|
if (currentOverride?.id) {
|
||||||
queryClient.removeQueries({
|
queryClient.removeQueries({
|
||||||
queryKey: queryKeys.songs.lyricsByRemoteId({
|
queryKey: queryKeys.songs.lyricsByRemoteId({
|
||||||
remoteSongId: override.id,
|
remoteSongId: currentOverride.id,
|
||||||
remoteSource: override.source,
|
remoteSource: currentOverride.source,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [currentSong?.id, currentSong?._serverId, override]);
|
|
||||||
|
// Clear the remote lyrics cache
|
||||||
|
queryClient.removeQueries({
|
||||||
|
queryKey: queryKeys.songs.remoteLyrics(currentSong._serverId, {
|
||||||
|
songId: currentSong.id,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clear the server lyrics cache so it refetches from server
|
||||||
|
const serverLyricsQueryKey = queryKeys.songs.serverLyrics(currentSong._serverId, {
|
||||||
|
songId: currentSong.id,
|
||||||
|
});
|
||||||
|
queryClient.removeQueries({
|
||||||
|
queryKey: serverLyricsQueryKey,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove the main lyrics query cache
|
||||||
|
const lyricsQueryKey = queryKeys.songs.lyrics(currentSong._serverId, {
|
||||||
|
songId: currentSong.id,
|
||||||
|
});
|
||||||
|
queryClient.removeQueries({
|
||||||
|
exact: true,
|
||||||
|
queryKey: lyricsQueryKey,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Refetch server lyrics first, then song lyrics to ensure fresh data from server
|
||||||
|
await queryClient.refetchQueries({
|
||||||
|
queryKey: serverLyricsQueryKey,
|
||||||
|
});
|
||||||
|
await queryClient.refetchQueries({
|
||||||
|
queryKey: lyricsQueryKey,
|
||||||
|
});
|
||||||
|
}, [currentSong, override]);
|
||||||
|
|
||||||
const fetchTranslation = useCallback(async () => {
|
const fetchTranslation = useCallback(async () => {
|
||||||
if (!lyrics) return;
|
if (!lyrics) return;
|
||||||
@@ -279,6 +370,8 @@ export const Lyrics = ({ fadeOutNoLyricsMessage = true, settingsKey = 'default'
|
|||||||
{
|
{
|
||||||
onCurrentSongChange: () => {
|
onCurrentSongChange: () => {
|
||||||
setOverride(undefined);
|
setOverride(undefined);
|
||||||
|
setAutoRemoteLyrics(null);
|
||||||
|
clearedOverrideRef.current = undefined;
|
||||||
setIndex(0);
|
setIndex(0);
|
||||||
setShowTranslation(false);
|
setShowTranslation(false);
|
||||||
setTranslatedLyrics(null);
|
setTranslatedLyrics(null);
|
||||||
|
|||||||
Reference in New Issue
Block a user