Materialize the trash — store, undo, and the container universe
Phase 2 swaps every consumer: Liveness and its ancestor walk are gone, replaced by ItemContainer — a UUID set plus the container side it lives on, presence the whole test, one selection boundary instead of the old liveness law. Deletion stages by place: board cards move to the trash at a store-minted head rank, trash-side delete is permanent behind its confirmation, Delete Immediately skips the trash from anywhere, lane delete captures the subtree and removes the folder. Restore has no method at all — moveCards resolves members in either container, so drag-out and cut-paste are the ordinary moves 13 calls them, registering ordinary Move steps. The delete inverse moves the card back to its captured lane and rank; redo replays the captured trash rank, a value the gesture actually wrote; lane undo recreates the subtree byte-faithfully in session. Purges register nothing — where 13's trash section contradicts its own Rules on that, Rules wins, filed for ruling. Staleness collapsed to present-or-absent: a container is a path, so a foreign restore fails the delete step's expectation structurally. Legacy tombstones migrate on the loose-file tail hook, cards oldest-first so minting above top reproduces the retired newest-first column, lanes returning live, one folded loss row naming both directions. Put Back, restoreByDrag, receiveRestoredCards, TrashEntry, and the kind machinery are deleted; the trash column renders the container correctly with its full face rework left to phase 3. Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
@@ -50,10 +50,10 @@ enum PasteTarget {
|
||||
lastActiveLaneID: lastActiveLaneID,
|
||||
snapshot: snapshot
|
||||
),
|
||||
let lane = snapshot.lanes.first(where: { $0.id == resolution.laneID && !$0.isDeleted })
|
||||
let lane = snapshot.lanes.first(where: { $0.id == resolution.laneID })
|
||||
else { return nil }
|
||||
|
||||
let rendered = lane.cards.filter { !$0.isDeleted }
|
||||
let rendered = lane.cards
|
||||
// `insertionIndex` answers `nil` for "append", which is `rendered.count` — the same position
|
||||
// said two ways, and the creation path's own degradation for an anchor that has since gone.
|
||||
let index = BoardStore.insertionIndex(after: resolution.anchorCardID, among: rendered) ?? rendered.count
|
||||
@@ -64,7 +64,7 @@ enum PasteTarget {
|
||||
/// included, because lane paste "stays enabled and lands at the board's right end" whatever the
|
||||
/// board holds. That is what makes it the other way out of a board with no lanes.
|
||||
static func lanes(selection: ItemReferenceSet, snapshot: BoardModel) -> Int {
|
||||
let lanes = snapshot.lanes.filter { !$0.isDeleted }
|
||||
let lanes = snapshot.lanes
|
||||
guard let anchor = NewCardTarget.flattenAnchor(selection: selection, snapshot: snapshot),
|
||||
let position = lanes.firstIndex(where: { $0.id == anchor.laneID })
|
||||
else {
|
||||
|
||||
Reference in New Issue
Block a user