feat: scaffold Tauri v2 + Svelte 5 project with base layout and utilities

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-21 10:45:53 -04:00
parent 95815ca6e0
commit 5cf61578ae
80 changed files with 8832 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
<div class="clip-list">
<div class="placeholder-text">No clips yet — press I to mark in-point</div>
</div>
<style>
.clip-list {
padding: 8px 12px;
background: var(--bg-secondary);
min-height: 80px;
border-top: 1px solid var(--border);
}
.placeholder-text {
color: var(--text-muted);
font-size: 13px;
}
</style>

View File

@@ -0,0 +1,16 @@
<div class="status-bar">
<span class="status-text">Ready</span>
</div>
<style>
.status-bar {
display: flex;
align-items: center;
padding: 4px 12px;
background: var(--bg-tertiary);
border-top: 1px solid var(--border);
font-size: 12px;
color: var(--text-secondary);
min-height: 24px;
}
</style>

View File

@@ -0,0 +1,17 @@
<div class="timeline">
<div class="placeholder-text">Timeline</div>
</div>
<style>
.timeline {
height: 160px;
background: var(--timeline-bg);
display: flex;
align-items: center;
justify-content: center;
}
.placeholder-text {
color: var(--text-muted);
font-size: 13px;
}
</style>

View File

@@ -0,0 +1,19 @@
<div class="transport-controls">
<span class="placeholder-text">Transport controls</span>
</div>
<style>
.transport-controls {
display: flex;
align-items: center;
padding: 8px 12px;
background: var(--bg-secondary);
border-top: 1px solid var(--border);
border-bottom: 1px solid var(--border);
min-height: 40px;
}
.placeholder-text {
color: var(--text-muted);
font-size: 13px;
}
</style>

View File

@@ -0,0 +1,12 @@
<div class="url-input">
<input type="text" placeholder="Paste a video URL..." />
</div>
<style>
.url-input {
flex: 1;
}
.url-input input {
width: 100%;
}
</style>

View File

@@ -0,0 +1,18 @@
<div class="video-player">
<div class="placeholder">Paste a URL above to load a video</div>
</div>
<style>
.video-player {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
background: #000;
min-height: 200px;
}
.placeholder {
color: var(--text-muted);
font-size: 16px;
}
</style>

14
src/lib/utils/colors.ts Normal file
View File

@@ -0,0 +1,14 @@
export const CLIP_COLORS = [
'#4A90D9',
'#E5734A',
'#5CB85C',
'#D94A7A',
'#D9A54A',
'#7B68EE',
'#20B2AA',
'#FF6B6B',
] as const;
export function getClipColor(index: number): string {
return CLIP_COLORS[index % CLIP_COLORS.length];
}

36
src/lib/utils/time.ts Normal file
View File

@@ -0,0 +1,36 @@
export function formatTime(totalSeconds: number): string {
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = Math.floor(totalSeconds % 60);
const millis = Math.round((totalSeconds % 1) * 1000);
const mm = String(minutes).padStart(2, '0');
const ss = String(seconds).padStart(2, '0');
const ms = String(millis).padStart(3, '0');
if (hours > 0) {
return `${hours}:${mm}:${ss}.${ms}`;
}
return `${mm}:${ss}.${ms}`;
}
export function parseTime(str: string): number | null {
const hmsMatch = str.match(/^(\d+):(\d{2}):(\d{2})(?:\.(\d{1,3}))?$/);
if (hmsMatch) {
const h = parseInt(hmsMatch[1], 10);
const m = parseInt(hmsMatch[2], 10);
const s = parseInt(hmsMatch[3], 10);
const ms = hmsMatch[4] ? parseInt(hmsMatch[4].padEnd(3, '0'), 10) : 0;
return h * 3600 + m * 60 + s + ms / 1000;
}
const msMatch = str.match(/^(\d{2}):(\d{2})(?:\.(\d{1,3}))?$/);
if (msMatch) {
const m = parseInt(msMatch[1], 10);
const s = parseInt(msMatch[2], 10);
const ms = msMatch[3] ? parseInt(msMatch[3].padEnd(3, '0'), 10) : 0;
return m * 60 + s + ms / 1000;
}
return null;
}