fix(desktop): macOS 단축키 표기 (Win/Ctrl/Alt → ⌘/⌃/⌥/⇧)
기존: HotkeyRecordModal에서 키 녹화 시 'Win+Shift+1' 같은 정적 displayLabel 저장
- KEY_DISPLAY_MAP이 Windows 전용 (91/92 → 'Win')
- SettingsModal HotkeyDisplay가 binding.displayLabel.split(' + ')로 chip 분리
- 그런데 displayLabel은 join('+') (space 없음) — split이 작동 안 해서 단일 chip 'Win+Shift+1'
- macOS에서도 'Win'으로 표시되어 사용자 혼동
수정:
- preload/index.ts: process.platform 노출 (electronAPI.platform)
- renderer/utils/format-hotkey.ts 신규
- formatHotkeySegments(binding) → 플랫폼별 segment 배열
- macOS: ['⌘', '⇧', '1'] (⌃ ⌥ ⇧ ⌘ 순, Apple HIG)
- Win/Linux: ['Ctrl', 'Win', 'Alt', 'Shift', '1']
- formatHotkeyLabel(binding) → 단일 문자열
- macOS: '⌘⇧1' (구분자 없음, Apple 표준)
- Win/Linux: 'Ctrl + Shift + 1'
- 사용 위치 일괄 교체 (binding.displayLabel → format 헬퍼):
- SettingsModal HotkeyDisplay (chip 표시)
- SettingsModal Agent 모드 설명 ({{key}} 치환)
- OnboardingModal 단축키 chip + 완료 화면
- DashboardPage CrtDisplay 'PRESS X TO RECORD'
- HotkeyRecordModal currentBinding 표시
displayLabel 필드는 ConfigService 호환을 위해 유지 (저장된 값은 그대로)
This commit is contained in:
parent
07c6d13c99
commit
0d17b71866
6 changed files with 135 additions and 8 deletions
|
|
@ -18,6 +18,7 @@ import {
|
|||
import { d3roPalette } from '@d3ro/ui/theme'
|
||||
import { useI18n } from '@d3ro/i18n'
|
||||
import type { HotkeyBinding } from '@d3ro/core/types'
|
||||
import { formatHotkeyLabel } from '../utils/format-hotkey'
|
||||
|
||||
// ── 키 이름 매핑 (Windows) ──────────────────────────────
|
||||
const KEY_DISPLAY_MAP: Record<number, string> = {
|
||||
|
|
@ -302,7 +303,7 @@ export function HotkeyRecordModal({
|
|||
|
||||
{currentBinding && (
|
||||
<Typography sx={{ color: d3roPalette.text.inactive, fontSize: '12px', mt: 2 }}>
|
||||
{t('hotkey.current', { keys: currentBinding.displayLabel })}
|
||||
{t('hotkey.current', { keys: formatHotkeyLabel(currentBinding) })}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import OpenInNewIcon from '@mui/icons-material/OpenInNew'
|
|||
import { d3roPalette, d3roFontMono, d3roShadow } from '@d3ro/ui/theme'
|
||||
import { Led } from '@d3ro/ui/components/ds'
|
||||
import { HotkeyRecordModal } from './HotkeyRecordModal'
|
||||
import { formatHotkeyLabel, formatHotkeySegments } from '../utils/format-hotkey'
|
||||
import { useI18n } from '@d3ro/i18n'
|
||||
import type { HotkeyBinding, AudioDevice } from '@d3ro/core/types'
|
||||
|
||||
|
|
@ -167,9 +168,9 @@ export function OnboardingModal({ open, onClose }: OnboardingModalProps): React.
|
|||
{hotkeyBinding ? (
|
||||
<Stack direction="row" spacing={1} justifyContent="center" alignItems="center">
|
||||
<Led color="green" size={8} />
|
||||
{hotkeyBinding.displayLabel.split(' + ').map((key) => (
|
||||
{formatHotkeySegments(hotkeyBinding).map((key, idx) => (
|
||||
<Chip
|
||||
key={key}
|
||||
key={`${key}-${idx}`}
|
||||
label={key}
|
||||
sx={{
|
||||
fontFamily: d3roFontMono,
|
||||
|
|
@ -247,7 +248,7 @@ export function OnboardingModal({ open, onClose }: OnboardingModalProps): React.
|
|||
</Typography>
|
||||
<Typography variant="body2" sx={{ color: d3roPalette.text.secondary, mb: 4 }}>
|
||||
{hotkeyBinding
|
||||
? t('onboarding.done.descWithKey', { key: hotkeyBinding.displayLabel })
|
||||
? t('onboarding.done.descWithKey', { key: formatHotkeyLabel(hotkeyBinding) })
|
||||
: t('onboarding.done.descNoKey')}
|
||||
</Typography>
|
||||
<Button variant="contained" onClick={handleFinish} fullWidth>
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import CheckCircleIcon from '@mui/icons-material/CheckCircle'
|
|||
import CancelIcon from '@mui/icons-material/Cancel'
|
||||
import { d3roPalette, d3roFontMono, d3roShadow } from '@d3ro/ui/theme'
|
||||
import { HotkeyRecordModal } from './HotkeyRecordModal'
|
||||
import { formatHotkeyLabel, formatHotkeySegments } from '../utils/format-hotkey'
|
||||
import { LicenseTab } from './LicenseTab'
|
||||
import { CloudSyncSection } from './CloudSyncSection'
|
||||
import { useI18n, LOCALE_META } from '@d3ro/i18n'
|
||||
|
|
@ -76,9 +77,9 @@ function HotkeyDisplay({
|
|||
</Typography>
|
||||
{binding ? (
|
||||
<Stack direction="row" spacing={0.5} alignItems="center">
|
||||
{binding.displayLabel.split(' + ').map((key) => (
|
||||
{formatHotkeySegments(binding).map((key, idx) => (
|
||||
<Chip
|
||||
key={key}
|
||||
key={`${key}-${idx}`}
|
||||
label={key}
|
||||
size="small"
|
||||
sx={{
|
||||
|
|
@ -407,7 +408,7 @@ export function SettingsModal({ open, onClose }: SettingsModalProps): React.Reac
|
|||
title={t('settings.agent')}
|
||||
description={
|
||||
dictationBinding
|
||||
? t('settings.agent.descWithKey', { key: dictationBinding.displayLabel })
|
||||
? t('settings.agent.descWithKey', { key: formatHotkeyLabel(dictationBinding) })
|
||||
: t('settings.agent.descNoKey')
|
||||
}
|
||||
enabled={dictationEnabled}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue