This commit introduces a visual indicator in the UI to show when a case
has pending uploads.
The `WorkerSnapshot` struct has been updated to include a
`pending_case_ids` field, which is an `Arc<HashSet<Uuid>>`. This set
stores the IDs of cases that currently have files in the pending
directory.
The `run_loop` function now populates this set by scanning the pending
directory and collecting the `case_id`s of any files found. This
snapshot is then sent to the UI via the `worker_rx` channel.
In the `DoctateApp::ui` method, the `pending_ids` set is cloned from the
worker's snapshot. If a case's ID is present in this set, a distinct "⬆"
prefix and a yellow label are used to highlight it, signifying an
ongoing or pending upload. Otherwise, the standard label is used.
The `WorkerSnapshot` now includes `last_failure`, which tracks the time
of the last recorded error. This allows the UI to display a more
accurate status, especially when a failure occurs after a recent
success.
The `pick_footer_status` function has been updated to prioritize
`last_failure`. If a failure occurred more recently than the last
success, the footer will show `Offline`, regardless of the success age.
This addresses scenarios where the server might have temporarily failed,
and the UI should reflect that immediately.
The `run_loop` function now updates `last_failure` upon transient or
terminal upload errors and poll failures. This ensures that the new
state information is correctly propagated.
This commit consolidates the upload and polling functionalities into a
single `ServerSync` worker. The `oneliner_poller` and `uploader` modules
have been removed, and their responsibilities are now handled by
`server_sync`.
The `ServerSync` worker manages both uploading pending recordings and
polling the `/api/oneliners` endpoint. Uploads take precedence, and
polling only occurs when the pending upload directory is empty. The
worker now uses a unified HTTP client and a single `tokio::select!` loop
for managing these tasks.
Key changes include:
- Removal of `oneliner_poller.rs` and `uploader.rs`.
- Introduction of `server_sync.rs` and `upload.rs` in
`doctate-client-core`.
- `ServerSync` now handles upload events (`UploadEvent`) and provides a
`WorkerSnapshot` for UI feedback.
- Upload logic has been refactored to handle transient and terminal
errors more robustly, including file deletion for terminal failures.
- Polling logic is integrated into the `ServerSync` loop, utilizing the
existing `SnapshotCache` and `CaseStore`.
- The `App` component in `client-desktop` has been updated to use
`ServerSync` instead of the separate poller and uploader.
- Documentation comments have been updated to reflect the new structure.
This commit introduces a new startup cleanup routine for the Doctate
client.
The cleanup process reaps stale markers and orphaned audio files to
adhere to data minimization principles and maintain client efficiency.
Specifically, it performs the following actions:
- Removes markers that are older than 72 hours and have been confirmed
by
the server. This ensures that old, irrelevant metadata is purged.
- Cleans up orphaned audio files (e.g., `.m4a` without corresponding
`.meta.json` or vice-versa) that are older than 24 hours. This
prevents the accumulation of audio data that will never be uploaded,
as such files are silently ignored by the uploader.
- Removes any temporary files (`.tmp`) left over from interrupted
writes,
as these are considered invalid at startup.
The `filetime` crate is added as a dependency to facilitate setting
modification times for testing purposes.
Introduce `last_recording_at` to `OnelinerEntry` and use it as the
primary sort key for cases. This ensures that cases with recent
dictation activity are prioritized, even if their initial creation date
is older.
The logic for determining a case's activity has been updated to consider
the most recent `.m4a` file's modification time (`last_recording_at`),
falling back to `updated_at` or `created_at` if necessary.
This change also refactors the timestamp formatting and handling within
the web interface to correctly display and sort cases based on their
actual last activity time, improving user experience and data relevance.
The `now_rfc3339` function is updated to strip sub-second precision for
consistent filename generation.
Add `SnapshotCache` struct to handle on-disk caching of API responses.
This includes `load`, `store`, and `clear` methods for managing the
cache file.
Atomic writes are implemented using a temporary file and rename
operation.
Error handling for file operations and JSON deserialization is included.
Unit tests are provided to verify cache functionality.
Introduces a new crate `doctate-client-core` to house shared client-side
logic. This includes:
- `case_store`: Manages local case marker files and merging with server
snapshots.
- `snapshot_cache`: Placeholder for caching server responses.
- `oneliner_poller`: Placeholder for the background polling task.
The workspace configuration and `Cargo.lock` have been updated to
include the new crate.