mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
Merge pull request #359 from nightah/refactor/calendar-selection-grouping
refactor(calendar): group calendars by accounts in settings
This commit is contained in:
commit
8ff53e0d80
5 changed files with 74 additions and 10 deletions
|
|
@ -146,6 +146,7 @@ class CalendarService: CalendarServiceProviding {
|
||||||
extension CalendarModel {
|
extension CalendarModel {
|
||||||
init(from calendar: EKCalendar) {
|
init(from calendar: EKCalendar) {
|
||||||
self.init(
|
self.init(
|
||||||
|
accountName: calendar.accountTitle,
|
||||||
id: calendar.calendarIdentifier,
|
id: calendar.calendarIdentifier,
|
||||||
title: calendar.title,
|
title: calendar.title,
|
||||||
color: calendar.color,
|
color: calendar.color,
|
||||||
|
|
@ -267,7 +268,7 @@ extension Priority {
|
||||||
|
|
||||||
// MARK: - Helper Extensions
|
// MARK: - Helper Extensions
|
||||||
|
|
||||||
private extension EKCalendar {
|
extension EKCalendar {
|
||||||
var accountTitle: String {
|
var accountTitle: String {
|
||||||
switch source.sourceType {
|
switch source.sourceType {
|
||||||
case .local, .subscribed, .birthdays:
|
case .local, .subscribed, .birthdays:
|
||||||
|
|
|
||||||
|
|
@ -2905,18 +2905,48 @@ struct CalendarSettings: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
Section(header: Text("Select Calendars")) {
|
Section(header: Text("Select Calendars")) {
|
||||||
ForEach(calendarManager.allCalendars, id: \.id) { calendar in
|
let grouped = Dictionary(grouping: calendarManager.allCalendars, by: \.accountName)
|
||||||
Toggle(isOn: Binding(
|
let sortedAccounts = grouped.keys.sorted()
|
||||||
get: { calendarManager.getCalendarSelected(calendar) },
|
|
||||||
set: { isSelected in
|
ForEach(sortedAccounts, id: \.self) { account in
|
||||||
Task {
|
let accountCalendars = grouped[account] ?? []
|
||||||
await calendarManager.setCalendarSelected(calendar, isSelected: isSelected)
|
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -382,6 +382,36 @@ class CalendarManager: ObservableObject {
|
||||||
lastEventsFetchDate = Date()
|
lastEventsFetchDate = Date()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setCalendarsSelected(_ calendars: [CalendarModel], isSelected: Bool) async {
|
||||||
|
var selectionState = Defaults[.calendarSelectionState]
|
||||||
|
let ids = Set(calendars.map { $0.id })
|
||||||
|
|
||||||
|
switch selectionState {
|
||||||
|
case .all:
|
||||||
|
if !isSelected {
|
||||||
|
let identifiers = Set(allCalendars.map { $0.id }).subtracting(ids)
|
||||||
|
selectionState = .selected(identifiers)
|
||||||
|
}
|
||||||
|
case .selected(var identifiers):
|
||||||
|
if isSelected {
|
||||||
|
identifiers.formUnion(ids)
|
||||||
|
} else {
|
||||||
|
identifiers.subtract(ids)
|
||||||
|
}
|
||||||
|
|
||||||
|
if identifiers.isEmpty || identifiers.count == allCalendars.count {
|
||||||
|
selectionState = .all
|
||||||
|
} else {
|
||||||
|
selectionState = .selected(identifiers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Defaults[.calendarSelectionState] = selectionState
|
||||||
|
updateSelectedCalendars()
|
||||||
|
await updateEvents(force: true)
|
||||||
|
await updateLockScreenEvents(force: true)
|
||||||
|
}
|
||||||
|
|
||||||
func setReminderCompleted(reminderID: String, completed: Bool) async {
|
func setReminderCompleted(reminderID: String, completed: Bool) async {
|
||||||
await calendarService.setReminderCompleted(reminderID: reminderID, completed: completed)
|
await calendarService.setReminderCompleted(reminderID: reminderID, completed: completed)
|
||||||
await updateEvents(force: true)
|
await updateEvents(force: true)
|
||||||
|
|
|
||||||
|
|
@ -302,6 +302,7 @@ final class LockScreenWidgetPreviewManager: ObservableObject {
|
||||||
private func applyCalendarPreviewEvents() {
|
private func applyCalendarPreviewEvents() {
|
||||||
let now = Date()
|
let now = Date()
|
||||||
let reminderCalendar = CalendarModel(
|
let reminderCalendar = CalendarModel(
|
||||||
|
accountName: "Preview",
|
||||||
id: "preview.reminders",
|
id: "preview.reminders",
|
||||||
title: "Reminders",
|
title: "Reminders",
|
||||||
color: .systemBlue,
|
color: .systemBlue,
|
||||||
|
|
@ -327,6 +328,7 @@ final class LockScreenWidgetPreviewManager: ObservableObject {
|
||||||
)
|
)
|
||||||
|
|
||||||
let eventCalendar = CalendarModel(
|
let eventCalendar = CalendarModel(
|
||||||
|
accountName: "Preview",
|
||||||
id: "preview.calendar",
|
id: "preview.calendar",
|
||||||
title: "Calendar",
|
title: "Calendar",
|
||||||
color: .systemOrange,
|
color: .systemOrange,
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
import Cocoa
|
import Cocoa
|
||||||
|
|
||||||
struct CalendarModel: Identifiable, Hashable {
|
struct CalendarModel: Identifiable, Hashable {
|
||||||
|
let accountName: String
|
||||||
let id: String
|
let id: String
|
||||||
let title: String
|
let title: String
|
||||||
let color: NSColor
|
let color: NSColor
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue