feat(ui): clipboard observer, system tray & notifications

Merged
MP
7mo ago
+2677-32

Summary

  • Clipboard observer: polls system clipboard every 500ms via tauri-plugin-clipboard-manager, extracts URLs (http/https/ftp/magnet), deduplicates with seen-set (capped at 1000 entries), re-entrancy guard on start()
  • System tray: menu with Pause All, Resume All, Clipboard Monitoring toggle (CheckMenuItem), Open Window, Quit; left-click opens/focuses main window
  • Desktop notifications: bridge subscribing to EventBus, notifies on DownloadCompleted and DownloadFailed via tauri-plugin-notification
  • Toggle command: clipboard_toggle IPC command with config persistence and clipboard-monitoring-changed event emission
  • Frontend: ClipboardIndicator in StatusBar with toggle, useClipboardMonitoring hook with async store sync
  • Test infra: Vitest config (jsdom, setup file), Tauri API mocks for frontend tests

Test plan

  • cargo test --workspace — 350 tests pass, 0 warnings
  • npx vitest run — 253 tests pass (8 new: 4 ClipboardIndicator + 4 useClipboardMonitoring)
  • npx tsc --noEmit — TypeScript strict clean
  • cargo clippy -- -D warnings — 0 warnings
  • Lefthook pre-commit hooks pass (no-secrets, rust-fmt, ts-lint, rust-clippy)
  • Manual: enable clipboard monitoring, copy URL, verify event fires
  • Manual: right-click tray icon, verify menu items work
  • Manual: complete a download, verify notification appears

Known gaps (deferred)

  • CAPTCHA notification: no CAPTCHA domain events exist yet
  • Tray icon animation: needs animated icon assets
  • get_urls() dispatch loop: added when AppState is wired (task-16 TODO)

Summary by cubic

Adds clipboard monitoring, a system tray, and desktop notifications to improve background control and feedback. Implements Linear #22 by auto-detecting copied URLs (bracket-aware trimming preserves IPv6 like http://[::1], supports single‑char and short hosts like ftp://a), quick tray actions, and reliable completion/failure alerts.

  • New Features

    • Clipboard observer polls every 500ms, extracts http/https/ftp/magnet URLs via greedy match with bracket-aware trailing punctuation stripping (preserves IPv6), dedupes with a capped seen-set, and emits ClipboardUrlDetected; removed redundant length filter so short FTP URLs are properly detected; JoinHandle-based cancellation prevents duplicate loops.
    • Tray with Pause All, Resume All, Clipboard Monitoring toggle, Open Window, Quit; left-click focuses the app. Toggle reflects persisted config; actions are wired via AppState when available.
    • IPC: clipboard_toggle (persist-before-toggle with rollback on failure) and clipboard_state; emits clipboard-monitoring-changed.
    • Desktop notifications for DownloadCompleted and DownloadFailed with generic failure text; full error is logged.
    • UI: ClipboardIndicator in StatusBar with toggle and aria-pressed; useClipboardMonitoring hook; tests and Tauri API mocks added (IPv6, short-host, bracket-stripping).
  • Dependencies

    • Enable tauri features tray-icon and image-png; add tauri-plugin-clipboard-manager, tauri-plugin-notification, and regex. Update capabilities to include core:tray:default and notification permissions (notification:allow-notify, notification:allow-request-permission, notification:allow-is-permission-granted).

Summary by CodeRabbit

  • New Features

    • Clipboard monitoring that auto-detects and deduplicates URLs, runtime toggle with persisted preference and frontend events; system tray with Pause/Resume, Clipboard toggle, Open Window, Quit, and tray-click focus; desktop notifications for download results; status bar Clipboard indicator with toggle.
  • Tests

    • Added unit and UI tests for clipboard extraction, indicator, and monitoring hook.
  • Documentation

    • CHANGELOG updated with the Clipboard Observer & System Tray feature.