// // ContentModeViewModel.swift // Feels (iOS) // // Created by Trey Tartt on 1/20/22. // import SwiftUI import CoreData class ContentModeViewModel: ObservableObject { @Published var grouped = [Int: [Int: [MoodEntry]]]() @Published public private(set) var savedOnboardingData = UserDefaultsStore.getOnboarding() init() { updateData() } private func getGroupedData() { grouped = PersistenceController.shared.splitIntoYearMonth() } public func shouldShowVotingHeader() -> Bool { isMissingCurrentVote() && savedOnboardingData.ableToVoteBasedOnCurentTime() ? true : false } public func updateOnboardingData(onboardingData: OnboardingData) { self.savedOnboardingData = UserDefaultsStore.saveOnboarding(onboardingData: onboardingData) LocalNotification.scheduleReminder(atTime: onboardingData.date, withTitle: onboardingData.title) } private func isMissingCurrentVote() -> Bool { let fetchRequest = NSFetchRequest(entityName: "MoodEntry") var calendar = Calendar.current calendar.timeZone = NSTimeZone.local var dateFrom: Date switch savedOnboardingData.inputDay { case .Today: dateFrom = calendar.startOfDay(for: Date()) case .Previous: dateFrom = calendar.startOfDay(for: Date()) dateFrom = calendar.date(byAdding: .day, value: -1, to: dateFrom)! } let dateTo = calendar.date(byAdding: .day, value: 1, to: dateFrom)! let fromPredicate = NSPredicate(format: "%@ <= %K", dateFrom as NSDate, #keyPath(MoodEntry.forDate)) let toPredicate = NSPredicate(format: "%K < %@", #keyPath(MoodEntry.forDate), dateTo as NSDate) let datePredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [fromPredicate, toPredicate]) fetchRequest.predicate = datePredicate let entries = try! PersistenceController.shared.viewContext.count(for: fetchRequest) return entries == 0 } public func updateData() { getGroupedData() } public func add(mood: Mood, forDate date: Date) { PersistenceController.shared.add(mood: mood, forDate: date) getGroupedData() } public func update(entry: MoodEntry, toMood mood: Mood) { let forDate = entry.forDate! if let entry = PersistenceController.shared.getEntry(byDate: entry.forDate!) { PersistenceController.shared.viewContext.delete(entry) } do { try PersistenceController.shared.viewContext.save() getGroupedData() } catch { // Replace this implementation with code to handle the error appropriately. // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } PersistenceController.shared.add(mood: mood, forDate: forDate) do { try PersistenceController.shared.viewContext.save() getGroupedData() } catch { // Replace this implementation with code to handle the error appropriately. // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } public func delete(offsets: IndexSet, inMonth month: Int, inYear year: Int) { if let monthEntries = grouped[year], let entries = monthEntries[month] { var mutableEntries = entries.sorted(by: { $0.forDate! > $1.forDate! }) var entriesToDelete = [MoodEntry]() for idx in offsets { let obj = mutableEntries.remove(at: idx) entriesToDelete.append(obj) } entriesToDelete.forEach({ entry in PersistenceController.shared.viewContext.delete(entry) }) } do { try PersistenceController.shared.viewContext.save() getGroupedData() } catch { // Replace this implementation with code to handle the error appropriately. // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } }