Files
focus/src/components/ShortcutsModal.tsx
gkxk c6f541ed94 feat: initial implementation of Focus RSVP speed reader
- Pure frontend SPA (Vite + React 19 + TypeScript + Tailwind CSS v4)
- Spritz ORP engine with absolute center crosshair gaze fixation
- Multilingual hybrid segmentation via Intl.Segmenter with punctuation attachment
- Adaptive breathing rhythm delay algorithm for natural comprehension
- IndexedDB local bookshelf, progress persistence, and client-side EPUB/TXT/MD parsing
- Curated sci-fi, philosophy, and classic speech samples
- Dark/OLED/Sepia/Slate/Nord themes and rich keyboard controls

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-20 08:28:20 +08:00

66 lines
2.7 KiB
TypeScript

import { HelpCircle, X } from 'lucide-react';
import React from 'react';
interface ShortcutsModalProps {
isOpen: boolean;
onClose: () => void;
}
const SHORTCUTS = [
{ key: '空格键 (Space)', action: '播放 / 暂停' },
{ key: '← / →', action: '快退 / 快进 10 个词' },
{ key: 'Shift + ← / →', action: '跳转到 上一句 / 下一句' },
{ key: '↑ / ↓', action: '微调阅读语速 ±25 WPM' },
{ key: 'Shift + ↑ / ↓', action: '加速调节语速 ±50 WPM' },
{ key: '[ / ] 或 PageUp/Down', action: '跳转到 上一章 / 下一章' },
{ key: 'R', action: '从头重新开始阅读' },
{ key: 'F', action: '切换全屏专注模式' },
{ key: 'Esc', action: '关闭当前浮层 / 弹窗' },
];
export const ShortcutsModal: React.FC<ShortcutsModalProps> = ({
isOpen,
onClose,
}) => {
if (!isOpen) return null;
return (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/60 backdrop-blur-sm animate-fade-in select-none">
<div className="relative w-full max-w-md bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-2xl shadow-2xl flex flex-col max-h-[85vh] overflow-hidden">
{/* Header */}
<div className="flex items-center justify-between px-6 py-4 border-b border-neutral-200 dark:border-neutral-800">
<div className="flex items-center space-x-2">
<HelpCircle className="w-5 h-5 text-rose-500" />
<h2 className="text-lg font-bold text-neutral-900 dark:text-neutral-100">
键盘极速快捷键
</h2>
</div>
<button
onClick={onClose}
className="p-1 rounded-lg text-neutral-400 hover:text-neutral-900 dark:hover:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 transition-colors"
>
<X className="w-5 h-5" />
</button>
</div>
{/* Shortcuts list */}
<div className="p-6 space-y-2.5 flex-1 overflow-y-auto">
{SHORTCUTS.map((s, idx) => (
<div
key={idx}
className="flex items-center justify-between py-1.5 border-b border-neutral-100 dark:border-neutral-800/60 last:border-0"
>
<kbd className="px-2.5 py-1 text-xs font-mono font-semibold bg-neutral-100 dark:bg-neutral-800 text-neutral-800 dark:text-neutral-200 rounded-md border border-neutral-200 dark:border-neutral-700 shadow-sm">
{s.key}
</kbd>
<span className="text-sm text-neutral-600 dark:text-neutral-300">
{s.action}
</span>
</div>
))}
</div>
</div>
</div>
);
};