Add audio recording and upload capabilities

Introduces new modules for audio recording (`recorder.rs`) and
asynchronous uploading (`uploader.rs`) with retry logic.

The `recorder` module uses `ffmpeg` as a subprocess to capture audio and
save it as M4A files. It handles starting, stopping, and reporting
recording events.

The `uploader` module manages a queue of recordings to be uploaded to
the server. It supports persistent storage of pending uploads via
sidecar JSON files, exponential backoff for retries, and emits events
for UI feedback.

New dependencies were added to `Cargo.toml` and `Cargo.lock` to support
these features, including `reqwest`, `serde_json`, `tokio`, `uuid`, and
`which`.
This commit is contained in:
2026-04-17 15:49:55 +02:00
parent c441377749
commit 5f7e46256c
6 changed files with 693 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
//! OS-conventional paths for client-side storage.
use std::path::PathBuf;
use directories::ProjectDirs;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum PathError {
#[error("cannot determine OS data directory (is $HOME set?)")]
NoDataDir,
}
/// Directory where recordings wait for upload. Persists across app
/// restarts and crashes.
/// Linux: `~/.local/share/doctate/pending/`
/// Windows: `%LOCALAPPDATA%\doctate\pending\`
/// macOS: `~/Library/Application Support/doctate/pending/`
pub fn pending_dir() -> Result<PathBuf, PathError> {
ProjectDirs::from("", "", "doctate")
.map(|dirs| dirs.data_local_dir().join("pending"))
.ok_or(PathError::NoDataDir)
}