commit b5b7b6e04ce569cdfd3bffb0b1b4038fa16c7be5
parent 8257d1666f32689c3273cf83c159a6ea4fa40b30
Author: Michael Camilleri <[email protected]>
Date: Thu, 21 May 2026 12:47:00 +0900
Improve NYT date navigation
This commit adds a tappable month title that opens a compact wheel date picker
with Cancel and Done controls, allowing archive jumps without applying changes
until confirmed.
Co-Authored-By: Codex GPT 5.5 <[email protected]>
Diffstat:
1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/Crossmate/Views/NYTBrowseView.swift b/Crossmate/Views/NYTBrowseView.swift
@@ -10,6 +10,8 @@ struct NYTBrowseView: View {
@State private var isLoading = false
@State private var errorMessage: String?
@State private var sessionExpired = false
+ @State private var showingMonthPicker = false
+ @State private var pickerDate: Date = NYTBrowseView.startOfCurrentMonth()
private static let nytTimeZone = TimeZone(identifier: "America/New_York")!
@@ -86,8 +88,22 @@ struct NYTBrowseView: View {
Spacer()
- Text(monthTitle)
+ Button {
+ pickerDate = selectedDate ?? displayedMonth
+ showingMonthPicker = true
+ } label: {
+ HStack(spacing: 4) {
+ Text(monthTitle)
+ Image(systemName: "chevron.down")
+ .font(.caption.weight(.semibold))
+ }
.font(.headline)
+ }
+ .buttonStyle(.plain)
+ .popover(isPresented: $showingMonthPicker) {
+ dateWheelPopover
+ .presentationCompactAdaptation(.popover)
+ }
Spacer()
@@ -159,6 +175,40 @@ struct NYTBrowseView: View {
return "Start \(selectedDate.formatted(style))"
}
+ private var dateWheelPopover: some View {
+ VStack(spacing: 14) {
+ HStack {
+ Button("Cancel", role: .cancel) {
+ showingMonthPicker = false
+ }
+
+ Spacer()
+
+ Button("Done") {
+ selectedDate = pickerDate
+ displayedMonth = startOfMonth(for: pickerDate)
+ showingMonthPicker = false
+ }
+ .buttonStyle(.borderedProminent)
+ }
+
+ DatePicker(
+ "Puzzle Date",
+ selection: $pickerDate,
+ in: Self.minDate...Date(),
+ displayedComponents: .date
+ )
+ .datePickerStyle(.wheel)
+ .labelsHidden()
+ .environment(\.calendar, Self.nytCalendar)
+ .environment(\.timeZone, Self.nytTimeZone)
+ .frame(width: 320, height: 160)
+ .clipped()
+ }
+ .padding(.horizontal)
+ .padding(.vertical, 8)
+ }
+
private func isSelected(_ date: Date) -> Bool {
guard let selectedDate else { return false }
return Self.nytCalendar.isDate(date, inSameDayAs: selectedDate)
@@ -173,6 +223,12 @@ struct NYTBrowseView: View {
}
}
+ private func startOfMonth(for date: Date) -> Date {
+ let cal = Self.nytCalendar
+ let components = cal.dateComponents([.year, .month], from: date)
+ return cal.date(from: components) ?? date
+ }
+
private var monthTitle: String {
let formatter = DateFormatter()
formatter.calendar = Self.nytCalendar