56 lines
1.7 KiB
Swift
56 lines
1.7 KiB
Swift
import Foundation
|
|
import Combine
|
|
import CoreData
|
|
|
|
@MainActor
|
|
class JournalViewModel: ObservableObject {
|
|
@Published var snapshotNotes: [Snapshot] = []
|
|
@Published var monthlyNotes: [MonthlyNoteItem] = []
|
|
|
|
private let snapshotRepository: SnapshotRepository
|
|
private var cancellables = Set<AnyCancellable>()
|
|
|
|
init(snapshotRepository: SnapshotRepository? = nil) {
|
|
self.snapshotRepository = snapshotRepository ?? SnapshotRepository()
|
|
setupObservers()
|
|
refresh()
|
|
}
|
|
|
|
private func setupObservers() {
|
|
NotificationCenter.default.publisher(for: .NSManagedObjectContextObjectsDidChange)
|
|
.debounce(for: .milliseconds(300), scheduler: DispatchQueue.main)
|
|
.sink { [weak self] _ in
|
|
self?.refresh()
|
|
}
|
|
.store(in: &cancellables)
|
|
}
|
|
|
|
func refresh() {
|
|
snapshotNotes = snapshotRepository.fetchAllSnapshots()
|
|
.sorted { $0.date > $1.date }
|
|
let snapshotMonths = Set(snapshotNotes.map { $0.date.startOfMonth })
|
|
let noteMonths = Set(MonthlyCheckInStore.allNotes().map { $0.date.startOfMonth })
|
|
let allMonths = snapshotMonths.union(noteMonths)
|
|
|
|
monthlyNotes = allMonths
|
|
.sorted(by: >)
|
|
.map { date -> MonthlyNoteItem in
|
|
let entry = MonthlyCheckInStore.entry(for: date)
|
|
return MonthlyNoteItem(
|
|
date: date,
|
|
note: entry?.note ?? "",
|
|
rating: entry?.rating,
|
|
mood: entry?.mood
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
struct MonthlyNoteItem: Identifiable, Equatable {
|
|
var id: Date { date }
|
|
let date: Date
|
|
let note: String
|
|
let rating: Int?
|
|
let mood: MonthlyCheckInMood?
|
|
}
|