120 lines
4.0 KiB
Swift
120 lines
4.0 KiB
Swift
import SwiftUI
|
|
import SwiftData
|
|
import EventKit
|
|
|
|
@MainActor
|
|
final class SettingsViewModel: ObservableObject {
|
|
@Published var availableCalendars: [EKCalendar] = []
|
|
@Published var showCalendarPermissionAlert: Bool = false
|
|
@Published var showToast: Bool = false
|
|
@Published var toastMessage: String = ""
|
|
|
|
func loadCalendars() {
|
|
availableCalendars = CalendarService.shared.availableCalendars()
|
|
}
|
|
|
|
@discardableResult
|
|
func ensureValidCalendarSelection(settings: AppSettings) -> Bool {
|
|
loadCalendars()
|
|
|
|
guard !availableCalendars.isEmpty else {
|
|
settings.calendarId = nil
|
|
settings.syncEnabled = false
|
|
showToastMessage(String(localized: "toast_calendar_unavailable"))
|
|
return false
|
|
}
|
|
|
|
if let selected = settings.calendarId,
|
|
availableCalendars.contains(where: { $0.calendarIdentifier == selected }) {
|
|
return true
|
|
}
|
|
|
|
settings.calendarId = availableCalendars.first?.calendarIdentifier
|
|
return true
|
|
}
|
|
|
|
func requestCalendarAccess() async -> Bool {
|
|
let granted = await CalendarService.shared.requestAccess()
|
|
if !granted {
|
|
showCalendarPermissionAlert = true
|
|
} else {
|
|
loadCalendars()
|
|
}
|
|
return granted
|
|
}
|
|
|
|
func openSystemSettings() {
|
|
if let url = URL(string: UIApplication.openSettingsURLString) {
|
|
UIApplication.shared.open(url)
|
|
}
|
|
}
|
|
|
|
func updateCalendarEvents(settings: AppSettings, plan: WeekPlan?) {
|
|
guard let plan = plan, settings.syncEnabled else { return }
|
|
CalendarService.shared.updateEventsTime(
|
|
slots: plan.slots,
|
|
weekStartDate: plan.weekStartDate,
|
|
settings: settings
|
|
)
|
|
}
|
|
|
|
func resetAllData(context: ModelContext) {
|
|
do {
|
|
try deleteAll(of: MealSlot.self, in: context)
|
|
try deleteAll(of: WeekPlan.self, in: context)
|
|
try deleteAll(of: Dish.self, in: context)
|
|
try deleteAll(of: Tag.self, in: context)
|
|
DefaultDataService.createDefaultTags(context: context)
|
|
|
|
let settingsDescriptor = FetchDescriptor<AppSettings>()
|
|
if let existingSettings = try context.fetch(settingsDescriptor).first {
|
|
resetSettings(existingSettings)
|
|
} else {
|
|
DefaultDataService.createDefaultSettings(context: context)
|
|
if let createdSettings = try context.fetch(settingsDescriptor).first {
|
|
resetSettings(createdSettings)
|
|
}
|
|
}
|
|
|
|
try context.save()
|
|
} catch {
|
|
#if DEBUG
|
|
print("Failed to reset all data: \(error)")
|
|
#endif
|
|
}
|
|
}
|
|
|
|
private func deleteAll<T: PersistentModel>(of type: T.Type, in context: ModelContext) throws {
|
|
let descriptor = FetchDescriptor<T>()
|
|
let models = try context.fetch(descriptor)
|
|
for model in models {
|
|
context.delete(model)
|
|
}
|
|
try context.save()
|
|
}
|
|
|
|
private func showToastMessage(_ message: String) {
|
|
toastMessage = message
|
|
withAnimation(.easeInOut(duration: 0.2)) {
|
|
showToast = true
|
|
}
|
|
}
|
|
|
|
private func resetSettings(_ settings: AppSettings) {
|
|
let defaults = AppSettings()
|
|
settings.mealWindows = defaults.mealWindows
|
|
settings.includeWeekends = defaults.includeWeekends
|
|
settings.language = defaults.language
|
|
settings.calendarId = defaults.calendarId
|
|
settings.syncEnabled = defaults.syncEnabled
|
|
settings.syncMode = defaults.syncMode
|
|
settings.lunchTime = defaults.lunchTime
|
|
settings.dinnerTime = defaults.dinnerTime
|
|
settings.eventDuration = defaults.eventDuration
|
|
settings.eventPrefix = defaults.eventPrefix
|
|
settings.reminderMinutesBefore = defaults.reminderMinutesBefore
|
|
settings.iCloudSyncEnabled = false
|
|
settings.onboardingCompleted = false
|
|
}
|
|
}
|