mirror of
https://github.com/sipeed/NanoKVM-USB.git
synced 2026-09-12 06:29:59 -05:00
Merge pull request #44 from ShuJun-Junical/main
feat(browser): add keyboard shortcuts menu, add Ctrl+D and Win+Tab shortcuts
This commit is contained in:
@@ -4,7 +4,7 @@ import { KeyboardIcon } from 'lucide-react';
|
||||
|
||||
import { Paste } from './paste.tsx';
|
||||
import { VirtualKeyboard } from './virtual-keyboard.tsx';
|
||||
import { CtrlAltDel } from './ctrl-alt-del';
|
||||
import { KeyboardShortcutsMenu } from './shortcuts-menu.tsx';
|
||||
|
||||
export const Keyboard = () => {
|
||||
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
|
||||
@@ -12,8 +12,8 @@ export const Keyboard = () => {
|
||||
const content = (
|
||||
<>
|
||||
<Paste />
|
||||
<CtrlAltDel />
|
||||
<VirtualKeyboard />
|
||||
<KeyboardShortcutsMenu />
|
||||
</>
|
||||
);
|
||||
|
||||
|
||||
@@ -1,24 +1,27 @@
|
||||
import { useState } from 'react';
|
||||
import { SendHorizonal } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { device } from '@/libs/device';
|
||||
import { Modifiers } from '@/libs/device/keyboard.ts';
|
||||
import { KeyboardCodes } from '@/libs/keyboard';
|
||||
|
||||
export const CtrlAltDel = () => {
|
||||
const { t } = useTranslation();
|
||||
interface ShortcutProps {
|
||||
label: string;
|
||||
modifiers?: Partial<Modifiers>;
|
||||
keyCode: string;
|
||||
}
|
||||
|
||||
export const Shortcut = ({ label, modifiers = {}, keyCode }: ShortcutProps) => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
async function ctrlAltDel(): Promise<void> {
|
||||
async function handleClick(): Promise<void> {
|
||||
if (isLoading) return;
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
const modifiers = new Modifiers();
|
||||
modifiers.leftCtrl = true;
|
||||
modifiers.leftAlt = true;
|
||||
await send(modifiers, KeyboardCodes.get('Delete')!);
|
||||
const mods = new Modifiers();
|
||||
Object.assign(mods, modifiers);
|
||||
await send(mods, KeyboardCodes.get(keyCode)!);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
@@ -26,20 +29,19 @@ export const CtrlAltDel = () => {
|
||||
}
|
||||
}
|
||||
|
||||
async function send(modifiers: Modifiers, code: number) {
|
||||
async function send(mods: Modifiers, code: number) {
|
||||
const keys = [0x00, 0x00, code, 0x00, 0x00, 0x00];
|
||||
await device.sendKeyboardData(modifiers, keys);
|
||||
|
||||
await device.sendKeyboardData(mods, keys);
|
||||
await device.sendKeyboardData(new Modifiers(), [0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex h-[30px] cursor-pointer items-center space-x-1 rounded px-3 text-neutral-300 hover:bg-neutral-700/60"
|
||||
onClick={ctrlAltDel}
|
||||
onClick={handleClick}
|
||||
>
|
||||
<SendHorizonal size={18} />
|
||||
<span>{t('keyboard.ctrlAltDel')}</span>
|
||||
<span>{label}</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
55
browser/src/components/menu/keyboard/shortcuts-menu.tsx
Normal file
55
browser/src/components/menu/keyboard/shortcuts-menu.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import { useState } from 'react';
|
||||
import { SendHorizonal } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Popover } from 'antd';
|
||||
|
||||
import { Shortcut } from './shortcut.tsx';
|
||||
|
||||
export const KeyboardShortcutsMenu = () => {
|
||||
const { t } = useTranslation();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<Popover
|
||||
content={
|
||||
<div className="flex flex-col gap-1">
|
||||
{[
|
||||
{
|
||||
label: t('keyboard.ctrlAltDel'),
|
||||
modifiers: { leftCtrl: true, leftAlt: true },
|
||||
keyCode: 'Delete',
|
||||
},
|
||||
{
|
||||
label: t('keyboard.ctrlD'),
|
||||
modifiers: { leftCtrl: true },
|
||||
keyCode: 'KeyD',
|
||||
},
|
||||
{
|
||||
label: t('keyboard.winTab'),
|
||||
modifiers: { leftWindows: true },
|
||||
keyCode: 'Tab',
|
||||
},
|
||||
].map((shortcut) => (
|
||||
<Shortcut
|
||||
key={shortcut.keyCode}
|
||||
label={shortcut.label}
|
||||
modifiers={shortcut.modifiers}
|
||||
keyCode={shortcut.keyCode}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
}
|
||||
trigger="click"
|
||||
placement="rightTop"
|
||||
align={{ offset: [14, 0] }}
|
||||
open={open}
|
||||
onOpenChange={setOpen}
|
||||
arrow={false}
|
||||
>
|
||||
<div className="flex h-[30px] cursor-pointer items-center space-x-1 rounded px-3 text-neutral-300 hover:bg-neutral-700/60">
|
||||
<SendHorizonal size={18} />
|
||||
<span>{t('keyboard.shortcuts')}</span>
|
||||
</div>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
@@ -37,7 +37,10 @@ const be = {
|
||||
keyboard: {
|
||||
paste: 'Plakken',
|
||||
virtualKeyboard: 'Virtueel klavier',
|
||||
ctrlAltDel: 'Ctrl + Alt + Delete'
|
||||
shortcuts: 'Sneltoetsen',
|
||||
ctrlAltDel: 'Ctrl + Alt + Delete',
|
||||
ctrlD: 'Ctrl + D',
|
||||
winTab: 'Win + Tab',
|
||||
},
|
||||
mouse: {
|
||||
cursor: {
|
||||
@@ -62,5 +65,5 @@ const be = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default be;
|
||||
|
||||
export default be;
|
||||
|
||||
@@ -37,7 +37,10 @@ const de = {
|
||||
keyboard: {
|
||||
paste: 'Einfügen',
|
||||
virtualKeyboard: 'Virtuelle Tastatur',
|
||||
ctrlAltDel: 'Strg + Alt + Entfernen'
|
||||
shortcuts: 'Tastenkürzel',
|
||||
ctrlAltDel: 'Strg + Alt + Entfernen',
|
||||
ctrlD: 'Strg + D',
|
||||
winTab: 'Win + Tab',
|
||||
},
|
||||
mouse: {
|
||||
cursor: {
|
||||
@@ -62,5 +65,5 @@ const de = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default de;
|
||||
|
||||
export default de;
|
||||
|
||||
@@ -37,7 +37,10 @@ const en = {
|
||||
keyboard: {
|
||||
paste: 'Paste',
|
||||
virtualKeyboard: 'Keyboard',
|
||||
ctrlAltDel: 'Ctrl + Alt + Delete'
|
||||
shortcuts: 'Shortcuts',
|
||||
ctrlAltDel: 'Ctrl + Alt + Delete',
|
||||
ctrlD: 'Ctrl + D',
|
||||
winTab: 'Win + Tab',
|
||||
},
|
||||
mouse: {
|
||||
cursor: {
|
||||
|
||||
@@ -37,7 +37,10 @@ const nl = {
|
||||
keyboard: {
|
||||
paste: 'Plakken',
|
||||
virtualKeyboard: 'Virtueel toetsenbord',
|
||||
ctrlAltDel: 'Ctrl + Alt + Delete'
|
||||
shortcuts: 'Sneltoetsen',
|
||||
ctrlAltDel: 'Ctrl + Alt + Delete',
|
||||
ctrlD: 'Ctrl + D',
|
||||
winTab: 'Win + Tab',
|
||||
},
|
||||
mouse: {
|
||||
cursor: {
|
||||
@@ -62,5 +65,5 @@ const nl = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default nl;
|
||||
|
||||
export default nl;
|
||||
|
||||
@@ -37,7 +37,10 @@ const ru = {
|
||||
keyboard: {
|
||||
paste: 'Вставить текст',
|
||||
virtualKeyboard: 'Виртуальная клавиатура',
|
||||
ctrlAltDel: 'Ctrl + Alt + Delete'
|
||||
shortcuts: 'Сочетания клавиш',
|
||||
ctrlAltDel: 'Ctrl + Alt + Delete',
|
||||
ctrlD: 'Ctrl + D',
|
||||
winTab: 'Win + Tab',
|
||||
},
|
||||
mouse: {
|
||||
cursor: {
|
||||
|
||||
@@ -35,7 +35,10 @@ const zh = {
|
||||
keyboard: {
|
||||
paste: '粘贴',
|
||||
virtualKeyboard: '虚拟键盘',
|
||||
ctrlAltDel: 'Ctrl + Alt + Delete'
|
||||
shortcuts: '快捷键',
|
||||
ctrlAltDel: 'Ctrl + Alt + Delete',
|
||||
ctrlD: 'Ctrl + D',
|
||||
winTab: 'Win + Tab',
|
||||
},
|
||||
mouse: {
|
||||
cursor: {
|
||||
|
||||
Reference in New Issue
Block a user