refactor(calendar): group calendars by accounts in settings

Calendars in the "Select Calendars" settings section are now grouped by their source account with color indicators, making it possible to distinguish calendars that share the same name across different accounts.

Each account group header includes a toggle to select or deselect all calendars in that group.
This commit is contained in:
Amir Zarrinkafsh 2026-03-22 13:19:20 +11:00
commit d39c61c475
No known key found for this signature in database
GPG key ID: ECDB8EF9E77E4EBF
5 changed files with 74 additions and 10 deletions

View file

@ -2905,18 +2905,48 @@ struct CalendarSettings: View {
}
Section(header: Text("Select Calendars")) {
ForEach(calendarManager.allCalendars, id: \.id) { calendar in
Toggle(isOn: Binding(
get: { calendarManager.getCalendarSelected(calendar) },
set: { isSelected in
Task {
await calendarManager.setCalendarSelected(calendar, isSelected: isSelected)
let grouped = Dictionary(grouping: calendarManager.allCalendars, by: \.accountName)
let sortedAccounts = grouped.keys.sorted()
ForEach(sortedAccounts, id: \.self) { account in
let accountCalendars = grouped[account] ?? []
let allAccountSelected = accountCalendars.allSatisfy { calendarManager.getCalendarSelected($0) }
Section(header: HStack {
Text(account)
Spacer()
Toggle("", isOn: Binding(
get: { allAccountSelected },
set: { isSelected in
Task {
await calendarManager.setCalendarsSelected(accountCalendars, isSelected: isSelected)
}
}
))
.labelsHidden()
.toggleStyle(.switch)
.controlSize(.mini)
.disabled(!showCalendar)
}) {
ForEach(accountCalendars, id: \.id) { calendar in
Toggle(isOn: Binding(
get: { calendarManager.getCalendarSelected(calendar) },
set: { isSelected in
Task {
await calendarManager.setCalendarSelected(calendar, isSelected: isSelected)
}
}
)) {
HStack(spacing: 8) {
Circle()
.fill(Color(calendar.color))
.frame(width: 8, height: 8)
Text(calendar.title)
}
}
.disabled(!showCalendar)
}
)) {
Text(calendar.title)
}
.disabled(!showCalendar)
}
}
}