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:
@@ -264,17 +264,15 @@ private struct RecentBoardRow: View {
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 12) {
|
||||
// The board default symbol, on every row.
|
||||
//
|
||||
// The record carries no icon. 02 § Per-board app state settles that it should — "the
|
||||
// row's title and icon are registry-cached too — with live write-through" — and today it
|
||||
// holds only the display name and the counts. An `icon`/`iconColor` stamp joining
|
||||
// `recordClose` (and the store's reload path, which is where the write-through half
|
||||
// lives) is what turns this into the board's own glyph; until then a row that guessed
|
||||
// would be worse than one that is honestly generic.
|
||||
Image(systemName: ItemSymbol.board)
|
||||
// The board's own icon and tint — registry-cached with live write-through (02 §
|
||||
// Per-board app state: "the row's title and icon are registry-cached too — with live
|
||||
// write-through"). A record with no override, or one naming a symbol this system
|
||||
// cannot draw, falls back to the board-default glyph in secondary — the same
|
||||
// lenient-fallback shape every other icon site in the app uses (`ItemSymbol`,
|
||||
// `Palette`), applied here to the registry's cached string instead of a live snapshot.
|
||||
Image(systemName: iconName)
|
||||
.font(.system(size: 22))
|
||||
.foregroundStyle(.secondary)
|
||||
.foregroundStyle(iconTint)
|
||||
.frame(width: 34, height: 34)
|
||||
.accessibilityHidden(true)
|
||||
|
||||
@@ -301,6 +299,25 @@ private struct RecentBoardRow: View {
|
||||
.accessibilityElement(children: .combine)
|
||||
}
|
||||
|
||||
/// `row.icon`'s symbol if it names one this system can draw, the board default otherwise —
|
||||
/// `ItemSymbol.name(_:fallback:)`'s rule, restated for a plain cached string rather than a
|
||||
/// `FieldValue`: a record carries no `FieldValue`, so `missing`/`malformed`/`unrecognized`
|
||||
/// have already folded into one `nil` by the time it reaches here.
|
||||
private var iconName: String {
|
||||
guard let icon = row.icon, ItemSymbol.exists(icon) else { return ItemSymbol.board }
|
||||
return icon
|
||||
}
|
||||
|
||||
/// `row.iconColor`'s tint, or the standard secondary one — `LaneView`'s card-face `iconTint`,
|
||||
/// same fallback, same reason: an uncoloured icon is chrome, and chrome is secondary.
|
||||
private var iconTint: AnyShapeStyle {
|
||||
if let iconColor = row.iconColor, let color = Palette.color(named: iconColor) {
|
||||
AnyShapeStyle(color)
|
||||
} else {
|
||||
AnyShapeStyle(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var caption: some View {
|
||||
switch row.caption {
|
||||
|
||||
Reference in New Issue
Block a user