From b69cd60bdb60d8d4ffe1ff93af621dc971374557 Mon Sep 17 00:00:00 2001 From: HKLHaoBin Date: Fri, 24 Apr 2026 01:26:16 +0800 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=E5=BB=B6?= =?UTF-8?q?=E8=BF=9F=E6=B5=8B=E8=AF=95=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加一个新的延迟测试对话框,通过在可配置的 BPM 鸣响时点击来测量输入延迟。包括热键绑定、偏好设置以及在时间偏移组中的 UI 集成。支持应用当前或平均延迟值。 --- src/core/hotkey/schema.ts | 2 + src/core/pref/schema.ts | 2 + src/i18n/en/index.ts | 17 + src/i18n/i18n-types.ts | 85 +++ src/i18n/zh-hans/index.ts | 17 + .../dialogComponents/DelayTestDialog.vue | 501 ++++++++++++++++++ .../dialogComponents/KeyBindingDialog.vue | 1 + src/ui/dialogs/index.ts | 3 + src/ui/ribbon/groups/TimeShiftGroup.vue | 5 +- 9 files changed, 631 insertions(+), 2 deletions(-) create mode 100644 src/ui/dialogs/dialogComponents/DelayTestDialog.vue diff --git a/src/core/hotkey/schema.ts b/src/core/hotkey/schema.ts index 53012a2..29854ea 100644 --- a/src/core/hotkey/schema.ts +++ b/src/core/hotkey/schema.ts @@ -53,6 +53,7 @@ export const hotkeyCommandList = [ 'playPauseAudio', 'seekForward', 'volumeDown', + 'delayTestTap', 'copy', 'cut', @@ -96,6 +97,7 @@ export const getDefaultHotkeyMap = () => seekForward: k('ArrowRight'), volumeUp: k('ArrowUp'), volumeDown: k('ArrowDown'), + delayTestTap: k('Space'), undo: k(Ctrl, 'z'), redo: [k(Ctrl, 'y'), k(Ctrl, Shift, 'z')], find: k(Ctrl, 'f'), diff --git a/src/core/pref/schema.ts b/src/core/pref/schema.ts index b67d7ac..30d60fd 100644 --- a/src/core/pref/schema.ts +++ b/src/core/pref/schema.ts @@ -15,6 +15,7 @@ export interface PreferenceSchema { macStyleShortcuts: boolean hotkeyMap: HotKey.Map audioSeekingStepMs: number + latencyTestBpm: number // Timing globalLatencyMs: number alwaysIgnoreBackground: boolean @@ -43,6 +44,7 @@ export const getDefaultPref = (): PreferenceSchema => ({ macStyleShortcuts: isAppleDevice(), hotkeyMap: getDefaultHotkeyMap(), audioSeekingStepMs: 5000, + latencyTestBpm: 120, globalLatencyMs: 0, alwaysIgnoreBackground: false, hideLineTiming: true, diff --git a/src/i18n/en/index.ts b/src/i18n/en/index.ts index fb51ef9..3f00e42 100644 --- a/src/i18n/en/index.ts +++ b/src/i18n/en/index.ts @@ -160,6 +160,7 @@ const en = { timeShift: { groupLabel: 'Time Shift', delayTest: 'Delay Test', + delayTestDesc: 'Open the latency test dialog to measure tap timing against the beep track.', delay: 'Delay', batchTimeShift: 'Batch Shift', batchTimeShiftDesc: @@ -613,6 +614,7 @@ const en = { playPauseAudio: 'Play / Pause', seekForward: 'Seek Forward', volumeDown: 'Volume Down', + delayTestTap: 'Delay Test Tap', }, keyNames: { space: 'Space', @@ -741,6 +743,21 @@ const en = { applyToLine: 'Apply to Selected Lines', applyToAll: 'Apply to All', }, + delayTestDialog: { + header: 'Delay Test', + description: 'Press the configured key on every beep to measure input latency.', + tapHint: 'Press', + bpmLabel: 'BPM', + signHint: 'Positive = early, negative = late', + current: 'Current', + fastest: 'Fastest', + slowest: 'Slowest', + noSamples: 'No taps yet', + start: 'Start', + stop: 'Stop', + applyCurrent: 'Apply Current', + applyAverage: 'Apply Average', + }, consoleArt, } as const satisfies Translations diff --git a/src/i18n/i18n-types.ts b/src/i18n/i18n-types.ts index 0da6a49..16c6f50 100644 --- a/src/i18n/i18n-types.ts +++ b/src/i18n/i18n-types.ts @@ -423,6 +423,10 @@ type RootTranslation = { * 延​迟​测​试 */ delayTest: string + /** + * 打​开​延​迟​测​试​对​话​框​,​测​量​按​键​与​蜂​鸣​之​间​的​延​迟​。 + */ + delayTestDesc: string /** * 延​迟 */ @@ -1768,6 +1772,10 @@ type RootTranslation = { * 减​小​音​量 */ volumeDown: string + /** + * 延​迟​测​试​按​键 + */ + delayTestTap: string } keyNames: { /** @@ -2098,6 +2106,60 @@ type RootTranslation = { */ applyToAll: string } + delayTestDialog: { + /** + * 延​迟​测​试 + */ + header: string + /** + * 在​每​次​蜂​鸣​时​按​下​配​置​的​按​键​,​以​测​量​输​入​延​迟​。 + */ + description: string + /** + * 按​下 + */ + tapHint: string + /** + * B​P​M + */ + bpmLabel: string + /** + * 正​值​表​示​更​快​,​负​值​表​示​更​慢 + */ + signHint: string + /** + * 当​前 + */ + current: string + /** + * 最​快 + */ + fastest: string + /** + * 最​慢 + */ + slowest: string + /** + * 尚​无​按​键​记​录 + */ + noSamples: string + /** + * 开​始 + */ + start: string + /** + * 结​束 + */ + stop: string + /** + * 应​用​当​前​值 + */ + applyCurrent: string + /** + * 应​用​平​均​值 + */ + applyAverage: string + } /** * ╭​─​─​─​─​─​─​─​─​─​─​╮​ ​ ​ ​ ​ ​ ​ ​╶​╴​ ​ ​ ​ ​┌​─​╴​ ​ ​╶​─​┐​┌​─​┐​ ​ ​ ​ ​┌​─​┐​ ​ ​ ​ ​ ​ ​┌​─​─​─​─​─​┐​ ​ ​ ​ ​┌​─​┐​┌​─​┐​ ​│​ ​━​━​━​━​━​━​ ​ ​ ​│​ ​ ​ ​ ​ ​ ​╱​ ​ ​╲​ ​ ​ ​│​ ​ ​╲​╱​ ​ ​│​│​ ​│​ ​ ​ ​ ​│​ ​│​ ​ ​ ​ ​ ​ ​│​ ​┌​─​─​─​┘​ ​ ​ ​ ​│​ ​│​└​─​┘​┌​─​┐​ @@ -2529,6 +2591,10 @@ export type TranslationFunctions = { * 延迟测试 */ delayTest: () => LocalizedString + /** + * 打开延迟测试对话框,测量按键与蜂鸣之间的延迟。 + */ + delayTestDesc: () => LocalizedString /** * 延迟 */ @@ -3870,6 +3936,10 @@ export type TranslationFunctions = { * 减小音量 */ volumeDown: () => LocalizedString + /** + * 延迟测试按键 + */ + delayTestTap: () => LocalizedString } keyNames: { /** @@ -4199,6 +4269,21 @@ export type TranslationFunctions = { */ applyToAll: () => LocalizedString } + delayTestDialog: { + header: () => LocalizedString + description: () => LocalizedString + tapHint: () => LocalizedString + bpmLabel: () => LocalizedString + signHint: () => LocalizedString + current: () => LocalizedString + fastest: () => LocalizedString + slowest: () => LocalizedString + noSamples: () => LocalizedString + start: () => LocalizedString + stop: () => LocalizedString + applyCurrent: () => LocalizedString + applyAverage: () => LocalizedString + } /** * ╭──────────╮ ╶╴ ┌─╴ ╶─┐┌─┐ ┌─┐ ┌─────┐ ┌─┐┌─┐ │ ━━━━━━ │ ╱ ╲ │ ╲╱ ││ │ │ │ │ ┌───┘ │ │└─┘┌─┐ diff --git a/src/i18n/zh-hans/index.ts b/src/i18n/zh-hans/index.ts index 012eb5f..a419ca2 100644 --- a/src/i18n/zh-hans/index.ts +++ b/src/i18n/zh-hans/index.ts @@ -156,6 +156,7 @@ const zhHans = { timeShift: { groupLabel: '时移', delayTest: '延迟测试', + delayTestDesc: '打开延迟测试对话框,测量按键与蜂鸣之间的延迟。', delay: '延迟', batchTimeShift: '批量时移', batchTimeShiftDesc: '打开批量时移对话框,调整多个音节或行的时间戳。', @@ -591,6 +592,7 @@ const zhHans = { playPauseAudio: '播放/暂停音频', seekForward: '快进', volumeDown: '减小音量', + delayTestTap: '延迟测试按键', }, keyNames: { space: '空格', @@ -717,6 +719,21 @@ const zhHans = { applyToLine: '应用到选定行', applyToAll: '应用到全文', }, + delayTestDialog: { + header: '延迟测试', + description: '在每次蜂鸣时按下配置的按键,以测量输入延迟。', + tapHint: '按下', + bpmLabel: 'BPM', + signHint: '正值表示更快,负值表示更慢', + current: '当前', + fastest: '最快', + slowest: '最慢', + noSamples: '尚无按键记录', + start: '开始', + stop: '结束', + applyCurrent: '应用当前值', + applyAverage: '应用平均值', + }, consoleArt, } satisfies BaseTranslation diff --git a/src/ui/dialogs/dialogComponents/DelayTestDialog.vue b/src/ui/dialogs/dialogComponents/DelayTestDialog.vue new file mode 100644 index 0000000..0398d7d --- /dev/null +++ b/src/ui/dialogs/dialogComponents/DelayTestDialog.vue @@ -0,0 +1,501 @@ + + + + + diff --git a/src/ui/dialogs/dialogComponents/KeyBindingDialog.vue b/src/ui/dialogs/dialogComponents/KeyBindingDialog.vue index 3a55e1d..4c6e60b 100644 --- a/src/ui/dialogs/dialogComponents/KeyBindingDialog.vue +++ b/src/ui/dialogs/dialogComponents/KeyBindingDialog.vue @@ -109,6 +109,7 @@ const groupedCmdList = [ 'playPauseAudio', 'seekForward', 'volumeDown', + 'delayTestTap', ], }, ] as const satisfies { diff --git a/src/ui/dialogs/index.ts b/src/ui/dialogs/index.ts index 61f517e..a96e5fa 100644 --- a/src/ui/dialogs/index.ts +++ b/src/ui/dialogs/index.ts @@ -3,6 +3,7 @@ import type { Component } from 'vue' import type { ValueOf } from '@utils/types' import AboutDialog from './dialogComponents/AboutDialog.vue' +import DelayTestDialog from './dialogComponents/DelayTestDialog.vue' import BatchTimeShiftDialog from './dialogComponents/BatchTimeShiftDialog.vue' import CompatibilityDialog from './dialogComponents/CompatibilityDialog.vue' import FindReplaceDialog from './dialogComponents/FindReplaceDialog.vue' @@ -11,6 +12,7 @@ import FromTextModal from './dialogComponents/FromTextModal.vue' import KeyBindingDialog from './dialogComponents/KeyBindingDialog.vue' export const DialogKey = { + DelayTest: 'delayTest', BatchTimeShift: 'batchTimeShift', FindReplace: 'findReplace', KeyBinding: 'keyBinding', @@ -27,6 +29,7 @@ interface DialogReg { } export const dialogRegs: DialogReg[] = [ + { key: DialogKey.DelayTest, component: DelayTestDialog }, { key: DialogKey.BatchTimeShift, component: BatchTimeShiftDialog }, { key: DialogKey.FindReplace, component: FindReplaceDialog }, { key: DialogKey.KeyBinding, component: KeyBindingDialog }, diff --git a/src/ui/ribbon/groups/TimeShiftGroup.vue b/src/ui/ribbon/groups/TimeShiftGroup.vue index 5505795..4508ef6 100644 --- a/src/ui/ribbon/groups/TimeShiftGroup.vue +++ b/src/ui/ribbon/groups/TimeShiftGroup.vue @@ -4,8 +4,9 @@ icon="mdi mdi-timer-music-outline" :label="tt.delayTest()" size="small" - severity="secondary" - disabled + :severity="runtimeStore.dialogShown.delayTest ? undefined : 'secondary'" + @click="runtimeStore.dialogShown.delayTest = !runtimeStore.dialogShown.delayTest" + v-tooltip="tipDesc(tt.delayTest(), tt.delayTestDesc(), 'delayTestTap')" />
{{ tt.delay() }} From 5faf3a525b2266a228faa1ebb98a71ed06901597 Mon Sep 17 00:00:00 2001 From: HKLHaoBin Date: Fri, 24 Apr 2026 01:40:48 +0800 Subject: [PATCH 2/8] =?UTF-8?q?feat(i18n):=20=E4=B8=BA=E5=BB=B6=E8=BF=9F?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=B7=BB=E5=8A=A0=20BPM=20=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在英文和中文中为延迟测试 BPM 设置添加新的本地化键值。 --- src/i18n/en/index.ts | 2 ++ src/i18n/i18n-types.ts | 48 ++++++++++++++++++++++++++------------- src/i18n/zh-hans/index.ts | 2 ++ 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/i18n/en/index.ts b/src/i18n/en/index.ts index 3f00e42..97c6d99 100644 --- a/src/i18n/en/index.ts +++ b/src/i18n/en/index.ts @@ -288,6 +288,8 @@ const en = { macStyleShortcutsDesc: 'Display shortcuts using ⌘, ⌥ symbols etc.', audioSeekingStepMs: 'Seek step size', audioSeekingStepMsDesc: 'Time to jump when using hotkeys (ms)', + latencyTestBpm: 'Delay test BPM', + latencyTestBpmDesc: 'Beep rate used by the latency test dialog', swapTranslateRoman: 'Swap translation & romanization panels', swapTranslateRomanDesc: 'Place romanization panel on the left', hideTranslateRoman: 'Hide translation & romanization panels', diff --git a/src/i18n/i18n-types.ts b/src/i18n/i18n-types.ts index 16c6f50..cf86c33 100644 --- a/src/i18n/i18n-types.ts +++ b/src/i18n/i18n-types.ts @@ -832,14 +832,22 @@ type RootTranslation = { * 音​频​按​键​跳​转​步​长 */ audioSeekingStepMs: string - /** - * 按​键​快​进​或​快​退​时​跳​转​的​时​长​ ​(​毫​秒​) - */ - audioSeekingStepMsDesc: string - /** - * 交​换​翻​译​与​音​译​框​位​置 - */ - swapTranslateRoman: string + /** + * 按​键​快​进​或​快​退​时​跳​转​的​时​长​ ​(​毫​秒​) + */ + audioSeekingStepMsDesc: string + /** + * 延​迟​测​试​ ​B​P​M + */ + latencyTestBpm: string + /** + * 延​迟​测​试​对​话​框​使​用​的​蜂​鸣​节​拍 + */ + latencyTestBpmDesc: string + /** + * 交​换​翻​译​与​音​译​框​位​置 + */ + swapTranslateRoman: string /** * 在​内​容​视​图​将​音​译​框​置​于​左​侧​,​并​影​响​查​找​顺​序 */ @@ -3000,14 +3008,22 @@ export type TranslationFunctions = { * 音频按键跳转步长 */ audioSeekingStepMs: () => LocalizedString - /** - * 按键快进或快退时跳转的时长 (毫秒) - */ - audioSeekingStepMsDesc: () => LocalizedString - /** - * 交换翻译与音译框位置 - */ - swapTranslateRoman: () => LocalizedString + /** + * 按键快进或快退时跳转的时长 (毫秒) + */ + audioSeekingStepMsDesc: () => LocalizedString + /** + * 延迟测试 BPM + */ + latencyTestBpm: () => LocalizedString + /** + * 延迟测试对话框使用的蜂鸣节拍 + */ + latencyTestBpmDesc: () => LocalizedString + /** + * 交换翻译与音译框位置 + */ + swapTranslateRoman: () => LocalizedString /** * 在内容视图将音译框置于左侧,并影响查找顺序 */ diff --git a/src/i18n/zh-hans/index.ts b/src/i18n/zh-hans/index.ts index a419ca2..605f211 100644 --- a/src/i18n/zh-hans/index.ts +++ b/src/i18n/zh-hans/index.ts @@ -279,6 +279,8 @@ const zhHans = { macStyleShortcutsDesc: '使用 ⌘、⌥ 等符号展示组合键', audioSeekingStepMs: '音频按键跳转步长', audioSeekingStepMsDesc: '按键快进或快退时跳转的时长 (毫秒)', + latencyTestBpm: '延迟测试 BPM', + latencyTestBpmDesc: '延迟测试对话框使用的蜂鸣节拍', swapTranslateRoman: '交换翻译与音译框位置', swapTranslateRomanDesc: '在内容视图将音译框置于左侧,并影响查找顺序', hideTranslateRoman: '隐藏翻译音译框', From ca542c6aba97203c0295a7a77cf3f20a4fb3a141 Mon Sep 17 00:00:00 2001 From: HKLHaoBin Date: Fri, 24 Apr 2026 01:49:20 +0800 Subject: [PATCH 3/8] refactor(i18n): restructure and expand localization types for delay test dialog Adjust indentation and add new keys for delay test dialog components, including header, description, and control labels. --- src/i18n/i18n-types.ts | 103 ++++++++++++++++++++++++++++------------- 1 file changed, 71 insertions(+), 32 deletions(-) diff --git a/src/i18n/i18n-types.ts b/src/i18n/i18n-types.ts index cf86c33..5088f16 100644 --- a/src/i18n/i18n-types.ts +++ b/src/i18n/i18n-types.ts @@ -832,22 +832,22 @@ type RootTranslation = { * 音​频​按​键​跳​转​步​长 */ audioSeekingStepMs: string - /** - * 按​键​快​进​或​快​退​时​跳​转​的​时​长​ ​(​毫​秒​) - */ - audioSeekingStepMsDesc: string - /** - * 延​迟​测​试​ ​B​P​M - */ - latencyTestBpm: string - /** - * 延​迟​测​试​对​话​框​使​用​的​蜂​鸣​节​拍 - */ - latencyTestBpmDesc: string - /** - * 交​换​翻​译​与​音​译​框​位​置 - */ - swapTranslateRoman: string + /** + * 按​键​快​进​或​快​退​时​跳​转​的​时​长​ ​(​毫​秒​) + */ + audioSeekingStepMsDesc: string + /** + * 延​迟​测​试​ ​B​P​M + */ + latencyTestBpm: string + /** + * 延​迟​测​试​对​话​框​使​用​的​蜂​鸣​节​拍 + */ + latencyTestBpmDesc: string + /** + * 交​换​翻​译​与​音​译​框​位​置 + */ + swapTranslateRoman: string /** * 在​内​容​视​图​将​音​译​框​置​于​左​侧​,​并​影​响​查​找​顺​序 */ @@ -3008,22 +3008,22 @@ export type TranslationFunctions = { * 音频按键跳转步长 */ audioSeekingStepMs: () => LocalizedString - /** - * 按键快进或快退时跳转的时长 (毫秒) - */ - audioSeekingStepMsDesc: () => LocalizedString - /** - * 延迟测试 BPM - */ - latencyTestBpm: () => LocalizedString - /** - * 延迟测试对话框使用的蜂鸣节拍 - */ - latencyTestBpmDesc: () => LocalizedString - /** - * 交换翻译与音译框位置 - */ - swapTranslateRoman: () => LocalizedString + /** + * 按键快进或快退时跳转的时长 (毫秒) + */ + audioSeekingStepMsDesc: () => LocalizedString + /** + * 延迟测试 BPM + */ + latencyTestBpm: () => LocalizedString + /** + * 延迟测试对话框使用的蜂鸣节拍 + */ + latencyTestBpmDesc: () => LocalizedString + /** + * 交换翻译与音译框位置 + */ + swapTranslateRoman: () => LocalizedString /** * 在内容视图将音译框置于左侧,并影响查找顺序 */ @@ -4286,18 +4286,57 @@ export type TranslationFunctions = { applyToAll: () => LocalizedString } delayTestDialog: { + /** + * 延迟测试 + */ header: () => LocalizedString + /** + * 在每次蜂鸣时按下配置的按键,以测量输入延迟。 + */ description: () => LocalizedString + /** + * 按下 + */ tapHint: () => LocalizedString + /** + * BPM + */ bpmLabel: () => LocalizedString + /** + * 正值表示更快,负值表示更慢 + */ signHint: () => LocalizedString + /** + * 当前 + */ current: () => LocalizedString + /** + * 最快 + */ fastest: () => LocalizedString + /** + * 最慢 + */ slowest: () => LocalizedString + /** + * 尚无按键记录 + */ noSamples: () => LocalizedString + /** + * 开始 + */ start: () => LocalizedString + /** + * 结束 + */ stop: () => LocalizedString + /** + * 应用当前值 + */ applyCurrent: () => LocalizedString + /** + * 应用平均值 + */ applyAverage: () => LocalizedString } /** From 8e2062b7a7a2e0f17f9dd32582fc2faa91e464f6 Mon Sep 17 00:00:00 2001 From: HKLHaoBin Date: Fri, 24 Apr 2026 01:56:38 +0800 Subject: [PATCH 4/8] =?UTF-8?q?feat(ui):=20=E4=B8=BA=E5=BB=B6=E8=BF=9F?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=AF=B9=E8=AF=9D=E6=A1=86=E5=BC=95=E5=85=A5?= =?UTF-8?q?=E6=B5=85=E8=89=B2/=E6=B7=B1=E8=89=B2=E9=A2=9C=E8=89=B2?= =?UTF-8?q?=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 CSS 自定义属性以支持浅色和深色模式主题,使用动态变量替换硬编码颜色,以提高一致性和可访问性。 --- .../dialogComponents/DelayTestDialog.vue | 50 ++++++++++++++----- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/src/ui/dialogs/dialogComponents/DelayTestDialog.vue b/src/ui/dialogs/dialogComponents/DelayTestDialog.vue index 0398d7d..7fda80d 100644 --- a/src/ui/dialogs/dialogComponents/DelayTestDialog.vue +++ b/src/ui/dialogs/dialogComponents/DelayTestDialog.vue @@ -368,6 +368,18 @@ onUnmounted(() => {