Realign code with the 2026-07-31 rulings
The trash sorts by modified descending — the arrival rank mint retires (Ranks.isOrderedForTrash one comparator, loader + merged order agree; the legacy deleted: migration stamps modified from the tombstone timestamp where parseable; delete undo steps validate existence-only; agent guide v8). Trash selection goes kind-blind — ranges, marquee, Select All, and the successor walk sweep both kinds; the guard moves to the exits (mixed-payload drop refusal, copy/cut validation). The copy stamping preflight widens back to comment depth (load-scoped posture — the board always loads, the gesture refuses whole). Fixes a latent no-op: trashed-lane drag restore never fired (DragSession.beginLanes hard-coded the board container). 2403 tests in 413 suites green. Claude-Session: https://claude.ai/code/session_01CqjXB7ASoWtbyoGod68k97
This commit is contained in:
@@ -535,6 +535,23 @@ struct BoardDropContext {
|
||||
cancelDrop()
|
||||
return false
|
||||
}
|
||||
// **A mixed-kind drag never leaves the trash** (04-interactions.md ▸ The trash, ruled
|
||||
// 2026-07-31 with kind-blind trash selection): "pickup is allowed — the selection is legal —
|
||||
// but every out-of-trash drop target refuses the mixed payload, and the release surfaces a
|
||||
// notice explaining the rule … the refused drag ends like any refusal, rows staying put".
|
||||
//
|
||||
// One guard for every out-of-trash target, because every one of them funnels through this
|
||||
// commit — the lane masonries, the strip, the cross-board arrivals, and the window fallback
|
||||
// alike. A *within*-trash release cannot reach it: the column declines `.trash`-container
|
||||
// sessions outright (`TrashDrop.accepts`), so a trash-origin drag never holds a `.trash`
|
||||
// proposal, and "within-trash drops stay inert" needs no clause here.
|
||||
//
|
||||
// The notice is the destination board's strip, which is where the user is looking.
|
||||
guard !(session.container == .trash && session.mixesKinds) else {
|
||||
store.banners.postMixedTrashDrag()
|
||||
cancelDrop()
|
||||
return false
|
||||
}
|
||||
let ids = survivors.map { session.members[$0] }
|
||||
let folders = survivors.map { session.folders[$0] }
|
||||
let within = DragLocality.isSameBoard(sourceRoot, store.rootURL)
|
||||
|
||||
Reference in New Issue
Block a user