From a985df1bf52455acd1010dd5e5aeeb1796068223 Mon Sep 17 00:00:00 2001 From: mrtbts <66320961+scratchusernamemrtbts@users.noreply.github.com> Date: Tue, 15 Apr 2025 21:48:16 +0700 Subject: [PATCH] feat(synced-lyrics): lyrics offset --- src/i18n/resources/en.json | 8 ++++++ src/plugins/synced-lyrics/index.ts | 1 + src/plugins/synced-lyrics/menu.ts | 27 +++++++++++++++++++ .../renderer/components/SyncedLine.tsx | 2 +- src/plugins/synced-lyrics/types.ts | 1 + 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/i18n/resources/en.json b/src/i18n/resources/en.json index 824a681e51..19332ef609 100644 --- a/src/i18n/resources/en.json +++ b/src/i18n/resources/en.json @@ -752,6 +752,14 @@ }, "tooltip": "Choose the effect to apply to the current line" }, + "offset": { + "label": "Lyrics offset", + "tooltip": "Set the offset for the lyrics (useful when using bluetooth speakers)", + "prompt": { + "title": "Lyrics offset", + "label": "Set the lyrics offset in ms" + } + }, "precise-timing": { "label": "Make the lyrics perfectly synced", "tooltip": "Calculate to the milisecond the display of the next line (can have a small impact on performance)" diff --git a/src/plugins/synced-lyrics/index.ts b/src/plugins/synced-lyrics/index.ts index 1dbc2d55cb..5a6c01064d 100644 --- a/src/plugins/synced-lyrics/index.ts +++ b/src/plugins/synced-lyrics/index.ts @@ -16,6 +16,7 @@ export default createPlugin({ config: { enabled: false, preciseTiming: true, + lyricsOffset: 0, showLyricsEvenIfInexact: true, showTimeCodes: false, defaultTextString: '♪', diff --git a/src/plugins/synced-lyrics/menu.ts b/src/plugins/synced-lyrics/menu.ts index 2a1adcb32e..df4d6f08d9 100644 --- a/src/plugins/synced-lyrics/menu.ts +++ b/src/plugins/synced-lyrics/menu.ts @@ -1,4 +1,7 @@ +import prompt from 'custom-electron-prompt'; + import { t } from '@/i18n'; +import promptOptions from '@/providers/prompt-options'; import type { MenuItemConstructorOptions } from 'electron'; import type { MenuContext } from '@/types/contexts'; @@ -10,6 +13,30 @@ export const menu = async ( const config = await ctx.getConfig(); return [ + { + label: t('plugins.synced-lyrics.menu.offset.label'), + toolTip: t('plugins.synced-lyrics.menu.offset.tooltip'), + type: 'normal', + async click() { + const config = await ctx.getConfig(); + const newOffset = await prompt( + { + title: t('plugins.synced-lyrics.menu.offset.prompt.title'), + label: t('plugins.synced-lyrics.menu.offset.prompt.label'), + value: config.lyricsOffset || 0, + type: 'counter', + counterOptions: { multiFire: true }, + width: 380, + ...promptOptions(), + }, + ctx.window, + ); + + ctx.setConfig({ + lyricsOffset: newOffset ?? config.lyricsOffset, + }); + }, + }, { label: t('plugins.synced-lyrics.menu.precise-timing.label'), toolTip: t('plugins.synced-lyrics.menu.precise-timing.tooltip'), diff --git a/src/plugins/synced-lyrics/renderer/components/SyncedLine.tsx b/src/plugins/synced-lyrics/renderer/components/SyncedLine.tsx index abca8fc0c1..5489690147 100644 --- a/src/plugins/synced-lyrics/renderer/components/SyncedLine.tsx +++ b/src/plugins/synced-lyrics/renderer/components/SyncedLine.tsx @@ -24,7 +24,7 @@ interface SyncedLineProps { export const SyncedLine = (props: SyncedLineProps) => { const status = createMemo(() => { - const current = currentTime(); + const current = Math.max(0, currentTime() - (config()?.lyricsOffset ?? 0)); if (props.line.timeInMs >= current) return 'upcoming'; if (current - props.line.timeInMs >= props.line.duration) return 'previous'; diff --git a/src/plugins/synced-lyrics/types.ts b/src/plugins/synced-lyrics/types.ts index b33e16abdc..596ad98dbc 100644 --- a/src/plugins/synced-lyrics/types.ts +++ b/src/plugins/synced-lyrics/types.ts @@ -4,6 +4,7 @@ export type SyncedLyricsPluginConfig = { enabled: boolean; preciseTiming: boolean; showTimeCodes: boolean; + lyricsOffset: number; defaultTextString: string; showLyricsEvenIfInexact: boolean; lineEffect: LineEffect;