Skip to content

Commit c431fcf

Browse files
Hotkey input
1 parent 9886f81 commit c431fcf

5 files changed

Lines changed: 166 additions & 119 deletions

File tree

src/renderer-app/src/components/onboarding/OnboardingHotkeyInput.vue

Lines changed: 51 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,29 @@
11
<template>
2-
<div class="hotkey-input-container">
3-
<div class="hotkey-input-wrapper" :class="{ focused: isFocused }">
4-
<input
5-
ref="inputRef"
6-
type="text"
7-
class="hotkey-input"
8-
:value="displayValue"
9-
@keydown="handleKeydown"
10-
@focus="handleFocus"
11-
@blur="handleBlur"
12-
:placeholder="placeholder"
13-
readonly
14-
/>
15-
<button
16-
v-if="modelValue"
17-
type="button"
18-
class="hotkey-clear-btn"
19-
@click="clearHotkey"
20-
title="Clear hotkey"
21-
>
22-
<i class="ph-duotone ph-x"></i>
23-
</button>
24-
</div>
25-
<div class="hotkey-hint" v-if="isFocused">
26-
Press your desired key combination
27-
</div>
2+
<div
3+
class="hotkey-input-wrapper"
4+
:class="{ focused: isFocused }"
5+
@click="$refs.inputRef.focus()"
6+
>
7+
<input
8+
ref="inputRef"
9+
type="text"
10+
class="hotkey-input"
11+
:value="displayValue"
12+
@keydown="handleKeydown"
13+
@focus="handleFocus"
14+
@blur="handleBlur"
15+
:placeholder="isFocused ? 'Press keys...' : placeholder"
16+
readonly
17+
/>
18+
<button
19+
v-if="modelValue"
20+
type="button"
21+
class="hotkey-clear-btn"
22+
@click.stop="clearHotkey"
23+
title="Clear"
24+
>
25+
<i class="ph-duotone ph-x"></i>
26+
</button>
2827
</div>
2928
</template>
3029

