crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

commit 5f3b3d5ce893c77a5e3b683edb38436e73e458cf
parent 4e4af5250f9160e80fb7cca1f8bc2e098043cf2b
Author: Michael Camilleri <[email protected]>
Date:   Tue, 14 Apr 2026 09:23:00 +0900

Add submit button to calendar picker

Diffstat:
MCrossmate/Views/CalendarDayCell.swift | 16+++++++++++++---
MCrossmate/Views/NYTBrowseView.swift | 37++++++++++++++++++++++++++++++++++++-
2 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/Crossmate/Views/CalendarDayCell.swift b/Crossmate/Views/CalendarDayCell.swift @@ -4,17 +4,22 @@ struct CalendarDayCell: View { let dayNumber: Int let isEnabled: Bool let isToday: Bool + let isSelected: Bool let onTap: () -> Void var body: some View { Button(action: onTap) { Text("\(dayNumber)") .font(.body) - .fontWeight(isToday ? .bold : .regular) + .fontWeight(isToday || isSelected ? .bold : .regular) .frame(maxWidth: .infinity, minHeight: 44) - .foregroundStyle(isEnabled ? Color.primary : Color.secondary.opacity(0.4)) + .foregroundStyle(foregroundColor) .background { - if isToday { + if isSelected { + Circle() + .fill(Color.accentColor) + .frame(width: 36, height: 36) + } else if isToday { Circle() .fill(Color.accentColor.opacity(0.15)) .frame(width: 36, height: 36) @@ -24,4 +29,9 @@ struct CalendarDayCell: View { .buttonStyle(.plain) .disabled(!isEnabled) } + + private var foregroundColor: Color { + if isSelected { return .white } + return isEnabled ? .primary : .secondary.opacity(0.4) + } } diff --git a/Crossmate/Views/NYTBrowseView.swift b/Crossmate/Views/NYTBrowseView.swift @@ -6,6 +6,7 @@ struct NYTBrowseView: View { @Environment(\.nytPuzzleFetcher) private var fetcher @State private var displayedMonth: Date = NYTBrowseView.startOfCurrentMonth() + @State private var selectedDate: Date? @State private var isLoading = false @State private var errorMessage: String? @@ -40,6 +41,7 @@ struct NYTBrowseView: View { weekdayHeader dayGrid Spacer() + confirmButton } .padding() .disabled(isLoading) @@ -112,7 +114,8 @@ struct NYTBrowseView: View { dayNumber: dayNumber, isEnabled: isEnabled(date), isToday: cal.isDateInToday(date), - onTap: { fetch(date) } + isSelected: isSelected(date), + onTap: { selectedDate = date } ) } else { Color.clear.frame(minHeight: 44) @@ -121,6 +124,38 @@ struct NYTBrowseView: View { } } + private var confirmButton: some View { + Button { + if let selectedDate { + fetch(selectedDate) + } + } label: { + Text(confirmButtonTitle) + .font(.headline) + .frame(maxWidth: .infinity) + } + .buttonStyle(.borderedProminent) + .controlSize(.large) + .disabled(selectedDate == nil) + } + + private var confirmButtonTitle: String { + guard let selectedDate else { return "Select a Date" } + let style = Date.FormatStyle( + date: .complete, + time: .omitted, + locale: .current, + calendar: Self.nytCalendar, + timeZone: Self.nytTimeZone + ) + return "Start \(selectedDate.formatted(style))" + } + + private func isSelected(_ date: Date) -> Bool { + guard let selectedDate else { return false } + return Self.nytCalendar.isDate(date, inSameDayAs: selectedDate) + } + // MARK: - Month navigation private func shiftMonth(by delta: Int) {