diff options
| -rw-r--r-- | .gitignore | 9 | ||||
| -rw-r--r-- | README.md | 131 | ||||
| -rw-r--r-- | src-tauri/src/lib.rs | 25 | ||||
| -rw-r--r-- | src-tauri/tauri.conf.json | 3 |
4 files changed, 161 insertions, 7 deletions
@@ -11,6 +11,15 @@ node_modules dist dist-ssr *.local +src-tauri/target +graphify-out/ +.opencode/ +.worktrees/ +worktrees/ +docs/superpowers/ + +# Local dev audio assets +src-tauri/audio/*.ogg # Editor directories and files .vscode/* @@ -1,7 +1,130 @@ -# Tauri + React + Typescript +# Solstice -This template should help get you started developing with Tauri, React and Typescript in Vite. +Minimalist Pomodoro timer desktop app. Stack: Tauri 2 + React 19 + TypeScript + Rust. -## Recommended IDE Setup +## Prereqs -- [VS Code](https://code.visualstudio.com/) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) +- Node.js 20+ +- Rust toolchain +- Tauri system deps for your OS + +Install Tauri OS deps first if `npm run tauri dev` or `npm run tauri build` fails: + +- https://v2.tauri.app/start/prerequisites/ + +## Clone And Install + +```bash +git clone ssh://git@tylerhoang.xyz:46701/srv/git/solstice.git +cd solstice +npm install +``` + +## Run In Dev + +Full desktop app with hot reload: + +```bash +npm run tauri dev +``` + +What this does: + +- starts Vite dev server on `http://localhost:1420` +- builds Rust side in dev mode +- opens native Tauri window + +Frontend only in browser: + +```bash +npm run dev +``` + +## Build + +Frontend build + TypeScript check only: + +```bash +npm run build +``` + +This writes static frontend files to `dist/`. It does **not** create runnable desktop app by itself. + +Desktop app build: + +```bash +npm run tauri build +``` + +This runs frontend build first, then builds packaged Tauri app. + +## Run Built App + +After `npm run tauri build`, look here: + +- packaged outputs: `src-tauri/target/release/bundle/` +- raw release binary: `src-tauri/target/release/` + +Typical local run on Linux: + +```bash +./src-tauri/target/release/solstice +``` + +If exact filename differs on your OS, use installer/package inside `src-tauri/target/release/bundle/`. + +## Audio Files + +Ambient audio is user-supplied. Expected filenames: + +- `rain.ogg` +- `cafe.ogg` +- `white_noise.ogg` + +Lookup order: + +1. app data audio dir +2. bundled `audio/` dir + +### Easiest Dev Setup + +Place OGG files in: + +```text +src-tauri/audio/ +``` + +This directory is also release source for bundled default sounds. `npm run tauri build` packages any expected `.ogg` files found there, and built app uses them when app-data audio is absent. + +Example: + +```bash +cp /path/to/rain.ogg src-tauri/audio/rain.ogg +cp /path/to/cafe.ogg src-tauri/audio/cafe.ogg +cp /path/to/white_noise.ogg src-tauri/audio/white_noise.ogg +``` + +Do not rename files. App looks for those exact names. + +### App Data Audio Dir + +On startup app creates `<app_data_dir>/audio` and prefers files there over bundled files. + +Use this when you want custom audio without touching repo files. App state also persists under same app data dir as `data.json`. + +## Useful Commands + +```bash +npm run dev # frontend only +npm run build # TS check + frontend build +npm run tauri dev # desktop app in dev mode +npm run tauri build # desktop app release build +``` + +Rust side only: + +```bash +cd src-tauri +cargo build +cargo test +``` diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 2b359eb..aaa9cd2 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -23,6 +23,17 @@ fn app_data_dir(app: &AppHandle) -> std::path::PathBuf { app.path().app_data_dir().expect("Failed to resolve app data dir") } +fn fallback_bundled_audio_root() -> std::path::PathBuf { + std::path::PathBuf::from("src-tauri") +} + +fn bundled_audio_dir(app: &AppHandle) -> std::path::PathBuf { + app.path() + .resource_dir() + .unwrap_or_else(|_| fallback_bundled_audio_root()) + .join("audio") +} + fn persist_timer_snapshot( timer: &TimerState, data: &State<'_, AppDataWrapper>, @@ -423,9 +434,7 @@ pub fn run() { }); // Initialise audio engine (graceful if no device) - let bundled_audio_dir = app.handle().path().resource_dir() - .unwrap_or_else(|_| std::path::PathBuf::from(".")) - .join("audio"); + let bundled_audio_dir = bundled_audio_dir(app.handle()); let audio_state = audio::init_audio(app_audio_dir, bundled_audio_dir); let audio_arc = Arc::clone(&audio_state.0); app.manage(audio_state); @@ -462,3 +471,13 @@ pub fn run() { .run(tauri::generate_context!()) .expect("error while running tauri application"); } + +#[cfg(test)] +mod tests { + use super::fallback_bundled_audio_root; + + #[test] + fn dev_audio_fallback_points_at_src_tauri() { + assert_eq!(fallback_bundled_audio_root(), std::path::PathBuf::from("src-tauri")); + } +} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index b39e99f..daa4c74 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -28,6 +28,9 @@ "bundle": { "active": true, "targets": "all", + "resources": [ + "audio/*.ogg" + ], "icon": [ "icons/32x32.png", "icons/128x128.png", |
