Commit Graph

2 Commits

Author SHA1 Message Date
Dal Rupnik 100fc1e8bc fix: harden drag-and-drop against the edge-case report
Introduces DropHandler to own the drop pipeline and addresses every item
from the review:

- Folders / .app bundles / packages: DropProgressCopier.copyTree walks
  directories instead of failing with a generic 'Failed to copy'.
- File promises (Photos, Mail, browser image drags) are now accepted and
  materialized instead of silently no-opping.
- Multi-file toast race: per-file DropSession id; stale relocation
  results for a superseded file are ignored by update/finish/
  setFinalDestination.
- Partial files: copyTree removes its partial output on any error, and
  the handler drops the now-empty subdir, so the guest never sees a
  truncated file.
- Teardown race: in-flight guest relocations register with
  RelocationGate; 'tart run' drains it (<=6s) before deleting the drop
  zone / exiting.
- Path collisions: each file copies into its own dropRoot/<uuid>/ subdir.
- Reserved name: a user --dir named 'Dropped Files' is now rejected.
- Linux / no agent: relocation is skipped and the toast says 'Copied to
  the shared folder' instead of a misleading Finder destination.
- Agent-down timing: success toast holds on a fallback timer that
  outlives the 5s RPC deadline so the final destination is always shown.
- Concurrency: relocations run one-at-a-time; copy failures are
  coalesced into a single alert instead of a modal storm.
- Zero-byte/unknown size shows just the copied amount, not '0 bytes of ?'.
- Removed dead DropFolderBox + stale doc comment; fixed the
  http://-vs-https:// typo in toRemoteOrLocalURL.

Tests: DropProgressCopierTests (replace/cancel/error-cleanup/empty/
directory/size), GuestDropParseTests (stdout parser), and a reserved-name
case in DirectoryShareTests. Product and test target both compile.
2026-05-20 10:15:08 +02:00
Dal Rupnik 93d5708c08 refactor: split DropProgressToast into focused sub-250-line files
DropProgressToast.swift (436 lines) bundled four responsibilities. Split
verbatim into:

- DropCancellationToken.swift  - cancel token + DropCopyCancelled sentinel
- DropProgressCopier.swift     - chunked file copier
- DropProgressToast.swift      - toast state/coordination (lifecycle API)
- DropProgressToast+Panel.swift - AppKit panel construction/positioning

Each file is well under 250 lines and single-responsibility. The only
non-move change is widening the members the +Panel extension references
from private to internal; no behavior, signatures, or logic changed.
2026-05-20 10:15:08 +02:00