Files
Reflect/Shared/Models/ContentModeViewModel.swift
2022-02-10 11:54:32 -06:00

153 lines
5.7 KiB
Swift

//
// 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()
@Published var numberOfItems = 0
var hasNoData: Bool {
grouped.isEmpty
}
private var numberOfEntries: Int {
var num = 0
grouped.keys.forEach({
let year = grouped[$0]
let monthKeys = year?.keys
monthKeys?.forEach({
num += year![$0]!.count
})
})
return num
// grouped.keys.map{
// grouped[$0]!.values.reduce(0) { sum, array in
// sum + array.count
// }
// }.reduce(0, +)
}
init() {
PersistenceController.shared.switchContainerListeners.append {
self.getGroupedData()
}
updateData()
}
private func getGroupedData() {
grouped = PersistenceController.shared.splitIntoYearMonth()
numberOfItems = numberOfEntries
}
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<MoodEntry>(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, entryType: EntryType) {
PersistenceController.shared.add(mood: mood, forDate: date, entryType: entryType)
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, entryType: .listView)
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
let entryDate = entry.forDate!
PersistenceController.shared.viewContext.delete(entry)
self.add(mood: .missing, forDate: entryDate, entryType: .listView)
})
}
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)")
}
}
}