feat: add About dialog with version, author, and license info

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-22 12:40:32 -04:00
parent 9096ed10db
commit 05c4b4713a
3 changed files with 164 additions and 1 deletions

View File

@@ -8,6 +8,7 @@
import SetupWizard from '$lib/components/SetupWizard.svelte';
import PreferencesPanel from '$lib/components/PreferencesPanel.svelte';
import ExportDialog from '$lib/components/ExportDialog.svelte';
import AboutDialog from '$lib/components/AboutDialog.svelte';
import ProcessingModal from '$lib/components/ProcessingModal.svelte';
import { loadPreferences } from '$lib/stores/preferences.svelte';
import { getSelectedClipId, removeClip } from '$lib/stores/clips.svelte';
@@ -18,6 +19,7 @@
let showSetupWizard = $state(true);
let showPreferences = $state(false);
let showExportDialog = $state(false);
let showAboutDialog = $state(false);
let shuttleRate = $state(1);
let transportControls = $state<TransportControls | null>(null);
@@ -131,6 +133,12 @@
showExportDialog = true;
}
break;
case '/':
if (e.metaKey) {
e.preventDefault();
showAboutDialog = true;
}
break;
default:
break;
}
@@ -155,6 +163,10 @@
<ExportDialog onClose={() => (showExportDialog = false)} />
{/if}
{#if showAboutDialog}
<AboutDialog onClose={() => (showAboutDialog = false)} />
{/if}
{#if session.processingStep !== 'idle' && session.processingStep !== 'done'}
<ProcessingModal />
{/if}
@@ -162,6 +174,7 @@
<div class="app-shell">
<header class="toolbar">
<UrlInput />
<button class="about-btn" onclick={() => (showAboutDialog = true)} title="About">ℹ</button>
<button class="prefs-btn" onclick={() => (showPreferences = true)} title="Preferences">⚙</button>
</header>
@@ -185,7 +198,7 @@
</div>
</main>
<StatusBar />
<StatusBar onOpenAbout={() => (showAboutDialog = true)} />
</div>
<style>
@@ -243,6 +256,11 @@
overflow: hidden;
}
.about-btn {
font-size: 16px;
padding: 4px 8px;
}
.prefs-btn {
font-size: 18px;
padding: 4px 8px;

View File

@@ -0,0 +1,112 @@
<script lang="ts">
import { getVersion } from '@tauri-apps/api/app';
let { onClose }: { onClose: () => void } = $props();
let version = $state('');
$effect(() => {
getVersion().then((v) => {
version = v;
});
});
</script>
<div class="overlay" role="presentation" onclick={onClose}>
<div class="dialog" role="dialog" onclick={(e) => e.stopPropagation()}>
<img class="app-icon" src="/favicon.svg" alt="GUI Video Clipper icon" />
<h2>GUI Video Clipper</h2>
{#if version}
<span class="version">v{version}</span>
{/if}
<p class="author">by cottongin</p>
<p class="license">MIT License</p>
<a
class="repo-link"
href="https://code.cottongin.xyz/cottongin/gui-video-clipper"
target="_blank"
rel="noopener noreferrer"
>
code.cottongin.xyz/cottongin/gui-video-clipper
</a>
<div class="actions">
<button class="primary" onclick={onClose}>Close</button>
</div>
</div>
</div>
<style>
.overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 900;
}
.dialog {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: 12px;
padding: 32px;
max-width: 360px;
width: 100%;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
}
.app-icon {
width: 64px;
height: 64px;
border-radius: 12px;
margin-bottom: 8px;
}
h2 {
margin: 0;
font-size: 18px;
}
.version {
color: var(--text-secondary);
font-size: 14px;
font-family: var(--font-mono);
}
.author {
color: var(--text-secondary);
font-size: 13px;
margin: 0;
}
.license {
color: var(--text-muted);
font-size: 12px;
margin: 0;
}
.repo-link {
color: var(--accent);
font-size: 12px;
text-decoration: none;
}
.repo-link:hover {
text-decoration: underline;
}
.actions {
margin-top: 12px;
}
.primary {
background: var(--accent);
color: var(--bg-primary);
font-weight: 600;
}
</style>

View File

@@ -1,6 +1,17 @@
<script lang="ts">
import { getVersion } from '@tauri-apps/api/app';
import { session, upgradePreview } from '$lib/stores/videoSession.svelte';
let { onOpenAbout }: { onOpenAbout?: () => void } = $props();
let appVersion = $state('');
$effect(() => {
getVersion().then((v) => {
appVersion = v;
});
});
let previewPercent = $derived(Math.round(session.previewProgress * 100));
let exportPercent = $derived(Math.round(session.exportProgress * 100));
@@ -42,6 +53,11 @@
{:else}
<span class="status-text">Ready</span>
{/if}
{#if appVersion}
<button class="version-btn" onclick={() => onOpenAbout?.()} title="About GUI Video Clipper">
v{appVersion}
</button>
{/if}
</div>
<style>
@@ -91,4 +107,21 @@
background: var(--accent, #89b4fa);
color: var(--bg-primary, #1e1e2e);
}
.version-btn {
margin-left: auto;
background: none;
border: none;
color: var(--text-muted);
font-size: 11px;
font-family: var(--font-mono);
padding: 2px 6px;
cursor: pointer;
border-radius: 3px;
}
.version-btn:hover {
background: var(--bg-secondary);
color: var(--text-secondary);
}
</style>