Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 20 additions & 19 deletions clients/macos/vellum-assistant/Features/Chat/ChatView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -399,10 +399,16 @@ struct ChatView: View {

if let until = viewModel.compactionCircuitOpenUntil, until > Date() {
centeredChatColumn(width: max(layoutMetrics.chatColumnWidth - 2 * VSpacing.xl, 0)) {
CompactionCircuitOpenBanner(
openUntil: until,
onExpired: { viewModel.compactionCircuitOpenUntil = nil }
)
// CompactionCircuitOpenBanner is natural-width; spacers center it
// within the fixed column instead of leading-aligning it.
HStack(spacing: 0) {
Spacer(minLength: 0)
CompactionCircuitOpenBanner(
openUntil: until,
onExpired: { viewModel.compactionCircuitOpenUntil = nil }
)
Spacer(minLength: 0)
}
}
.padding(.bottom, -VSpacing.sm)
.animation(nil, value: queuedMessages.isEmpty)
Expand Down Expand Up @@ -529,29 +535,24 @@ struct ChatView: View {
)
}

/// Centers chat chrome at the chat-column width using `FixedWidthLayout`.
/// Centers a fixed-width column inside the available chat area.
///
/// `FixedWidthLayout` returns `nil` from `explicitAlignment` and places its
/// child via a `UnitPoint` anchor rather than alignment guides, so it acts
/// as a barrier to parent-initiated alignment queries on the subtree. The
/// inner `HStack { Spacer; content; Spacer }` reproduces the horizontal
/// `.center` positioning that `.frame(width:)` applied to non-filling
/// content; flexible content (anything with `.frame(maxWidth: .infinity)`
/// or an internal `Spacer`) collapses the inner spacers to zero and
/// occupies the full column width.
/// Sizes `content` with `FixedWidthLayout` so the column has a definite
/// width and `placeSubviews` does not query `explicitAlignment` on the
/// subtree. Flanking `Spacer`s split any remaining horizontal space to
/// keep the column horizontally centered on the page. The helper does
/// NOT center content within the column; callers that pass natural-width
/// content (no internal `Spacer`, no `.frame(maxWidth: .infinity)`) and
/// want it centered must wrap it themselves. See `MessageListView` for
/// the same pattern.
@ViewBuilder
private func centeredChatColumn<Content: View>(
width: CGFloat,
@ViewBuilder content: () -> Content
) -> some View {
HStack(spacing: 0) {
Spacer(minLength: 0)
HStack(spacing: 0) {
Spacer(minLength: 0)
content()
Spacer(minLength: 0)
}
.fixedWidth(width)
content().fixedWidth(width)
Spacer(minLength: 0)
}
}
Expand Down