Give the registry live display-state write-through and record-before-load

BoardRecord carries icon/iconColor; recordOpen/recordClose stamp them with the
display name, and a displayStateDelegate on the store (wired in BoardWindowHost
beside onFrameChanged) syncs all three through BoardRegistry.syncDisplayState on
every successful reload — welcome rows now wear the board's own icon and follow
in-app renames live. recordOpen now runs before the load with the folder name as
a brand-new record's provisional display name, so a first open that fails
fail-fast still lands in recents carrying the failure row-level (02's rule); an
existing record's cached name survives a failing retry, and the welcome fallback
list remains only for failures naming no record at all.

Claude-Session: https://claude.ai/code/session_01CqjXB7ASoWtbyoGod68k97
This commit is contained in:
2026-07-27 20:44:30 -04:00
parent cacd48cb0f
commit f2d9f3ad07
10 changed files with 608 additions and 41 deletions
+26 -2
View File
@@ -23,7 +23,9 @@ private func record(
at path: String,
lanes: Int? = nil,
cards: Int? = nil,
opened: Date = Date()
opened: Date = Date(),
icon: String? = nil,
iconColor: String? = nil
) -> BoardRecord {
BoardRecord(
bookmark: Data(),
@@ -31,7 +33,9 @@ private func record(
lastKnownPath: path,
lastOpened: opened,
laneCount: lanes,
cardCount: cards
cardCount: cards,
icon: icon,
iconColor: iconColor
)
}
@@ -208,6 +212,26 @@ struct WelcomeRowTests {
"the sort rule lives in BoardRegistry.recents() and must not be duplicated here")
}
@Test("A record's cached icon and iconColor ride straight through to its row")
func iconAndIconColorPassThrough() throws {
let recent = available(record(name: "Roadmap", at: "/Boards/Roadmap.kanban", icon: "star.fill", iconColor: "fern"))
let row = try #require(WelcomeRow.derive(recents: [recent], failures: []).rows.first)
#expect(row.icon == "star.fill")
#expect(row.iconColor == "fern")
}
@Test("A record with no cached icon carries nil through to its row — the renderer's default to draw")
func noIconIsNilNotAGuess() throws {
let recent = available(record(name: "Roadmap", at: "/Boards/Roadmap.kanban"))
let row = try #require(WelcomeRow.derive(recents: [recent], failures: []).rows.first)
#expect(row.icon == nil)
#expect(row.iconColor == nil)
}
@Test("A record with no display name falls back to its folder name, extension stripped")
func displayNameFallsBackToTheFolderName() {
let recent = available(record(name: "", at: "/Boards/Untitled.kanban"))