Merge pull request #47 from SteelDynamite/claude/dreamy-brown-AVqxJ
This commit is contained in:
commit
707e1ac2e2
|
|
@ -37,7 +37,7 @@ Two-crate workspace (`resolver = "2"`, edition 2021) plus a Tauri app:
|
|||
|
||||
- **Storage trait** (`storage.rs`): Strategy pattern for task persistence. `FileSystemStorage` reads/writes markdown files with YAML frontmatter and JSON metadata files. Atomic writes (temp file + rename, with temp cleanup on failure) for all metadata files. Input validation: task titles max 500 chars, descriptions max 1MB, list names max 255 chars, YAML frontmatter max 64KB. Delete operations update metadata before removing files to prevent orphaned metadata on crash.
|
||||
- **Repository** (`repository.rs`): `TaskRepository` wraps a `Storage` impl and provides the public API for task/list CRUD, ordering, and grouping. Tests live here.
|
||||
- **Config** (`config.rs`): `AppConfig` manages workspaces keyed by UUID string. `WorkspaceConfig` stores `name`, `path`, `mode` (Local/Webdav/GoogleTasks), `webdav_url`, `webdav_path` (user-selected remote folder), `google_account` (display name/email for GoogleTasks workspaces), `theme`, `sync_interval_secs` (focused polling interval), and `sync_interval_unfocused_secs` (lower-frequency polling when window loses focus, for mobile battery optimization). `add_workspace` returns a generated UUID. Stored in platform-specific config dirs via the `directories` crate. Atomic writes (temp file + rename) prevent corruption on crash.
|
||||
- **Config** (`config.rs`): `AppConfig` manages workspaces keyed by UUID string. `WorkspaceConfig` stores `name`, `path`, `mode` (Local/Webdav/GoogleTasks), `webdav_url`, `webdav_path` (user-selected remote folder), `google_account` (display name/email for GoogleTasks workspaces), `last_sync` (timestamp of last successful sync), `theme`, `sync_interval_secs` (focused polling interval), and `sync_interval_unfocused_secs` (lower-frequency polling when window loses focus, for mobile battery optimization). `add_workspace` returns a generated UUID. Stored in platform-specific config dirs via the `directories` crate. Atomic writes (temp file + rename) prevent corruption on crash.
|
||||
- **Sync** (`sync.rs`): Three-way diff sync with offline queue. File-based `.sync.lock` prevents concurrent sync operations (auto-cleaned after 5 minutes if stale). Checksum-based conflict resolution: downloads remote, compares SHA-256 — identical content is a false conflict (skipped); when different, remote wins and local is recovered as a duplicate with a new UUID and `[RECOVERED FROM CONFLICT]` prefix (duplicate file cleaned up if metadata update fails). Auto-sync lifecycle: periodic polling (configurable interval, default 60s), debounced file-change (5s), window-focus (30s stale threshold). Wrapped in `tokio::time::timeout` (60s) to handle unreachable servers on Windows. Path traversal validation rejects `..` components and backslashes anywhere in sync paths. Atomic writes for sync state and queue files (temp cleanup on failure).
|
||||
- **WebDAV** (`webdav.rs`): reqwest client with rustls-tls, 30s request timeout, 10s connect timeout. Rejects non-HTTPS URLs. `Zeroizing<String>` for credential fields. `move_resource` method for WebDAV MOVE (workspace rename). 10MB cap on both PROPFIND responses and file downloads. Desktop credentials via `keyring` crate (feature-gated); Tauri GUI uses `tauri-plugin-credentials` for cross-platform support (Android Keystore + desktop keychain).
|
||||
- **Google Tasks** (`google_tasks.rs`): Read-only Google Tasks API client using reqwest with Bearer auth. `gt_id_to_uuid()` converts Google Task IDs to stable UUID v5 values for consistent cross-sync identity. Fetches all task lists and tasks from the Google Tasks REST API and writes them locally via `FileSystemStorage`. Remote always wins (read-only workspace mode). OAuth flow is partially implemented — client ID/secret are placeholders pending real credentials.
|
||||
|
|
@ -80,7 +80,7 @@ Pre-alpha. No users, no released builds, no data to migrate. Breaking changes to
|
|||
- Sliding lists drawer with checkmark selection
|
||||
- Settings popup overlay
|
||||
- Workspace switcher drop-up with add/remove
|
||||
- Per-workspace theme system (System default, Light, Dark, Nord, Dracula, Solarized Dark, Ink) via CSS `data-theme` attribute
|
||||
- Per-workspace theme system (System default, Light, Dark, Nord, Dracula, Solarized Dark, Black and Gold, Ink) via CSS `data-theme` attribute
|
||||
- Completed tasks section with animated show/hide
|
||||
- Date picker/editor (DateTimePicker in new task + task detail); `has_time: bool` field tracks whether time is set
|
||||
- Move task between lists (inline list in kebab menu, no submenu)
|
||||
|
|
@ -108,6 +108,7 @@ Pre-alpha. No users, no released builds, no data to migrate. Breaking changes to
|
|||
- Custom confirmation dialogs (ConfirmDialog component replaces native confirm())
|
||||
- Workspace path validation (rejects system directories)
|
||||
- Task detail auto-cleanup (taskStack clears when viewed task is deleted or list switches)
|
||||
- Swipe gestures on mobile: swipe left/right on a task to toggle completion (swipe direction depends on current status)
|
||||
- Accessibility: ARIA labels/roles on interactive components, keyboard handlers, `prefers-reduced-motion` CSS support
|
||||
|
||||
### GUI features NOT yet done
|
||||
|
|
|
|||
12
PLAN.md
12
PLAN.md
|
|
@ -123,6 +123,7 @@ WorkspaceConfig {
|
|||
webdav_url: Option<String>,
|
||||
webdav_path: Option<String>, // User-selected remote folder
|
||||
google_account: Option<String>, // Email/display name (GoogleTasks workspaces)
|
||||
last_sync: Option<DateTime>, // Timestamp of last successful sync
|
||||
theme: Option<String>,
|
||||
sync_interval_secs: Option<u64>, // Auto-sync polling interval (focused)
|
||||
sync_interval_unfocused_secs: Option<u64>, // Auto-sync interval when unfocused
|
||||
|
|
@ -750,10 +751,10 @@ WorkspaceConfig {
|
|||
- [x] Mark tasks complete/incomplete with animated transitions
|
||||
- [x] Drag-and-drop task reordering
|
||||
- [x] Sliding lists drawer (80cqi wide, left side)
|
||||
- [x] Settings popup overlay (WebDAV config, dark mode toggle)
|
||||
- [x] Dark mode (GNOME-style neutral theme, cyan-blue accent)
|
||||
- [x] Settings popup overlay (WebDAV config, theme selector, window decorations)
|
||||
- [x] Per-workspace theme system (System default, Light, Dark, Nord, Dracula, Solarized Dark, Black and Gold, Ink)
|
||||
- [x] Animated completed section show/hide
|
||||
- [x] Move task between lists (kebab menu → "Move to..." submenu in task detail view)
|
||||
- [x] Move task between lists (inline list in task kebab menu, no submenu)
|
||||
- [x] Optional time on due dates (`has_time: bool` field on Task with `#[serde(default)]` for backward compat; replaces the hours==0 heuristic)
|
||||
- [x] Due date picker/editor (DateTimePicker component in both new task toast + task detail view)
|
||||
- [x] WebDAV setup flow with credentials (settings auto-populates URL/username/password from config + keychain on open)
|
||||
|
|
@ -908,7 +909,8 @@ npm run tauri ios build
|
|||
- [ ] Multiple windows (optional)
|
||||
|
||||
#### Mobile-Specific
|
||||
- [x] Swipe gestures (swipe to complete, swipe to delete)
|
||||
- [x] Swipe gestures (swipe to toggle completion; direction depends on current task status)
|
||||
- [ ] Swipe to delete
|
||||
- [ ] Pull-to-refresh
|
||||
- [ ] Touch-optimized UI elements
|
||||
- [ ] Larger touch targets
|
||||
|
|
@ -977,7 +979,7 @@ npm run tauri ios build
|
|||
#### Google Tasks Importer
|
||||
- [x] `google_tasks.rs` module in `onyx-core` — client, UUID mapping, read-only sync (remote always wins)
|
||||
- [x] `GoogleTasks` workspace mode and `google_account` config field
|
||||
- [x] Tauri commands: `google_tasks_authorize()`, `google_tasks_sync()`
|
||||
- [x] Tauri commands: `start_google_oauth()`, `add_google_tasks_workspace()`, `sync_google_tasks_workspace()`
|
||||
- [ ] Complete OAuth flow (client ID/secret placeholders need real credentials)
|
||||
- [ ] Migrate tasks, lists, due dates, notes with full UI integration
|
||||
- [ ] Preserve task hierarchy and order
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ onyx/
|
|||
- Drag-and-drop reordering
|
||||
- Sliding lists drawer, settings popup
|
||||
- Workspace switcher with add/remove
|
||||
- Dark mode (GNOME-style neutral grays, cyan-blue accent)
|
||||
- Per-workspace theme system (System default, Light, Dark, Nord, Dracula, Solarized Dark, Black and Gold, Ink)
|
||||
- Due date picker/editor with optional time
|
||||
- Subtask hierarchy with three-panel slide navigation
|
||||
- Move tasks between lists
|
||||
|
|
@ -64,6 +64,7 @@ onyx/
|
|||
- WebDAV setup flow with credential auto-population
|
||||
- File watcher (auto-reloads on external changes)
|
||||
- Auto-sync with configurable interval, status indicators
|
||||
- Swipe gestures on mobile (swipe to toggle completion)
|
||||
- Custom confirmation dialogs
|
||||
- Desktop packaging (Linux: AppImage + .deb; Windows: MSI)
|
||||
|
||||
|
|
|
|||
14
docs/API.md
14
docs/API.md
|
|
@ -207,6 +207,20 @@ let list = repo.get_list(list_id)?;
|
|||
repo.delete_list(list_id)?;
|
||||
```
|
||||
|
||||
#### Rename List
|
||||
|
||||
```rust
|
||||
repo.rename_list(list_id, "New Name".to_string())?;
|
||||
```
|
||||
|
||||
#### Move Task Between Lists
|
||||
|
||||
```rust
|
||||
// Atomically moves a task from one list to another.
|
||||
// If the delete-from-source step fails, the copy in the destination is rolled back.
|
||||
repo.move_task(from_list_id, to_list_id, task_id)?;
|
||||
```
|
||||
|
||||
### Task Ordering
|
||||
|
||||
#### Reorder Task
|
||||
|
|
|
|||
Loading…
Reference in a new issue