@@ -110,113 +109,90 @@ export default {
110109
</script>
111110

112111
<style scoped>
113-
.hotkey-input-container {
114-
display: flex;
115-
flex-direction: column;
116-
gap: 8px;
117-
width: 100%;
118-
max-width: 280px;
119-
}
120-
121112
.hotkey-input-wrapper {
122-
display: flex;
113+
display: inline-flex;
123114
align-items: center;
124-
gap: 8px;
125-
background: rgba(255, 255, 255, 0.9);
126-
border: 2px solid var(--border, #e6e6e6);
127-
border-radius: 10px;
128-
padding: 4px;
115+
background: rgba(255, 255, 255, 0.95);
116+
border: 1px solid var(--border, #e6e6e6);
117+
border-radius: 6px;
118+
padding: 0 4px 0 0;
129119
transition: all 0.2s ease;
120+
cursor: pointer;
130121
}
131122
132123
.hotkey-input-wrapper.focused {
133124
border-color: var(--accent, #007aff);
134-
box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.15);
125+
box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.12);
135126
}
136127
137128
.hotkey-input {
138-
flex: 1;
139-
padding: 12px 16px;
129+
width: 80px;
130+
padding: 6px 8px;
140131
border: none;
141132
background: transparent;
142133
font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", monospace;
143-
font-size: 14px;
134+
font-size: 12px;
144135
text-align: center;
145136
cursor: pointer;
146137
outline: none;
147138
color: var(--fg, #222222);
148139
}
149140
150141
.hotkey-input::placeholder {
151-
color: var(--muted, #666666);
152-
font-family: inherit;
153-
font-style: normal;
142+
color: var(--muted, #888888);
143+
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
144+
font-size: 10px;
154145
}
155146
156147
.hotkey-clear-btn {
157148
display: flex;
158149
align-items: center;
159150
justify-content: center;
160-
width: 32px;
161-
height: 32px;
151+
width: 18px;
152+
height: 18px;
162153
padding: 0;
163154
border: none;
164-
border-radius: 6px;
165-
background: rgba(255, 59, 48, 0.1);
155+
border-radius: 4px;
156+
background: rgba(255, 59, 48, 0.12);
166157
color: #ff3b30;
167158
cursor: pointer;
168159
transition: all 0.15s ease;
160+
flex-shrink: 0;
169161
}
170162
171163
.hotkey-clear-btn:hover {
172-
background: rgba(255, 59, 48, 0.2);
164+
background: rgba(255, 59, 48, 0.22);
173165
}
174166
175167
.hotkey-clear-btn i {
176-
font-size: 16px;
177-
}
178-
179-
.hotkey-hint {
180-
font-size: 11px;
181-
color: var(--accent, #007aff);
182-
text-align: center;
183-
animation: pulse-hint 1.5s ease-in-out infinite;
184-
}
185-
186-
@keyframes pulse-hint {
187-
0%, 100% {
188-
opacity: 1;
189-
}
190-
50% {
191-
opacity: 0.6;
192-
}
168+
font-size: 10px;
193169
}
194170
195171
@media (prefers-color-scheme: dark) {
196172
.hotkey-input-wrapper {
197-
background: rgba(255, 255, 255, 0.06);
198-
border-color: rgba(255, 255, 255, 0.12);
173+
background: rgba(255, 255, 255, 0.08);
174+
border-color: rgba(255, 255, 255, 0.15);
199175
}
200176
201177
.hotkey-input-wrapper.focused {
202178
border-color: var(--accent, #007aff);
203-
box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.25);
179+
box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.2);
204180
}
205181
206182
.hotkey-input {
207183
color: #ececec;
208184
}
209185
210186
.hotkey-input::placeholder {
211-
color: #888888;
187+
color: #777777;
212188
}
213189
214190
.hotkey-clear-btn {
215-
background: rgba(255, 59, 48, 0.15);
191+
background: rgba(255, 59, 48, 0.18);
216192
}
217193
218194
.hotkey-clear-btn:hover {
219-
background: rgba(255, 59, 48, 0.25);
195+
background: rgba(255, 59, 48, 0.28);
220196
}
221197
}
222198
</style>

src/renderer-app/src/scripts/onboarding.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,12 +454,11 @@ export default {
454454
}
455455
};
456456

457-
// Apply suggested hotkey based on mode
458457
const applySuggestedHotkey = () => {
459458
if (hotkeyMode.value === "toggle") {
460459
currentHotkey.value = "Control+D";
461460
} else {
462-
currentHotkey.value = "Alt+Right";
461+
currentHotkey.value = "Alt+/";
463462
}
464463
};
465464

src/renderer-app/src/styles/onboarding.less

Lines changed: 89 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -396,12 +396,32 @@
396396
}
397397
}
398398

399+
// Compact styles for hotkey content
400+
.hotkey-content {
401+
gap: 8px;
402+
}
403+
404+
.step-header.compact {
405+
gap: 6px;
406+
}
407+
408+
.step-icn.small {
409+
width: 44px;
410+
height: 44px;
411+
font-size: 22px;
412+
}
413+
399414
// Hotkey Mode Cards
400415
.hotkey-mode-cards {
401416
display: flex;
402417
gap: 12px;
403418
width: 100%;
404419
margin-top: 8px;
420+
421+
&.compact {
422+
gap: 8px;
423+
margin-top: 4px;
424+
}
405425
}
406426

407427
.hotkey-mode-card {
@@ -418,6 +438,32 @@
418438
transition: all 0.2s ease;
419439
position: relative;
420440

441+
&.compact {
442+
flex-direction: row;
443+
gap: 10px;
444+
padding: 12px 14px;
445+
border-radius: 10px;
446+
447+
.mode-content {
448+
text-align: left;
449+
flex: 1;
450+
451+
h3 {
452+
font-size: 13px;
453+
}
454+
455+
p {
456+
font-size: 10px;
457+
margin-top: 2px;
458+
}
459+
}
460+
461+
.mode-check {
462+
position: static;
463+
font-size: 16px;
464+
}
465+
}
466+
421467
&:hover {
422468
border-color: rgba(0, 122, 255, 0.3);
423469
background: rgba(0, 122, 255, 0.04);
@@ -439,6 +485,12 @@
439485
color: var(--accent);
440486
font-size: 28px;
441487
transition: all 0.2s ease;
488+
489+
&.small {
490+
width: 36px;
491+
height: 36px;
492+
font-size: 18px;
493+
}
442494
}
443495

444496
&.active .mode-icon {
@@ -484,22 +536,56 @@
484536
background: var(--card-bg);
485537
border: 1px solid var(--border);
486538
border-radius: 12px;
539+
540+
&.compact {
541+
flex-direction: row;
542+
justify-content: center;
543+
margin-top: 8px;
544+
padding: 10px 14px;
545+
gap: 10px;
546+
border-radius: 10px;
547+
}
487548
}
488549

489-
.hotkey-label {
550+
.hotkey-row {
490551
display: flex;
491552
align-items: center;
492553
gap: 8px;
493-
font-size: 13px;
554+
}
555+
556+
.hotkey-label {
557+
display: flex;
558+
align-items: center;
559+
gap: 6px;
560+
font-size: 12px;
494561
font-weight: 500;
495562
color: var(--fg);
563+
white-space: nowrap;
496564

497565
i {
498-
font-size: 16px;
566+
font-size: 14px;
499567
color: var(--accent);
500568
}
501569
}
502570

571+
.suggestion-btn {
572+
padding: 6px 12px;
573+
background: rgba(0, 122, 255, 0.1);
574+
border: 1px solid rgba(0, 122, 255, 0.2);
575+
border-radius: 6px;
576+
color: var(--accent);
577+
font-family: "SF Mono", Monaco, monospace;
578+
font-size: 12px;
579+
cursor: pointer;
580+
transition: all 0.15s ease;
581+
white-space: nowrap;
582+
583+
&:hover {
584+
background: rgba(0, 122, 255, 0.2);
585+
border-color: rgba(0, 122, 255, 0.4);
586+
}
587+
}
588+
503589
.hotkey-suggestion {
504590
display: flex;
505591
align-items: center;
@@ -510,23 +596,6 @@
510596
font-size: 11px;
511597
color: var(--muted);
512598
}
513-
514-
.suggestion-btn {
515-
padding: 4px 10px;
516-
background: rgba(0, 122, 255, 0.1);
517-
border: 1px solid rgba(0, 122, 255, 0.2);
518-
border-radius: 4px;
519-
color: var(--accent);
520-
font-family: "SF Mono", Monaco, monospace;
521-
font-size: 11px;
522-
cursor: pointer;
523-
transition: all 0.15s ease;
524-
525-
&:hover {
526-
background: rgba(0, 122, 255, 0.2);
527-
border-color: rgba(0, 122, 255, 0.4);
528-
}
529-
}
530599
}
531600

532601
@media (prefers-color-scheme: dark) {

src/renderer-app/src/utils/hotkey.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ export function normalizeKey(key, code, altKey) {
7979
} else if (CODE_TO_KEY_MAP[code]) {
8080
keyToUse = CODE_TO_KEY_MAP[code];
8181
}
82+
} else if (code.startsWith("Key")) {
83+
keyToUse = code.replace("Key", "");
8284
}
8385

8486
return SPECIAL_KEY_MAP[keyToUse] || keyToUse;

0 commit comments

Comments
 (0)