diff --git a/src/plugins/synced-lyrics/menu.ts b/src/plugins/synced-lyrics/menu.ts index 2a1adcb3..c6f51c12 100644 --- a/src/plugins/synced-lyrics/menu.ts +++ b/src/plugins/synced-lyrics/menu.ts @@ -93,47 +93,23 @@ export const menu = async ( toolTip: t('plugins.synced-lyrics.menu.default-text-string.tooltip'), type: 'submenu', submenu: [ - { - label: '♪', - type: 'radio', - checked: config.defaultTextString === '♪', - click() { - ctx.setConfig({ - defaultTextString: '♪', - }); - }, + { label: '♪', value: '♪' }, + { label: '" "', value: ' ' }, + { label: '...', value: ['.', '..', '...'] }, + { label: '•••', value: ['•', '••', '•••'] }, + { label: '———', value: '———' }, + ].map(({ label, value }) => ({ + label, + type: 'radio', + checked: + typeof value === 'string' + ? config.defaultTextString === value + : JSON.stringify(config.defaultTextString) === + JSON.stringify(value), + click() { + ctx.setConfig({ defaultTextString: value }); }, - { - label: '" "', - type: 'radio', - checked: config.defaultTextString === ' ', - click() { - ctx.setConfig({ - defaultTextString: ' ', - }); - }, - }, - { - label: '...', - type: 'radio', - checked: config.defaultTextString === '...', - click() { - ctx.setConfig({ - defaultTextString: '...', - }); - }, - }, - { - label: '———', - type: 'radio', - checked: config.defaultTextString === '———', - click() { - ctx.setConfig({ - defaultTextString: '———', - }); - }, - }, - ], + })), }, { label: t('plugins.synced-lyrics.menu.romanization.label'), diff --git a/src/plugins/synced-lyrics/renderer/components/SyncedLine.tsx b/src/plugins/synced-lyrics/renderer/components/SyncedLine.tsx index c3826833..b34f0982 100644 --- a/src/plugins/synced-lyrics/renderer/components/SyncedLine.tsx +++ b/src/plugins/synced-lyrics/renderer/components/SyncedLine.tsx @@ -1,10 +1,10 @@ -import { createEffect, createMemo, For, Show, createSignal } from 'solid-js'; +import { createEffect, For, Show, createSignal, createMemo } from 'solid-js'; import { type VirtualizerHandle } from 'virtua/solid'; import { type LineLyrics } from '@/plugins/synced-lyrics/types'; -import { config } from '../renderer'; +import { config, currentTime } from '../renderer'; import { _ytAPI } from '..'; import { canonicalize, romanize, simplifyUnicode } from '../utils'; @@ -17,37 +17,84 @@ interface SyncedLineProps { status: 'upcoming' | 'current' | 'previous'; } -export const SyncedLine = (props: SyncedLineProps) => { - const text = createMemo(() => { - if (!props.line.text.trim()) { - return config()?.defaultTextString ?? ''; - } - - return props.line.text; +const EmptyLine = (props: SyncedLineProps) => { + const states = createMemo(() => { + const defaultText = config()?.defaultTextString ?? ''; + return Array.isArray(defaultText) ? defaultText : [defaultText]; }); - const [romanization, setRomanization] = createSignal(''); + const index = createMemo(() => { + const progress = currentTime() - props.line.timeInMs; + const total = props.line.duration; + const percentage = Math.min(1, progress / total); + return Math.max(0, Math.floor((states().length - 1) * percentage)); + }); + + return ( +
{ + _ytAPI?.seekTo((props.line.timeInMs + 10) / 1000); + }} + > +
+ + +
+ + + + } + when={states().length > 1} + > + + + + +
+
+
+ ); +}; + +export const SyncedLine = (props: SyncedLineProps) => { + const text = createMemo(() => props.line.text.trim()); + + const [romanization, setRomanization] = createSignal(''); createEffect(() => { + const input = canonicalize(text()); if (!config()?.romanization) return; - const input = canonicalize(text()); romanize(input).then((result) => { setRomanization(canonicalize(result)); }); }); return ( - - } - when={text()} - > + } when={text()}>
{ diff --git a/src/plugins/synced-lyrics/types.ts b/src/plugins/synced-lyrics/types.ts index 37686222..7afe2c47 100644 --- a/src/plugins/synced-lyrics/types.ts +++ b/src/plugins/synced-lyrics/types.ts @@ -4,7 +4,7 @@ export type SyncedLyricsPluginConfig = { enabled: boolean; preciseTiming: boolean; showTimeCodes: boolean; - defaultTextString: string; + defaultTextString: string | string[]; showLyricsEvenIfInexact: boolean; lineEffect: LineEffect; romanization: boolean;