Fix Lyric Translation Not Resetting (#1208)

* Refactor lyrics translation and index handling

* Add auto translation toggle to lyric settings

* Add enableAutoTranslation setting to lyrics
This commit is contained in:
Xudong Zhou 2025-11-01 08:08:10 +08:00 committed by GitHub
parent d12e4a1635
commit dd34888961
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 51 additions and 18 deletions

View file

@ -32,8 +32,12 @@ import { FullLyricsMetadata, LyricSource, LyricsOverride } from '/@/shared/types
export const Lyrics = () => {
const currentSong = useCurrentSong();
const { translationApiKey, translationApiProvider, translationTargetLanguage } =
useLyricsSettings();
const {
enableAutoTranslation,
translationApiKey,
translationApiProvider,
translationTargetLanguage,
} = useLyricsSettings();
const { t } = useTranslation();
const [index, setIndex] = useState(0);
const [translatedLyrics, setTranslatedLyrics] = useState<null | string>(null);
@ -52,7 +56,7 @@ export const Lyrics = () => {
const [lyrics, synced] = useMemo(() => {
if (Array.isArray(data)) {
if (data.length > 0) {
const selectedLyric = data[Math.min(index, data.length)];
const selectedLyric = data[Math.min(index, data.length - 1)];
return [selectedLyric, selectedLyric.synced];
}
} else if (data?.lyrics) {
@ -89,11 +93,7 @@ export const Lyrics = () => {
);
}, [currentSong?.id, currentSong?.serverId]);
const handleOnTranslateLyric = useCallback(async () => {
if (translatedLyrics) {
setShowTranslation(!showTranslation);
return;
}
const fetchTranslation = useCallback(async () => {
if (!lyrics) return;
const originalLyrics = Array.isArray(lyrics.lyrics)
? lyrics.lyrics.map(([, line]) => line).join('\n')
@ -106,14 +106,15 @@ export const Lyrics = () => {
);
setTranslatedLyrics(TranslatedText);
setShowTranslation(true);
}, [
translatedLyrics,
lyrics,
translationApiKey,
translationApiProvider,
translationTargetLanguage,
showTranslation,
]);
}, [lyrics, translationApiKey, translationApiProvider, translationTargetLanguage]);
const handleOnTranslateLyric = useCallback(async () => {
if (translatedLyrics) {
setShowTranslation(!showTranslation);
return;
}
await fetchTranslation();
}, [translatedLyrics, showTranslation, fetchTranslation]);
const { isInitialLoading: isOverrideLoading } = useSongLyricsByRemoteId({
options: {
@ -133,6 +134,8 @@ export const Lyrics = () => {
() => {
setOverride(undefined);
setIndex(0);
setShowTranslation(false);
setTranslatedLyrics(null);
},
{ equalityFn: (a, b) => a?.id === b?.id },
);
@ -142,6 +145,12 @@ export const Lyrics = () => {
};
}, []);
useEffect(() => {
if (lyrics && !translatedLyrics && enableAutoTranslation) {
fetchTranslation();
}
}, [lyrics, translatedLyrics, enableAutoTranslation, fetchTranslation]);
const languages = useMemo(() => {
if (Array.isArray(data)) {
return data.map((lyric, idx) => ({ label: lyric.lang, value: idx.toString() }));

View file

@ -214,6 +214,28 @@ export const LyricSettings = () => {
isHidden: !isElectron(),
title: t('setting.translationApiKey', { postProcess: 'sentenceCase' }),
},
{
control: (
<Switch
aria-label="Enable auto translation"
defaultChecked={settings.enableAutoTranslation}
onChange={(e) => {
setSettings({
lyrics: {
...settings,
enableAutoTranslation: e.currentTarget.checked,
},
});
}}
/>
),
description: t('setting.enableAutoTranslation', {
context: 'description',
postProcess: 'sentenceCase',
}),
isHidden: !isElectron(),
title: t('setting.enableAutoTranslation', { postProcess: 'sentenceCase' }),
},
];
return <SettingsSection divider={false} options={lyricOptions} />;

View file

@ -225,6 +225,7 @@ const HotkeysSettingsSchema = z.object({
const LyricsSettingsSchema = z.object({
alignment: z.enum(['center', 'left', 'right']),
delayMs: z.number(),
enableAutoTranslation: z.boolean(),
enableNeteaseTranslation: z.boolean(),
fetch: z.boolean(),
follow: z.boolean(),
@ -612,6 +613,7 @@ const initialState: SettingsState = {
lyrics: {
alignment: 'center',
delayMs: 0,
enableAutoTranslation: false,
enableNeteaseTranslation: false,
fetch: false,
follow: true,