help menu

This commit is contained in:
2026-05-06 13:00:57 -06:00
parent acf7f2e64c
commit 6ac1d68887
8 changed files with 272 additions and 52 deletions

View File

@ -13,6 +13,7 @@ import ZoneEditor from './components/ZoneEditor';
import BackgroundMusicPanel from './components/BackgroundMusicPanel';
import AppendClipPanel from './components/AppendClipPanel';
import LicenseDialog from './components/LicenseDialog';
import HelpContent from './components/HelpContent';
import { useKeyboardShortcuts } from './hooks/useKeyboardShortcuts';
import { useLicenseStore } from './store/licenseStore';
import {
@ -35,11 +36,12 @@ import {
ListVideo,
Clock,
AlertTriangle,
HelpCircle,
} from 'lucide-react';
const LAST_MEDIA_PATH_KEY = 'talkedit:lastMediaPath';
type Panel = 'ai' | 'settings' | 'export' | 'silence' | 'zones' | 'markers' | 'music' | 'append' | null;
type Panel = 'ai' | 'settings' | 'export' | 'silence' | 'zones' | 'markers' | 'music' | 'append' | 'help' | null;
export default function App() {
const {
@ -133,6 +135,9 @@ export default function App() {
const [speedMode, setSpeedMode] = useState(false);
const [speedModeValue, setSpeedModeValue] = useState(1.25);
const [showReprocessConfirm, setShowReprocessConfirm] = useState(false);
const [showWelcomeOverlay, setShowWelcomeOverlay] = useState(() => {
return localStorage.getItem('talkedit:welcomeDismissed') !== 'true';
});
const [showUnsavedPrompt, setShowUnsavedPrompt] = useState(false);
const [pendingProceedAction, setPendingProceedAction] = useState<(() => Promise<void>) | null>(null);
const [lastSavedSignature, setLastSavedSignature] = useState<string | null>(null);
@ -727,34 +732,6 @@ export default function App() {
title="Append additional video clips — concatenate multiple files during export"
/>
<div className="w-px h-5 bg-editor-border mx-1" />
<div className="flex items-center gap-1.5 px-2 py-1 rounded-md bg-editor-surface border border-editor-border">
<select
value={whisperModel}
onChange={(e) => setWhisperModel(e.target.value)}
className="bg-editor-surface text-xs text-editor-text focus:outline-none [color-scheme:dark]"
title="Transcription model"
>
<optgroup label="Multilingual">
<option value="tiny">tiny</option>
<option value="base">base</option>
<option value="small">small</option>
<option value="medium">medium</option>
<option value="large-v2">large-v2</option>
<option value="large-v3">large-v3</option>
<option value="large-v3-turbo">large-v3-turbo</option>
<option value="distil-large-v3">distil-large-v3</option>
</optgroup>
<optgroup label="English">
<option value="tiny.en">tiny.en</option>
<option value="base.en">base.en</option>
<option value="small.en">small.en</option>
<option value="medium.en">medium.en</option>
<option value="distil-small.en">distil-small.en</option>
<option value="distil-medium.en">distil-medium.en</option>
</optgroup>
</select>
</div>
<div className="w-px h-5 bg-editor-border mx-1" />
<ToolbarButton
icon={<Sparkles className="w-4 h-4" />}
label="AI Tools"
@ -776,6 +753,13 @@ export default function App() {
active={activePanel === 'settings'}
onClick={() => togglePanel('settings')}
/>
<ToolbarButton
icon={<HelpCircle className="w-4 h-4" />}
label="Help"
active={activePanel === 'help'}
onClick={() => togglePanel('help')}
title="View help and feature documentation"
/>
</div>
</header>
@ -833,6 +817,9 @@ export default function App() {
<div className="text-center space-y-1">
<p className="text-sm font-medium text-editor-text">Processing audio</p>
<p className="text-xs text-editor-text-muted">{transcriptionStatus || 'Please wait...'}</p>
<div className="w-48 h-1.5 bg-editor-border rounded-full overflow-hidden mt-3">
<div className="h-full bg-editor-accent rounded-full animate-pulse" style={{ width: '60%' }} />
</div>
</div>
</div>
) : words.length > 0 ? (
@ -885,6 +872,7 @@ export default function App() {
{activePanel === 'ai' && <AIPanel onReprocess={handleReprocessProject} whisperModel={whisperModel} setWhisperModel={setWhisperModel} />}
{activePanel === 'export' && <ExportDialog />}
{activePanel === 'settings' && <SettingsPanel />}
{activePanel === 'help' && <HelpContent />}
</div>
</div>
)}
@ -893,6 +881,53 @@ export default function App() {
<LicenseDialog />
{showWelcomeOverlay && (
<div className="fixed inset-0 z-[85] flex items-center justify-center bg-black/70 px-4">
<div className="w-full max-w-sm rounded-xl border border-editor-border bg-editor-bg p-6 space-y-5 shadow-2xl">
<div className="flex flex-col items-center gap-3 text-center">
<Film className="w-10 h-10 text-editor-accent opacity-80" />
<h2 className="text-lg font-semibold">Welcome to TalkEdit</h2>
<p className="text-xs text-editor-text-muted leading-relaxed">
The offline video editor for long-form content. No account. No subscription. Your data never leaves your machine.
</p>
</div>
<div className="space-y-3">
<div className="flex items-start gap-3 p-2 rounded bg-editor-surface">
<span className="w-5 h-5 rounded-full bg-editor-accent/20 text-editor-accent text-[10px] font-semibold flex items-center justify-center shrink-0 mt-0.5">1</span>
<span className="text-xs text-editor-text-muted leading-relaxed">
<strong className="text-editor-text">Open a video</strong> TalkEdit transcribes it into a word-level transcript.
</span>
</div>
<div className="flex items-start gap-3 p-2 rounded bg-editor-surface">
<span className="w-5 h-5 rounded-full bg-editor-accent/20 text-editor-accent text-[10px] font-semibold flex items-center justify-center shrink-0 mt-0.5">2</span>
<span className="text-xs text-editor-text-muted leading-relaxed">
<strong className="text-editor-text">Edit by selecting words</strong> deleting words cuts the matching video. Like editing a doc.
</span>
</div>
<div className="flex items-start gap-3 p-2 rounded bg-editor-surface">
<span className="w-5 h-5 rounded-full bg-editor-accent/20 text-editor-accent text-[10px] font-semibold flex items-center justify-center shrink-0 mt-0.5">3</span>
<span className="text-xs text-editor-text-muted leading-relaxed">
<strong className="text-editor-text">Export your final cut</strong> with captions, background music, AI cleanup, and more.
</span>
</div>
</div>
<div className="flex flex-col items-center gap-2">
<button
onClick={() => { localStorage.setItem('talkedit:welcomeDismissed', 'true'); setShowWelcomeOverlay(false); }}
className="w-full px-6 py-2.5 bg-editor-accent hover:bg-editor-accent-hover rounded-lg text-sm font-medium transition-colors"
>
Got it
</button>
<p className="text-[10px] text-editor-text-muted">
Press <kbd className="px-1 py-0.5 text-[10px] font-mono bg-editor-surface border border-editor-border rounded">?</kbd> anytime to see shortcuts, or click <strong className="text-editor-text">Help</strong> in the toolbar.
</p>
</div>
</div>
</div>
)}
{showReprocessConfirm && (
<div
className="fixed inset-0 z-[60] flex items-center justify-center bg-black/60 px-4"