- {languages.length > 1 && (
-
-
- )}
+ <>
+
+ {languages.length > 0 && (
+
+ {languages.length > 1 && (
+
+ )}
-
- {isDesktop && sources.length ? (
-
- ) : null}
- handleLyricOffset(offsetMs - 50)}
- tooltip={{
- label: t('common.slower', { postProcess: 'sentenceCase' }),
- openDelay: 0,
- }}
- variant="subtle"
- />
-
-
-
- handleLyricOffset(offsetMs + 50)}
- tooltip={{
- label: t('common.faster', { postProcess: 'sentenceCase' }),
- openDelay: 0,
- }}
- variant="subtle"
- />
- {isDesktop && sources.length ? (
-
- {t('common.clear', { postProcess: 'sentenceCase' })}
-
- ) : null}
-
+
+
+
handleLyricOffset(offsetMs + 50)}
+ tooltip={{
+ label: t('common.faster', { postProcess: 'sentenceCase' }),
+ openDelay: 0,
+ }}
+ variant="subtle"
+ />
+ {isDesktop && sources.length ? (
+
+ {t('common.clear', { postProcess: 'sentenceCase' })}
+
+ ) : null}
+
-
- {isDesktop && sources.length && onTranslateLyric ? (
-
- {t('common.translation', { postProcess: 'sentenceCase' })}
-
- ) : null}
+
+ {isDesktop && sources.length && onTranslateLyric ? (
+
+ {t('common.translation', { postProcess: 'sentenceCase' })}
+
+ ) : null}
+
-
+ >
);
};
diff --git a/src/renderer/features/lyrics/lyrics.tsx b/src/renderer/features/lyrics/lyrics.tsx
index 3aeabe5c5..84f61d96e 100644
--- a/src/renderer/features/lyrics/lyrics.tsx
+++ b/src/renderer/features/lyrics/lyrics.tsx
@@ -8,6 +8,7 @@ import styles from './lyrics.module.css';
import { queryKeys } from '/@/renderer/api/query-keys';
import { translateLyrics } from '/@/renderer/features/lyrics/api/lyric-translate';
import { lyricsQueries } from '/@/renderer/features/lyrics/api/lyrics-api';
+import { openLyricsExportModal } from '/@/renderer/features/lyrics/components/lyrics-export-form';
import { LyricsActions } from '/@/renderer/features/lyrics/lyrics-actions';
import {
SynchronizedLyrics,
@@ -258,6 +259,10 @@ export const Lyrics = ({ fadeOutNoLyricsMessage = true }: LyricsProps) => {
const languages = useMemo(() => {
if (Array.isArray(data)) {
return data.map((lyric, idx) => ({ label: lyric.lang, value: idx.toString() }));
+ } else if (data?.lyrics) {
+ // xxx denotes undefined lyrics language. If it's a single lyric (from a remote source)
+ // the language is most likely not available, so leave it undefined
+ return [{ label: 'xxx', value: '0' }];
}
return [];
}, [data]);
@@ -290,6 +295,12 @@ export const Lyrics = ({ fadeOutNoLyricsMessage = true }: LyricsProps) => {
return undefined;
}, [isLoadingLyrics, hasNoLyrics, fadeOutNoLyricsMessage]);
+ const handleExportLyrics = useCallback(() => {
+ if (lyrics) {
+ openLyricsExportModal({ lyrics, offsetMs: currentOffsetMs, synced });
+ }
+ }, [currentOffsetMs, lyrics, synced]);
+
return (
@@ -341,6 +352,7 @@ export const Lyrics = ({ fadeOutNoLyricsMessage = true }: LyricsProps) => {
index={index}
languages={languages}
offsetMs={currentOffsetMs}
+ onExportLyrics={handleExportLyrics}
onRemoveLyric={handleOnRemoveLyric}
onSearchOverride={handleOnSearchOverride}
onTranslateLyric={