Skip to content

Commit b6273be

Browse files
committed
Merge feat/redesign-three-pages into main
2 parents 5b50634 + 6df87b1 commit b6273be

23 files changed

Lines changed: 1854 additions & 928 deletions

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,10 @@ temp-docs/
3232
# Website (官网子项目)
3333
website/node_modules/
3434
website/dist/
35+
36+
# Agent / 设计工具产物(本地工具,不入产品仓库)
37+
.agents/
38+
.claude/
39+
designs/
40+
skills-lock.json
41+
systemprompt.txt

electron/shared/locales/en.json

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
{
22
"app": {
33
"name": "Voice Key",
4+
"tagline": "Speak to type",
45
"version": "Version {{version}}"
56
},
7+
"theme": {
8+
"light": "Light",
9+
"dark": "Dark"
10+
},
611
"nav": {
712
"home": "Home",
813
"settings": "Settings",
@@ -18,15 +23,30 @@
1823
},
1924
"home": {
2025
"title": "Speak naturally, write perfectly",
21-
"subtitle": "Hold down <kbd>{{hotkey}}</kbd>, speak, and let go to insert spoken text.",
26+
"eyebrow": "Overview",
27+
"subtitle": "Hold the hotkey and speak — let go to inject the text at your cursor.",
28+
"charUnit": "chars",
29+
"recent7": "Last 7 days",
30+
"greeting": {
31+
"morning": "Good morning",
32+
"afternoon": "Good afternoon",
33+
"evening": "Good evening",
34+
"night": "Working late"
35+
},
36+
"hero": {
37+
"standby": "Ready to listen",
38+
"holdToTalk": "Hold to talk",
39+
"holdHint": "Hold the key in any app — speak, and get text"
40+
},
2241
"stats": {
2342
"totalCharacters": "Total characters recognized",
2443
"totalAudio": "Total audio duration",
2544
"recentChange": "+{{value}} in {{range}}",
2645
"todaySessions": "Today's sessions",
2746
"todayDuration": "Today's duration",
28-
"todayCharacters": "Today's input",
47+
"todayCharacters": "Today's characters",
2948
"activeDays": "Active days",
49+
"activeDaysHint": "Days you dictated",
3050
"peakDay": "Peak day",
3151
"peakDayValue": "{{date}} · {{value}} chars"
3252
},
@@ -43,6 +63,7 @@
4363
"description": "Characters recognized in the selected range",
4464
"ariaLabel": "Recognition volume trend",
4565
"seriesLabel": "Characters",
66+
"days": "{{count}}d",
4667
"rangeSelectAriaLabel": "Select time range",
4768
"rangePlaceholder": "Last 3 months"
4869
},
@@ -61,6 +82,24 @@
6182
},
6283
"settings": {
6384
"title": "Settings",
85+
"eyebrow": "Preferences",
86+
"subtitle": "Configure speech recognition, refine & translation, and hotkeys — changes save automatically.",
87+
"descGeneral": "Language and startup",
88+
"descAsr": "GLM ASR · turn speech into text",
89+
"descRefine": "Shares one LLM connection",
90+
"descLogs": "For troubleshooting",
91+
"connectionTitle": "Connection",
92+
"aboutHint": "Stay up to date for the best experience",
93+
"health": {
94+
"asr": "Speech recognition",
95+
"asrOn": "Key configured",
96+
"asrOff": "Not configured",
97+
"refine": "Refinement",
98+
"refineOn": "Ready",
99+
"refineOff": "Incomplete",
100+
"translation": "Translation",
101+
"translationOff": "Off"
102+
},
64103
"about": "About Voice Key",
65104
"version": "Current Version: v{{version}}",
66105
"checkUpdate": "Check for Updates",
@@ -223,6 +262,16 @@
223262
},
224263
"history": {
225264
"title": "History",
265+
"eyebrow": "Dictation history",
266+
"clearTitle": "Clear all",
267+
"groupCount_one": "{{formattedCount}} item",
268+
"groupCount_other": "{{formattedCount}} items",
269+
"detailPlaceholder": "Select a record on the left to read it in full",
270+
"detail": {
271+
"chars": "Characters",
272+
"duration": "Duration",
273+
"speed": "CPM"
274+
},
226275
"loading": "Loading...",
227276
"loadFailed": "Failed to load history",
228277
"searchPlaceholder": "Search history...",

electron/shared/locales/zh.json

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
{
22
"app": {
33
"name": "Voice Key",
4+
"tagline": "说出文字",
45
"version": "版本 {{version}}"
56
},
7+
"theme": {
8+
"light": "浅色",
9+
"dark": "深色"
10+
},
611
"nav": {
712
"home": "首页",
813
"settings": "设置",
@@ -18,15 +23,30 @@
1823
},
1924
"home": {
2025
"title": "自然说话,完美成文",
21-
"subtitle": "按住 <kbd>{{hotkey}}</kbd> 说话,松开即可插入文本。",
26+
"eyebrow": "概览",
27+
"subtitle": "按住快捷键说出文字,松开即把内容注入到光标处。",
28+
"charUnit": "",
29+
"recent7": "近 7 天",
30+
"greeting": {
31+
"morning": "早上好",
32+
"afternoon": "下午好",
33+
"evening": "晚上好",
34+
"night": "夜深了"
35+
},
36+
"hero": {
37+
"standby": "随时待命",
38+
"holdToTalk": "按住说话",
39+
"holdHint": "在任何应用里按住快捷键,说完即得文字"
40+
},
2241
"stats": {
2342
"totalCharacters": "识别字符总数",
2443
"totalAudio": "录音总时长",
2544
"recentChange": "{{range}} +{{value}}",
2645
"todaySessions": "今日录音",
2746
"todayDuration": "今日时长",
28-
"todayCharacters": "今日输入",
47+
"todayCharacters": "今日字数",
2948
"activeDays": "活跃天数",
49+
"activeDaysHint": "坚持用语音记录",
3050
"peakDay": "峰值日",
3151
"peakDayValue": "{{date}} · {{value}} 字"
3252
},
@@ -43,6 +63,7 @@
4363
"description": "所选时间范围内的识别字符数",
4464
"ariaLabel": "识别量趋势",
4565
"seriesLabel": "字符数",
66+
"days": "{{count}} 天",
4667
"rangeSelectAriaLabel": "选择时间范围",
4768
"rangePlaceholder": "最近 3 个月"
4869
},
@@ -61,6 +82,24 @@
6182
},
6283
"settings": {
6384
"title": "设置",
85+
"eyebrow": "偏好设置",
86+
"subtitle": "配置语音识别、润色翻译与快捷键,所有修改都会自动保存。",
87+
"descGeneral": "界面语言与启动方式",
88+
"descAsr": "GLM ASR · 把语音转成文字",
89+
"descRefine": "共用一套大模型连接",
90+
"descLogs": "排查问题时使用",
91+
"connectionTitle": "连接状态",
92+
"aboutHint": "保持更新以获得最佳体验",
93+
"health": {
94+
"asr": "语音识别",
95+
"asrOn": "已配置密钥",
96+
"asrOff": "未配置",
97+
"refine": "润色服务",
98+
"refineOn": "连接就绪",
99+
"refineOff": "未完成配置",
100+
"translation": "翻译",
101+
"translationOff": "未启用"
102+
},
64103
"about": "关于 Voice Key",
65104
"version": "当前版本:v{{version}}",
66105
"checkUpdate": "检查更新",
@@ -223,6 +262,16 @@
223262
},
224263
"history": {
225264
"title": "历史记录",
265+
"eyebrow": "听写历史",
266+
"clearTitle": "清空全部",
267+
"groupCount_one": "{{formattedCount}} 条",
268+
"groupCount_other": "{{formattedCount}} 条",
269+
"detailPlaceholder": "选择左侧的一条记录,在这里查看完整文字",
270+
"detail": {
271+
"chars": "字数",
272+
"duration": "时长",
273+
"speed": "字/分"
274+
},
226275
"loading": "加载中...",
227276
"loadFailed": "加载历史记录失败",
228277
"searchPlaceholder": "搜索历史记录...",

index.html

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,24 @@
55
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<title>Voice Key</title>
8+
<link rel="preconnect" href="https://fonts.googleapis.com" />
9+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
10+
<link
11+
href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap"
12+
rel="stylesheet"
13+
/>
14+
<script>
15+
// 在首帧前应用主题,避免闪烁
16+
try {
17+
var t = localStorage.getItem('vk-theme')
18+
if (
19+
t === 'dark' ||
20+
(t === null && window.matchMedia('(prefers-color-scheme: dark)').matches)
21+
) {
22+
document.documentElement.classList.add('dark')
23+
}
24+
} catch (e) {}
25+
</script>
826
</head>
927
<body>
1028
<div id="root"></div>

src/components/HotkeyKeys.tsx

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { cn } from '@/lib/utils'
2+
3+
const MAC_SYMBOLS: Record<string, string> = {
4+
Command: '⌘',
5+
Control: '⌃',
6+
Alt: '⌥',
7+
Shift: '⇧',
8+
Space: '空格',
9+
Enter: '↵',
10+
Escape: 'Esc',
11+
}
12+
13+
const WIN_SYMBOLS: Record<string, string> = {
14+
Command: 'Win',
15+
Control: 'Ctrl',
16+
Alt: 'Alt',
17+
Shift: 'Shift',
18+
Space: 'Space',
19+
Enter: 'Enter',
20+
Escape: 'Esc',
21+
}
22+
23+
interface HotkeyKeysProps {
24+
value: string
25+
className?: string
26+
}
27+
28+
/** 把 Electron Accelerator 字符串渲染成一组实体键帽。 */
29+
export function HotkeyKeys({ value, className }: HotkeyKeysProps) {
30+
const isMac = window.electronAPI?.platform === 'darwin'
31+
const symbols = isMac ? MAC_SYMBOLS : WIN_SYMBOLS
32+
const parts = (value || '').split('+').filter(Boolean)
33+
34+
if (parts.length === 0) {
35+
return <span className="text-muted-foreground text-xs">未设置</span>
36+
}
37+
38+
return (
39+
<span className={cn('inline-flex items-center gap-1', className)}>
40+
{parts.map((p, i) => (
41+
<kbd key={i} className={cn('vk-keycap', p === 'Space' && 'is-wide')}>
42+
{symbols[p] || p}
43+
</kbd>
44+
))}
45+
</span>
46+
)
47+
}

src/components/HotkeyRecorder.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ export function HotkeyRecorder({
156156
<div
157157
onClick={startRecording}
158158
className={cn(
159-
'flex-1 px-4 py-2.5 rounded-lg border cursor-pointer transition-all',
159+
'flex-1 px-4 py-2.5 rounded-lg border cursor-pointer transition-[background-color,border-color,box-shadow,color]',
160160
'bg-background text-foreground font-mono text-sm',
161161
'select-none',
162162
isRecording

src/components/HotkeySettings.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,17 @@ export function HotkeySettings({
126126
const filteredPresets = PTT_PRESETS.filter((p) => p.platform === 'all' || p.platform === platform)
127127

128128
return (
129-
<Card>
129+
<Card className="rounded-2xl">
130130
<CardHeader>
131-
<CardTitle className="flex items-center gap-2">
132-
<Keyboard className="w-5 h-5" />
133-
{t('hotkey.title')}
134-
</CardTitle>
135-
<CardDescription>{t('hotkey.description')}</CardDescription>
131+
<div className="flex items-center gap-3">
132+
<span className="grid h-9 w-9 shrink-0 place-items-center rounded-[10px] bg-accent text-accent-foreground">
133+
<Keyboard className="h-[18px] w-[18px]" />
134+
</span>
135+
<div>
136+
<CardTitle className="text-[15px]">{t('hotkey.title')}</CardTitle>
137+
<CardDescription className="mt-0.5 text-xs">{t('hotkey.description')}</CardDescription>
138+
</div>
139+
</div>
136140
</CardHeader>
137141

138142
<CardContent className="space-y-6">

0 commit comments

Comments
 (0)