6.5 KiB
Project: StreamCapture (Tauri + Vue 3 YouTube Downloader)
1. Context & Objective
You are an expert Full-Stack Rust/TypeScript developer specializing in Tauri v2 application development.
Your task is to build a cross-platform (Windows & macOS) desktop application named "StreamCapture" in the current directory.
The app is a GUI wrapper for yt-dlp, but unlike standard sidecar implementations, it must manage the yt-dlp binary externally (in the user's AppData directory) to allow for frequent updates without rebuilding the app.
Tech Stack:
- Core: Tauri v2 (Rust)
- Frontend: Vue 3 (Composition API,
<script setup>) - Build Tool: Vite
- Styling: Tailwind CSS (Mobile-first, Modern UI)
- State Management: Pinia
- Icons: Lucide-vue-next
- HTTP Client (Rust):
reqwest(for downloading yt-dlp)
2. Core Architecture & Workflow
2.1. External Binary Management (Crucial)
Since yt-dlp updates frequently, we do NOT bundle it inside the binary.
- Location: The app must utilize the system's local data directory (e.g.,
%APPDATA%/StreamCapture/binon Windows,~/Library/Application Support/StreamCapture/binon macOS). - Initialization: On app launch, the Rust backend must check if
yt-dlpexists in that directory. - Auto-Download: If missing, download the correct binary from the official GitHub releases (
yt-dlp.exefor Win,yt-dlp_macosfor Mac). - Permissions: On macOS, apply
chmod +x(0o755) to the downloaded binary immediately. - Execution: Use Rust's
std::process::Commandto execute this specific binary using its absolute path.
2.2. Configuration Persistence
- File:
settings.jsonin the app data directory. - Fields:
download_path: string (Default: System Download Dir)theme: 'light' | 'dark' | 'system' (Default: system)last_updated: timestamp (for yt-dlp check)
2.3. History Persistence
- File:
history.json. - Stores a list of completed or failed downloads (metadata, status, timestamp, file path).
3. Rust Backend Specifications (src-tauri/src/lib.rs & Modules)
Create specific commands to handle logic securely. Avoid exposing raw shell execution to the frontend.
Module: ytdlp_manager
init_ytdlp(): Checks existence. If missing, downloads it. Returns status.update_ytdlp(): Runsyt-dlp -U.get_version(): Returns current version string.
Module: downloader
fetch_metadata(url: String):- Runs
yt-dlp --dump-single-json --flat-playlist [url]. - Logic: If it's a playlist, return a list of video objects (id, title, thumbnail, duration). If single video, return one object.
- Important: Do NOT download media yet.
- Runs
download_video(url: String, options: DownloadOptions):- Options Struct:
{ is_audio_only: bool, quality: String, output_path: String } - Process: Spawns a command. Emits Tauri Events (
download-progress) to frontend with percentage and speed.
- Options Struct:
Module: storage
- Helper functions to read/write
settings.jsonandhistory.json.
4. Frontend Specifications (Vue 3 + Tailwind)
4.1. UI Layout
- Sidebar: Navigation (Home/Download, History, Settings).
- Header: Theme toggle, App status (checking yt-dlp...).
- Main Content: Dynamic view based on route.
4.2. Views
A. Home View (The Downloader)
- Input Area: Large, modern input box for URL. "Analyze" button.
- Selection Area (Conditional):
- Appears after "Analyze" succeeds.
- Shows thumbnail(s) and title(s).
- If Playlist: Show list of items with checkboxes (Select All / Select None).
- Options Panel:
- Format: Dropdown (Best Video+Audio, 1080p, 720p, 480p).
- Mode: Toggle Switch (Video / Audio Only).
- Action: Big "Download" button.
- Progress: Progress bars for active downloads.
B. History View
- Table/List of past downloads.
- Columns: Thumbnail (small), Title, Date, Format, Status (Success/Fail).
- Actions: "Open File Location", "Delete Record" (Icon), "Clear All" (Button at top).
C. Settings View
- Download Path: Input field + "Browse" button (use Tauri
dialogAPI). - Yt-dlp: Show current version. Button "Check for Updates".
- Theme: Radio buttons (Light/Dark/System).
4.3. State Management (Pinia stores)
useSettingsStore: Loads/saves config. Handles theme applying (adding.darkclass tohtml).useQueueStore: Manages active downloads and progress events.
5. Visual Design Guidelines (Tailwind)
- Theme:
- Light Mode: White/Gray-50 background, Zinc-900 text, Primary Blue-600.
- Dark Mode: Zinc-950 background, Gray-100 text, Primary Blue-500.
- Components:
- Rounded corners (
rounded-xl). - Subtle shadows (
shadow-sm,shadow-md). - Input fields with focus rings.
- Transitions for hover states and page switches.
- Rounded corners (
6. Implementation Steps for Gemini
Please generate the code in the following order. Ensure all files include // filepath: ... comments.
- Rust Setup:
Cargo.toml(dependencies: reqwest, serde, serde_json, tokio, etc.).src-tauri/src/lib.rs: Main entry with command registration.src-tauri/src/ytdlp.rs: The download/update logic.src-tauri/src/commands.rs: The Tauri commands exposed to frontend.
- Frontend Setup:
package.json: deps (pinia, vue-router, lucide-vue-next, tailwindcss, autoprefixer, postcss).src/style.css: Tailwind directives.src/stores/...: Pinia stores.src/components/...: Reusable UI components (Input, Button, Card).src/views/...: The main pages.src/App.vue: Main layout.
- Configuration:
tailwind.config.js: Dark mode config.src-tauri/capabilities/default.json: CRITICAL. Configure permissions to allow accessingapp_data_dirand the network scope.
7. Testing Requirements
- Create a basic Rust test in
src-tauri/src/ytdlp.rsthat verifies it can construct the correct path for the binary based on OS. - Ensure Vue components handle "Loading" states gracefully (skeletons or spinners).
IMPORTANT NOTE ON PERMISSIONS:
Since we are using std::process::Command directly in Rust, we do not need to configure the strict shell scope in tauri.conf.json, but we MUST ensure the App Data directory is writable.
Start by generating the Rust backend logic first, as the frontend depends on these commands.