Files
omnivore/apple/OmnivoreKit/Sources/App/Views/Highlights/NotebookViewModel.swift
2023-04-10 15:59:40 +08:00

96 lines
3.2 KiB
Swift

import CoreData
import Models
import Services
import SwiftUI
import Views
struct HighlightListItemParams: Identifiable {
let id = UUID()
let highlightID: String
let title: String
let annotation: String
let quote: String
let labels: [LinkedItemLabel]
let createdBy: InternalUserProfile?
}
@MainActor final class NotebookViewModel: ObservableObject {
@Published var highlightItems = [HighlightListItemParams]()
func load(itemObjectID: NSManagedObjectID, dataService: DataService) {
if let linkedItem = dataService.viewContext.object(with: itemObjectID) as? LinkedItem {
loadHighlights(item: linkedItem)
}
}
func updateAnnotation(highlightID: String, annotation: String, dataService: DataService) {
dataService.updateHighlightAttributes(highlightID: highlightID, annotation: annotation)
if let index = highlightItems.firstIndex(where: { $0.highlightID == highlightID }) {
highlightItems[index] = HighlightListItemParams(
highlightID: highlightID,
title: highlightItems[index].title,
annotation: annotation,
quote: highlightItems[index].quote,
labels: highlightItems[index].labels,
createdBy: highlightItems[index].createdBy
)
}
}
func deleteHighlight(highlightID: String, dataService: DataService) {
dataService.deleteHighlight(highlightID: highlightID)
highlightItems.removeAll { $0.highlightID == highlightID }
}
func setLabelsForHighlight(highlightID: String, labels: [LinkedItemLabel], dataService: DataService) {
dataService.setLabelsForHighlight(highlightID: highlightID, labelIDs: labels.map(\.unwrappedID))
if let index = highlightItems.firstIndex(where: { $0.highlightID == highlightID }) {
highlightItems[index] = HighlightListItemParams(
highlightID: highlightID,
title: highlightItems[index].title,
annotation: highlightItems[index].annotation,
quote: highlightItems[index].quote,
labels: labels,
createdBy: highlightItems[index].createdBy
)
}
}
func highlightAsMarkdown(item: HighlightListItemParams) -> String {
var buffer = "> \(item.quote)"
if !item.annotation.isEmpty {
buffer += "\n\n\(item.annotation)"
}
buffer += "\n"
return buffer
}
func highlightsAsMarkdown() -> String {
highlightItems.map { highlightAsMarkdown(item: $0) }.lazy.joined(separator: "\n\n")
}
private func loadHighlights(item: LinkedItem) {
let unsortedHighlights = item.highlights.asArray(of: Highlight.self).filter { $0.type == "HIGHLIGHT" }
let highlights = unsortedHighlights.sorted { left, right in
if left.positionPercent > 0, right.positionPercent > 0 {
return left.positionPercent < right.positionPercent
}
return (left.createdAt ?? Date()) < (right.createdAt ?? Date())
}
highlightItems = highlights.map {
HighlightListItemParams(
highlightID: $0.unwrappedID,
title: LocalText.genericHighlight,
annotation: $0.annotation ?? "",
quote: $0.quote ?? "",
labels: $0.labels.asArray(of: LinkedItemLabel.self),
createdBy: $0.createdByMe ? nil : InternalUserProfile.makeSingle($0.createdBy)
)
}
}
}