163 lines
6.2 KiB
Swift
163 lines
6.2 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 {
|
|
if isMissingCurrentVote() {
|
|
return true
|
|
}
|
|
|
|
return 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 latestVoteUnLocked = UserDefaultsStore.getOnboarding().ableToVoteBasedOnCurentTime()
|
|
let inputDay = UserDefaultsStore.getOnboarding().inputDay
|
|
|
|
var startDate: Date?
|
|
|
|
switch (latestVoteUnLocked, inputDay) {
|
|
case (true, .Previous):
|
|
startDate = Calendar.current.date(byAdding: .day, value: -1, to: Date())!
|
|
case (true, .Today):
|
|
startDate = Date()
|
|
case (false, .Previous):
|
|
startDate = Calendar.current.date(byAdding: .day, value: -2, to: Date())!
|
|
case (false, .Today):
|
|
startDate = Calendar.current.date(byAdding: .day, value: -1, to: Date())!
|
|
}
|
|
|
|
startDate = Calendar.current.startOfDay(for: startDate!)
|
|
let endDate = Calendar.current.date(byAdding: .day, value: 1, to: startDate!)!
|
|
|
|
let fetchRequest = NSFetchRequest<MoodEntry>(entityName: "MoodEntry")
|
|
let fromPredicate = NSPredicate(format: "%@ <= %K", startDate!
|
|
as NSDate, #keyPath(MoodEntry.forDate))
|
|
let toPredicate = NSPredicate(format: "%K < %@", #keyPath(MoodEntry.forDate), endDate 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)")
|
|
}
|
|
}
|
|
}
|