The board settings sheet — setup leaves the popover for a home a stray click can't dismiss
The popover/sheet split lands: a board-scoped, titled, sectioned sheet on the board window hosts everything setup-shaped, opened from the popover's Board Settings… row and the new Board ▸ Board Settings… menu row. The three existing setup controls relocate — add-git (whose noteFormVisible lines now make the sheet the form-anchored failure surface), branch creation (a standing field; create-and-switch runs the identical settle sequence), and the commit-identity fields (the 2s visibility-scoped poll rides with them). The popover keeps the daily face and its postures; its Pro/mode-none section becomes header + door (.addGit renamed .noRepository). Availability is derived from the section inventory (Pro + mode none or git), so pro-m2's sections can't drift from the doors; the sheet's fields join the caret-chord disable set. The audit suite pins what the free fixture can reach; the sheet's own audit is manual until a tier override is ruled. Claude-Session: https://claude.ai/code/session_01CqjXB7ASoWtbyoGod68k97
This commit is contained in:
@@ -57,6 +57,12 @@ struct BoardWindowHost: View {
|
||||
/// menu item through the focus system, like the store.
|
||||
@State private var boardInfo = BoardInfoPresentation()
|
||||
|
||||
/// This window's board settings sheet, open or not (03-board-ui.md § Board settings sheet).
|
||||
/// `@State` for `boardInfo`'s reason — one per window — and published the same way, because
|
||||
/// Board ▸ Board Settings… is a menu-bar item that has to reach the frontmost board window, and
|
||||
/// because the sheet is presented *on this window* and modal to it.
|
||||
@State private var boardSettings = BoardSettingsPresentation()
|
||||
|
||||
/// This window's purge alert, open or not (03-board-ui.md § Trash). `@State` for `boardInfo`'s
|
||||
/// reason and reaching the menu bar the same way: File ▸ Delete (landing on a trash selection)
|
||||
/// and Empty Trash… are menu-bar items, and a menu item cannot present anything of its own.
|
||||
@@ -197,6 +203,17 @@ struct BoardWindowHost: View {
|
||||
.onChange(of: boardSearch.isFocused) { _, _ in
|
||||
boardSearch.dismissTransientIfCleared(query: store.searchQuery)
|
||||
}
|
||||
// **The board settings sheet** (03-board-ui.md ▸ Board settings sheet) — presented from
|
||||
// the board window's own content, which is what makes it modal to *this* board rather
|
||||
// than to the app: "a board-scoped, titled, sectioned sheet on the board window".
|
||||
//
|
||||
// It hangs here rather than inside `BoardView` for the reason the popover's flag is a
|
||||
// window's: the two doors that open it are the titlebar popover's row and a menu-bar
|
||||
// item, neither of which is inside the board, and a sheet has to be presented by
|
||||
// something that outlives the surface that asked for it.
|
||||
.sheet(isPresented: $boardSettings.isPresented) {
|
||||
BoardSettingsSheet(store: store, presentation: boardSettings)
|
||||
}
|
||||
// "The board in front", for the menu items that act on it (`LaneWidthCommands`), and
|
||||
// beside it the window's own popover flag, which is what File ▸ Board Info toggles, its
|
||||
// purge-alert host, which the trash's two confirmed commands raise, and its search
|
||||
@@ -207,6 +224,7 @@ struct BoardWindowHost: View {
|
||||
// is keyed on the window rather than on the board it is showing.
|
||||
.focusedSceneValue(\.boardWindowRef, ref)
|
||||
.focusedSceneValue(\.boardInfo, boardInfo)
|
||||
.focusedSceneValue(\.boardSettings, boardSettings)
|
||||
.focusedSceneValue(\.trashConfirmations, trashConfirmations)
|
||||
// Board ▸ Open Card's second half — the same closure `BoardView` gets, so the menu item
|
||||
// and the double-click open one window per card by construction.
|
||||
@@ -694,13 +712,21 @@ struct BoardWindowHost: View {
|
||||
// happen on this path — `beginSession` precedes `configureWindow` — and reads as the free
|
||||
// tier's posture, which is the harmless direction.
|
||||
let session = appModel.session(for: ref)
|
||||
// The settings sheet's two doors validate on the same pair, so they are adopted here rather
|
||||
// than read again somewhere else: the popover's Board Settings… row and Board ▸ Board
|
||||
// Settings… must never disagree about whether this board has setup to show
|
||||
// (`BoardSettingsAvailability`). The mode *inside* the git state stays live — add-git flipping
|
||||
// it re-resolves the sheet's sections and both doors, which is the one mid-session transition
|
||||
// 06 sanctions.
|
||||
boardSettings.adopt(tier: session?.tier ?? .free, git: session?.git)
|
||||
windowController.installTitlebarAccessory(
|
||||
boardInfoTitlebarAccessory(
|
||||
store: store,
|
||||
recents: appModel.styleRecents,
|
||||
tier: session?.tier ?? .free,
|
||||
git: session?.git,
|
||||
presentation: boardInfo
|
||||
presentation: boardInfo,
|
||||
settings: boardSettings
|
||||
)
|
||||
)
|
||||
// The widget above now says the board's name (and, on a git-mode Pro board, its branch)
|
||||
|
||||
Reference in New Issue
Block a user