Files
omnivore/apple/OmnivoreKit/Sources/Services/InternalModels/InternalHighlight.swift
2022-12-19 17:07:27 +08:00

115 lines
3.4 KiB
Swift

import CoreData
import Foundation
import Models
struct InternalHighlight: Encodable {
let id: String
let shortId: String
let quote: String
let prefix: String?
let suffix: String?
let patch: String
let annotation: String?
let createdAt: Date?
let updatedAt: Date?
let createdByMe: Bool
let createdBy: InternalUserProfile?
var labels: [InternalLinkedItemLabel]
func asManagedObject(context: NSManagedObjectContext) -> Highlight {
let fetchRequest: NSFetchRequest<Models.Highlight> = Highlight.fetchRequest()
fetchRequest.predicate = NSPredicate(
format: "id == %@", id
)
let existingHighlight = (try? context.fetch(fetchRequest))?.first
let highlight = existingHighlight ?? Highlight(entity: Highlight.entity(), insertInto: context)
highlight.markedForDeletion = false
highlight.id = id
highlight.shortId = shortId
highlight.quote = quote
highlight.prefix = prefix
highlight.suffix = suffix
highlight.patch = patch
highlight.annotation = annotation
highlight.createdAt = createdAt
highlight.updatedAt = updatedAt
highlight.createdByMe = createdByMe
if let createdBy = createdBy {
highlight.createdBy = createdBy.asManagedObject(inContext: context)
}
if let existingLabels = highlight.labels {
highlight.removeFromLabels(existingLabels)
}
for label in labels {
highlight.addToLabels(label.asManagedObject(inContext: context))
}
return highlight
}
static func make(from highlight: Highlight) -> InternalHighlight {
InternalHighlight(
id: highlight.id ?? "",
shortId: highlight.shortId ?? "",
quote: highlight.quote ?? "",
prefix: highlight.prefix,
suffix: highlight.suffix,
patch: highlight.patch ?? "",
annotation: highlight.annotation,
createdAt: highlight.createdAt,
updatedAt: highlight.updatedAt,
createdByMe: highlight.createdByMe,
createdBy: InternalUserProfile.makeSingle(highlight.createdBy),
labels: InternalLinkedItemLabel.make(highlight.labels)
)
}
func persist(
context: NSManagedObjectContext,
associatedItemID: String?,
oldHighlightsIds: [String] = []
) {
context.perform {
let highlight = asManagedObject(context: context)
if let associatedItemID = associatedItemID {
let linkedItem = LinkedItem.lookup(byID: associatedItemID, inContext: context)
linkedItem?.addToHighlights(highlight)
}
if !oldHighlightsIds.isEmpty {
let fetchRequest: NSFetchRequest<Models.Highlight> = Highlight.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "id IN %@", oldHighlightsIds)
for highlight in (try? context.fetch(fetchRequest)) ?? [] {
context.delete(highlight)
}
}
do {
try context.save()
print("Highlight saved succesfully")
} catch {
context.rollback()
print("Failed to save Highlight: \(error.localizedDescription)")
}
}
}
func encoded() -> [String: Any]? {
guard let data = try? JSONEncoder().encode(self) else { return nil }
return try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any]
}
}
extension Array where Element == InternalHighlight {
var asJSONString: String {
let jsonData = try? JSONEncoder().encode(self)
guard let jsonData = jsonData else { return "[]" }
return String(data: jsonData, encoding: .utf8) ?? "[]"
}
}