fix(mac): avoid collapsed context pills in menu

This commit is contained in:
Peter Steinberger
2025-12-13 00:50:55 +00:00
parent 8cc2dc715c
commit 19ce08b4d0

View File

@@ -18,11 +18,12 @@ struct MenuContent: View {
@State private var sessionMenu: [SessionRow] = [] @State private var sessionMenu: [SessionRow] = []
@State private var contextSessions: [SessionRow] = [] @State private var contextSessions: [SessionRow] = []
@State private var contextActiveCount: Int = 0 @State private var contextActiveCount: Int = 0
@State private var contextCardWidth: CGFloat = 0 @State private var contextCardWidth: CGFloat = 280
private let activeSessionWindowSeconds: TimeInterval = 24 * 60 * 60 private let activeSessionWindowSeconds: TimeInterval = 24 * 60 * 60
private let contextCardPadding: CGFloat = 10 private let contextCardPadding: CGFloat = 10
private let contextPillHeight: CGFloat = 16 private let contextPillHeight: CGFloat = 16
private let contextFallbackWidth: CGFloat = 280
var body: some View { var body: some View {
VStack(alignment: .leading, spacing: 8) { VStack(alignment: .leading, spacing: 8) {
@@ -293,7 +294,7 @@ struct MenuContent: View {
} }
.onWidthChange { width in .onWidthChange { width in
// Keep a stable width; menu measurement can be noisy across opens. // Keep a stable width; menu measurement can be noisy across opens.
let next = max(0, width) let next = max(self.contextFallbackWidth, width)
if abs(next - self.contextCardWidth) > 1 { if abs(next - self.contextCardWidth) > 1 {
self.contextCardWidth = next self.contextCardWidth = next
} }
@@ -310,10 +311,9 @@ struct MenuContent: View {
return "\(count) active sessions" return "\(count) active sessions"
} }
private var contextPillWidth: CGFloat? { private var contextPillWidth: CGFloat {
let width = self.contextCardWidth let base = self.contextCardWidth > 0 ? self.contextCardWidth : self.contextFallbackWidth
guard width > 0 else { return nil } return max(1, base - (self.contextCardPadding * 2))
return max(1, width - (self.contextCardPadding * 2))
} }
@ViewBuilder @ViewBuilder
@@ -321,55 +321,29 @@ struct MenuContent: View {
let label = row.key let label = row.key
let summary = row.tokens.contextSummaryShort let summary = row.tokens.contextSummaryShort
Group { let width = self.contextPillWidth
if let width = self.contextPillWidth { ZStack(alignment: .center) {
ZStack(alignment: .center) { ContextUsageBar(
ContextUsageBar( usedTokens: row.tokens.total,
usedTokens: row.tokens.total, contextTokens: row.tokens.contextTokens,
contextTokens: row.tokens.contextTokens, width: width,
width: width, height: self.contextPillHeight)
height: self.contextPillHeight)
HStack(spacing: 8) { HStack(spacing: 8) {
Text(label) Text(label)
.font(.caption.weight(row.key == "main" ? .semibold : .regular)) .font(.caption.weight(row.key == "main" ? .semibold : .regular))
.lineLimit(1) .lineLimit(1)
.truncationMode(.middle) .truncationMode(.middle)
.layoutPriority(1) .layoutPriority(1)
Spacer(minLength: 8) Spacer(minLength: 8)
Text(summary) Text(summary)
.font(.caption.monospacedDigit()) .font(.caption.monospacedDigit())
.foregroundStyle(.secondary) .foregroundStyle(.secondary)
}
.padding(.horizontal, 8)
.padding(.vertical, 1)
}
.frame(width: width, height: self.contextPillHeight)
} else {
ZStack(alignment: .center) {
ContextUsageBar(
usedTokens: row.tokens.total,
contextTokens: row.tokens.contextTokens,
width: nil,
height: self.contextPillHeight)
HStack(spacing: 8) {
Text(label)
.font(.caption.weight(row.key == "main" ? .semibold : .regular))
.lineLimit(1)
.truncationMode(.middle)
.layoutPriority(1)
Spacer(minLength: 8)
Text(summary)
.font(.caption.monospacedDigit())
.foregroundStyle(.secondary)
}
.padding(.horizontal, 8)
.padding(.vertical, 1)
}
.frame(height: self.contextPillHeight)
} }
.padding(.horizontal, 8)
.padding(.vertical, 1)
} }
.frame(width: width, height: self.contextPillHeight)
} }
private var heartbeatStatusRow: some View { private var heartbeatStatusRow: some View {