on master help sign in
feat: show z.ai peak hours in popover

Display peak hours (14:00–18:00 CST / 06:00–10:00 UTC) in the z.ai section with a live orange indicator when currently in peak.

commit82213bb7ffbb1daf341e49ec734c767ebd2908a6 authoriko <mail@iko.soy> dateFri 17 Jul 2026, 14:10 (3 months ago) parentcc4275c
1 file changed+25
UsageMenubar/MenuView.swift+25
UsageMenubar/MenuView.swift+25
@@ -407,6 +407,9 @@ struct MenuView: View {
407407 }
408408 }
409409
410+ // Peak hours notice.
411+ zaiPeakHours
412+
410413 // Sparkline for the z.ai 5-hour % history.
411414 sparkline(
412415 values: viewModel.zaiSparklineValues,
@@ -439,6 +442,28 @@ struct MenuView: View {
439442 }
440443 }
441444
445+ /// z.ai peak hours: 14:00–18:00 CST (UTC+8), i.e. 06:00–10:00 UTC.
446+ /// Limits are most likely to bind during this window.
447+ private var zaiPeakHours: some View {
448+ let inPeak = Self.isZaiPeakHoursNow
449+
450+ return HStack(spacing: 6) {
451+ Circle()
452+ .fill(inPeak ? Color.orange : Color.secondary.opacity(0.4))
453+ .frame(width: 6, height: 6)
454+
455+ Text(inPeak ? "Peak hours now" : "Peak 14:00–18:00 CST")
456+ .font(Self.footnoteFont)
457+ .foregroundColor(inPeak ? .orange : .secondary)
458+ }
459+ }
460+
461+ /// Whether the current UTC time falls within z.ai's peak hours (06:00–10:00 UTC).
462+ private static var isZaiPeakHoursNow: Bool {
463+ let hour = Calendar(identifier: .gregorian).component(.hour, from: Date())
464+ return hour >= 6 && hour < 10
465+ }
466+
442467 /// Formats the time until a z.ai window resets, e.g. "3h 20m".
443468 private static func zaiResetsIn(from date: Date) -> String {
444469 let interval = date.timeIntervalSince(Date())