Refuse folder drops at hover, skip them in mixes
04's settled ruling: the attachment model is flat top-level files, so a drag containing only folders never engages — no highlight, no proposal, the standard incompatible-payload cursor — and a mixed drag proposes for its files only, importing them at the drop while a loss row names the skipped folders. Hover reads the providers' registered types (anything conforming to public.directory refuses, packages included); commit re-partitions authoritatively from the filesystem, so a synthetic payload that hides its type still can't land a folder. The create path now only ever fires with at least one importable file — the mint-fail-remove dance is gone from the folder case and stays reserved for genuine mid-batch failures. Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
@@ -1669,6 +1669,12 @@ public final class BoardStore {
|
||||
// ordinary store writes, with the drop commits' own rules above (one `performWrite` bracket per
|
||||
// gesture; a vanished or tombstoned destination is a silent no-op, the reload being the
|
||||
// authority; failures are the banner's).
|
||||
//
|
||||
// **Folders never arrive here from a drop.** "Folders are refused at hover" (04-interactions.md):
|
||||
// the gesture refuses a folders-only drag outright and `FinderDrop.land` partitions a mixed one
|
||||
// before it calls either of these, naming the skipped folders in a loss row. Both functions stay
|
||||
// honest about a directory anyway — `BoardWriter.importAttachments` refuses one by design — since
|
||||
// nothing about their contract says a drop is the only caller.
|
||||
|
||||
/// Copies `urls` into `cardID`'s `attachments/` — the drop-on-a-card half.
|
||||
///
|
||||
@@ -1711,9 +1717,9 @@ public final class BoardStore {
|
||||
/// (01-storage-format.md § Frontmatter).
|
||||
///
|
||||
/// **Partial failure is honest, and leaves no half-made card.** The batch stops at the first file
|
||||
/// that cannot be imported — a folder rather than a file, an unreadable source — which banners
|
||||
/// naming it; the cards already made keep their files, matching `importAttachments`' own
|
||||
/// "everything already imported stays landed". The card whose import failed is removed again
|
||||
/// that cannot be imported — an unreadable source, a vanished one, a disk with no room left —
|
||||
/// which banners naming it; the cards already made keep their files, matching `importAttachments`'
|
||||
/// own "everything already imported stays landed". The card whose import failed is removed again
|
||||
/// before the throw: it was minted moments earlier in this same bracket and holds nothing but
|
||||
/// what this call put there, and "creating-then-abandoning never leaves an empty card behind"
|
||||
/// (04-interactions.md ▸ Grammar) is the rule it would otherwise break.
|
||||
|
||||
Reference in New Issue
Block a user