| | |
| | | import { hotkeyVK } from '../../lib/stores/config' |
| | | import { hotkeyName } from '../../lib/stores/indicator' |
| | | |
| | | let currentKeyName = $state('Ctrl') |
| | | let currentKeyName = $state('') |
| | | let isRecording = $state(false) |
| | | let hintText = $state('') |
| | | let activeKeyHandler: ((e: KeyboardEvent) => void) | null = null |
| | |
| | | e.preventDefault() |
| | | e.stopPropagation() |
| | | |
| | | if (isHotkeyCaptureCancel(e)) { |
| | | hintText = t('status.cancelled') |
| | | clearHotkeyCapture() |
| | | return |
| | | } |
| | | |
| | | const vk = mapKeyToVK(e) |
| | | if (vk > 0) { |
| | | isRecording = false |
| | |
| | | try { |
| | | await Call.ByName('voicesnap/services.HotkeyService.SetHotkey', vk) |
| | | const name: any = await Call.ByName('voicesnap/services.HotkeyService.GetKeyName', vk) |
| | | if (name) { |
| | | if (typeof name === 'string') { |
| | | hotkeyName.set(name) |
| | | currentKeyName = name |
| | | } |
| | |
| | | |
| | | activeKeyHandler = onKey |
| | | document.addEventListener('keydown', onKey) |
| | | } |
| | | |
| | | function isHotkeyCaptureCancel(e: KeyboardEvent): boolean { |
| | | return e.key === 'Escape' || e.key === 'Esc' |
| | | } |
| | | |
| | | function clearHotkeyCapture() { |
| | |
| | | <div class="hotkey-display"> |
| | | <div class="hotkey-info"> |
| | | <span class="hotkey-label">{t('hotkeys.current')}</span> |
| | | <div class="hotkey-key" class:recording={isRecording}> |
| | | {isRecording ? '...' : currentKeyName} |
| | | <div class="hotkey-key" class:recording={isRecording} class:unset={!isRecording && !currentKeyName}> |
| | | {isRecording ? '...' : (currentKeyName || t('hotkeys.unset'))} |
| | | </div> |
| | | </div> |
| | | <button class="change-btn" onclick={startRecordingHotkey} disabled={isRecording}> |
| | | {t('hotkeys.change')} |
| | | {currentKeyName ? t('hotkeys.change') : t('hotkeys.set')} |
| | | </button> |
| | | </div> |
| | | |
| | | {#if !currentKeyName && !isRecording} |
| | | <p class="hint">{t('hotkeys.unsetDesc')}</p> |
| | | {/if} |
| | | |
| | | {#if hintText} |
| | | <p class="hint" class:recording={isRecording}>{hintText}</p> |
| | |
| | | animation: pulse 1s infinite; |
| | | } |
| | | |
| | | .hotkey-key.unset { |
| | | color: var(--color-secondary-label); |
| | | font-size: var(--font-size-base); |
| | | font-weight: 500; |
| | | } |
| | | |
| | | @keyframes pulse { |
| | | 0%, 100% { opacity: 1; } |
| | | 50% { opacity: 0.5; } |