remove HighlightDep and pdf specific highlight functions

This commit is contained in:
Satindar Dhillon 2022-04-21 22:03:39 -07:00
parent 23edb9b99b
commit 25e237255c
10 changed files with 12 additions and 258 deletions

View file

@ -1,4 +1,5 @@
import Combine
import CoreData
import Foundation
import Models
import Services
@ -17,52 +18,17 @@ public final class PDFViewerViewModel: ObservableObject {
self.feedItem = feedItem
}
public func loadHighlights(completion onComplete: @escaping ([HighlightDep]) -> Void) {
guard let username = services.dataService.currentViewer?.username else { return }
services.dataService.pdfHighlightsPublisher(username: username, slug: feedItem.slug).sink(
receiveCompletion: { [weak self] completion in
guard case .failure = completion else { return }
onComplete(self?.allHighlights(fetchedHighlights: []) ?? [])
},
receiveValue: { [weak self] highlights in
onComplete(self?.allHighlights(fetchedHighlights: highlights) ?? [])
}
public func loadHighlights(completion onComplete: @escaping ([String]) -> Void) {
let fetchRequest: NSFetchRequest<Models.Highlight> = Highlight.fetchRequest()
fetchRequest.predicate = NSPredicate(
format: "linkedItemId == %@", feedItem.id
)
.store(in: &subscriptions)
}
// TODO: use core data instead
private func allHighlights(fetchedHighlights: [HighlightDep]) -> [HighlightDep] {
var resultSet = [String: HighlightDep]()
for highlight in services.dataService.cachedHighlights(pdfID: feedItem.id) {
resultSet[highlight.id] = highlight
}
for highlight in fetchedHighlights {
resultSet[highlight.id] = highlight
}
for highlightId in services.dataService.deletedHighlightsIDs {
resultSet.removeValue(forKey: highlightId)
}
return Array(resultSet.values)
let highlights = (try? services.dataService.viewContext.fetch(fetchRequest)) ?? []
onComplete(highlights.map { $0.patch ?? "" })
}
public func createHighlight(shortId: String, highlightID: String, quote: String, patch: String) {
services.dataService.persistHighlight(
pdfID: feedItem.id,
highlight: HighlightDep(
id: highlightID,
shortId: shortId,
quote: quote,
prefix: nil,
suffix: nil,
patch: patch,
annotation: nil,
createdByMe: true
)
)
services.dataService
.createHighlightPublisher(
shortId: shortId,
@ -78,7 +44,6 @@ public final class PDFViewerViewModel: ObservableObject {
.store(in: &subscriptions)
}
// TODO: able to delete this now?
public func mergeHighlight(
shortId: String,
highlightID: String,
@ -103,7 +68,6 @@ public final class PDFViewerViewModel: ObservableObject {
}
public func removeHighlights(highlightIds: [String]) {
// TODO: update function to take an array?
highlightIds.forEach { highlightId in
services.dataService.deleteHighlightPublisher(highlightId: highlightId)
.sink { [weak self] completion in

View file

@ -51,9 +51,6 @@ import Views
}
func loadItems(dataService: DataService, isRefresh: Bool) {
// Clear offline highlights since we'll be populating new FeedItems with the correct highlights set
dataService.clearHighlights()
let thisSearchIdx = searchIdx
searchIdx += 1

View file

@ -162,7 +162,7 @@ public extension FeedItemDep {
linkedItem.contentReader = contentReader
// for label in item.labels {
// TODO: append labels
// TODO: append labels...and highlights?
// }
return linkedItem

View file

@ -1,85 +0,0 @@
import CoreData
import Foundation
public struct HighlightDep: Identifiable, Hashable, Codable {
public let id: String
public let shortId: String
public let quote: String
public let prefix: String?
public let suffix: String?
public let patch: String
public let annotation: String?
public let createdAt: Date?
public let updatedAt: Date?
public let createdByMe: Bool
public init(
id: String,
shortId: String,
quote: String,
prefix: String?,
suffix: String?,
patch: String,
annotation: String?,
createdByMe: Bool,
createdAt: Date? = nil,
updatedAt: Date? = nil
) {
self.id = id
self.shortId = shortId
self.quote = quote
self.prefix = prefix
self.suffix = suffix
self.patch = patch
self.annotation = annotation
self.createdAt = createdAt
self.updatedAt = updatedAt
self.createdByMe = createdByMe
}
public func toManagedObject(context: NSManagedObjectContext, associatedItemID: String) -> Highlight {
let highlight = Highlight(context: context)
highlight.linkedItemId = associatedItemID
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
return highlight
}
public func persist(context: NSManagedObjectContext, associatedItemID: String) -> Highlight? {
let highlight = toManagedObject(context: context, associatedItemID: associatedItemID)
do {
try context.save()
logger.debug("Highlight saved succesfully")
return highlight
} catch {
context.rollback()
logger.debug("Failed to save Highlight: \(error.localizedDescription)")
return nil
}
}
public static func make(from highlight: Highlight) -> HighlightDep {
HighlightDep(
id: highlight.id ?? "",
shortId: highlight.shortId ?? "",
quote: highlight.quote ?? "",
prefix: highlight.prefix,
suffix: highlight.suffix,
patch: highlight.patch ?? "",
annotation: highlight.annotation,
createdByMe: highlight.createdByMe,
createdAt: highlight.createdAt,
updatedAt: highlight.updatedAt
)
}
}

View file

@ -21,8 +21,6 @@ public final class DataService: ObservableObject {
persistentContainer.viewContext
}
public var deletedHighlightsIDs = Set<String>()
public init(appEnvironment: AppEnvironment, networker: Networker) {
self.appEnvironment = appEnvironment
self.networker = networker
@ -43,26 +41,6 @@ public final class DataService: ObservableObject {
return try? persistentContainer.viewContext.fetch(fetchRequest).first
}
public func clearHighlights() {
backgroundContext.perform {
self.deletedHighlightsIDs.removeAll()
let fetchRequest: NSFetchRequest<Models.Highlight> = Highlight.fetchRequest()
let highlights = (try? self.backgroundContext.fetch(fetchRequest)) ?? []
for highlight in highlights {
self.backgroundContext.delete(highlight)
}
do {
try self.backgroundContext.save()
} catch {
logger.debug("failed to delete objects")
}
}
}
public func switchAppEnvironment(appEnvironment: AppEnvironment) {
do {
try ValetKey.appEnvironmentString.setValue(appEnvironment.rawValue)

View file

@ -54,7 +54,7 @@ public extension DataService {
switch payload.data {
case let .saved(highlight: highlight):
_ = highlight.persist(
highlight.persist(
context: self.backgroundContext,
associatedItemID: articleId
)

View file

@ -1,55 +0,0 @@
import Combine
import Foundation
import Models
import SwiftGraphQL
public extension DataService {
func pdfHighlightsPublisher(username: String, slug: String) -> AnyPublisher<[HighlightDep], ServerError> {
enum QueryResult {
case success(result: [HighlightDep])
case error(error: String)
}
let articleSelection = Selection.Article {
try $0.highlights(selection: highlightDepSelection.list)
}
let selection = Selection<QueryResult, Unions.ArticleResult> {
try $0.on(
articleSuccess: .init {
QueryResult.success(result: try $0.article(selection: articleSelection))
},
articleError: .init {
QueryResult.error(error: try $0.errorCodes().description)
}
)
}
let query = Selection.Query {
try $0.article(username: username, slug: slug, selection: selection)
}
let path = appEnvironment.graphqlPath
let headers = networker.defaultHeaders
return Deferred {
Future { promise in
send(query, to: path, headers: headers) { result in
switch result {
case let .success(payload):
switch payload.data {
case let .success(result: result):
promise(.success(result))
case .error:
promise(.failure(.unknown))
}
case .failure:
promise(.failure(.unknown))
}
}
}
}
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
}

View file

@ -15,16 +15,3 @@ let highlightSelection = Selection.Highlight {
createdByMe: try $0.createdByMe()
)
}
let highlightDepSelection = Selection.Highlight {
HighlightDep(
id: try $0.id(),
shortId: try $0.shortId(),
quote: try $0.quote(),
prefix: try $0.prefix(),
suffix: try $0.suffix(),
patch: try $0.patch(),
annotation: try $0.annotation(),
createdByMe: try $0.createdByMe()
)
}

View file

@ -1,32 +0,0 @@
import Combine
import CoreData
import Foundation
import Models
// TODO: possibly remove this file?
public extension DataService {
func cachedHighlights(pdfID: String) -> [HighlightDep] {
let fetchRequest: NSFetchRequest<Models.Highlight> = Highlight.fetchRequest()
fetchRequest.predicate = NSPredicate(
format: "linkedItemId == %@ AND markedForDeletion == %@", pdfID, false
)
let highlights = (try? persistentContainer.viewContext.fetch(fetchRequest)) ?? []
return highlights.map { HighlightDep.make(from: $0) }
}
func persistHighlight(pdfID: String, highlight: HighlightDep) {
_ = highlight.toManagedObject(
context: persistentContainer.viewContext,
associatedItemID: pdfID
)
do {
try persistentContainer.viewContext.save()
print("Highlight saved succesfully")
} catch {
persistentContainer.viewContext.rollback()
print("Failed to save Highlight: \(error)")
}
}
}

View file

@ -301,10 +301,10 @@ import Utils
}
private func applyHighlights(documentProvider: PDFDocumentProvider) {
viewModel.loadHighlights { [weak self] highlights in
viewModel.loadHighlights { [weak self] highlightPatches in
var annnotations: [Annotation] = []
for highlight in highlights {
guard let data = highlight.patch.data(using: String.Encoding.utf8) else { continue }
for patch in highlightPatches {
guard let data = patch.data(using: String.Encoding.utf8) else { continue }
let annotation = try? Annotation(fromInstantJSON: data, documentProvider: documentProvider)
guard let annotation = annotation else { continue }
annnotations.append(annotation)