TheNoiseClock/TheNoiseClock/Features/Alarms/Views/Components/RepeatSelectionView.swift
Matt Bruce 8f79836481 added features.
Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
2026-02-08 12:10:38 -06:00

97 lines
3.2 KiB
Swift

//
// RepeatSelectionView.swift
// TheNoiseClock
//
// Created by Matt Bruce on 2/8/26.
//
import SwiftUI
import Bedrock
/// View for selecting repeat days for an alarm.
struct RepeatSelectionView: View {
@Binding var repeatWeekdays: [Int]
private let allWeekdays = [1, 2, 3, 4, 5, 6, 7]
var body: some View {
List {
Section("Quick Picks") {
quickPickRow(id: "once", title: "Once", weekdays: [])
quickPickRow(id: "everyday", title: "Every Day", weekdays: allWeekdays)
quickPickRow(id: "weekdays", title: "Weekdays", weekdays: [2, 3, 4, 5, 6])
quickPickRow(id: "weekends", title: "Weekends", weekdays: [1, 7])
}
Section("Repeat On") {
ForEach(orderedWeekdays, id: \.self) { weekday in
HStack {
Text(dayName(for: weekday))
.foregroundStyle(AppTextColors.primary)
Spacer()
if normalizedWeekdays.contains(weekday) {
Image(systemName: "checkmark")
.foregroundStyle(AppAccent.primary)
}
}
.contentShape(Rectangle())
.listRowBackground(AppSurface.card)
.onTapGesture {
toggleDay(weekday)
}
.accessibilityIdentifier("alarms.repeat.day.\(weekday)")
}
}
}
.listStyle(.insetGrouped)
.scrollContentBackground(.hidden)
.background(AppSurface.primary.ignoresSafeArea())
.navigationTitle("Repeat")
.navigationBarTitleDisplayMode(.inline)
}
private var normalizedWeekdays: [Int] {
Alarm.sanitizedWeekdays(repeatWeekdays)
}
private var orderedWeekdays: [Int] {
let first = max(1, min(Calendar.current.firstWeekday, 7))
return Array(first...7) + Array(1..<first)
}
@ViewBuilder
private func quickPickRow(id: String, title: String, weekdays: [Int]) -> some View {
HStack {
Text(title)
.foregroundStyle(AppTextColors.primary)
Spacer()
if Set(normalizedWeekdays) == Set(Alarm.sanitizedWeekdays(weekdays)) {
Image(systemName: "checkmark")
.foregroundStyle(AppAccent.primary)
}
}
.contentShape(Rectangle())
.listRowBackground(AppSurface.card)
.onTapGesture {
repeatWeekdays = Alarm.sanitizedWeekdays(weekdays)
}
.accessibilityIdentifier("alarms.repeat.quick.\(id)")
}
private func dayName(for weekday: Int) -> String {
let symbols = Calendar.current.weekdaySymbols
guard (1...7).contains(weekday) else { return "" }
return symbols[weekday - 1]
}
private func toggleDay(_ weekday: Int) {
var updated = Set(normalizedWeekdays)
if updated.contains(weekday) {
updated.remove(weekday)
} else {
updated.insert(weekday)
}
repeatWeekdays = Alarm.sanitizedWeekdays(Array(updated))
}
}