PopupView and Transimission can interfere with each other and cause an issue with the root screen becoming black and the app getting stuck.
125 lines
3.7 KiB
Swift
125 lines
3.7 KiB
Swift
import Foundation
|
|
import Models
|
|
import Services
|
|
import Utils
|
|
// import Views
|
|
|
|
final class PDFViewerViewModel: ObservableObject {
|
|
@Published var errorMessage: String?
|
|
@Published var readerView: Bool = false
|
|
|
|
let pdfItem: PDFItem
|
|
var highlights: [Highlight]
|
|
|
|
init(pdfItem: PDFItem) {
|
|
self.pdfItem = pdfItem
|
|
self.highlights = pdfItem.highlights
|
|
}
|
|
|
|
func findHighlight(dataService: DataService, highlightID: String) -> Highlight? {
|
|
let libraryItem = LibraryItem.lookup(byID: pdfItem.itemID, inContext: dataService.viewContext)
|
|
return libraryItem?.highlights.asArray(of: Highlight.self).first { $0.id == highlightID }
|
|
}
|
|
|
|
func loadHighlightPatches(completion onComplete: @escaping ([String]) -> Void) {
|
|
onComplete(pdfItem.highlights.map { $0.patch ?? "" })
|
|
}
|
|
|
|
// swiftlint:disable:next function_parameter_count
|
|
func createHighlight(
|
|
dataService: DataService,
|
|
shortId: String,
|
|
highlightID: String,
|
|
quote: String,
|
|
patch: String,
|
|
positionPercent: Double?,
|
|
positionAnchorIndex: Int?
|
|
) {
|
|
_ = dataService.createHighlight(
|
|
shortId: shortId,
|
|
highlightID: highlightID,
|
|
quote: quote,
|
|
patch: patch,
|
|
articleId: pdfItem.itemID,
|
|
positionPercent: positionPercent,
|
|
positionAnchorIndex: positionAnchorIndex
|
|
)
|
|
}
|
|
|
|
// swiftlint:disable:next function_parameter_count
|
|
func mergeHighlight(
|
|
dataService: DataService,
|
|
shortId: String,
|
|
highlightID: String,
|
|
quote: String,
|
|
patch: String,
|
|
positionPercent: Double?,
|
|
positionAnchorIndex: Int?,
|
|
overlapHighlightIdList: [String]
|
|
) {
|
|
_ = dataService.mergeHighlights(
|
|
shortId: shortId,
|
|
highlightID: highlightID,
|
|
quote: quote,
|
|
patch: patch,
|
|
articleId: pdfItem.itemID,
|
|
positionPercent: positionPercent,
|
|
positionAnchorIndex: positionAnchorIndex,
|
|
overlapHighlightIdList: overlapHighlightIdList
|
|
)
|
|
}
|
|
|
|
func removeHighlights(dataService: DataService, highlightIds: [String]) {
|
|
highlightIds.forEach { highlightID in
|
|
dataService.deleteHighlight(highlightID: highlightID)
|
|
}
|
|
}
|
|
|
|
func updateAnnotation(highlightID: String, annotation: String, dataService: DataService) {
|
|
dataService.updateHighlightAttributes(highlightID: highlightID, annotation: annotation)
|
|
|
|
if let highlight = pdfItem.highlights.first(where: { $0.id == highlightID }) {
|
|
highlight.annotation = annotation
|
|
}
|
|
}
|
|
|
|
func updateItemReadProgress(dataService: DataService, percent: Double, anchorIndex: Int, force: Bool = false) {
|
|
dataService.updateLinkReadingProgress(
|
|
itemID: pdfItem.itemID,
|
|
readingProgress: percent,
|
|
anchorIndex: anchorIndex,
|
|
force: force
|
|
)
|
|
}
|
|
|
|
func downloadPDF(dataService: DataService) async -> URL? {
|
|
do {
|
|
if let localPdfURL = pdfItem.localPdfURL, FileManager.default.fileExists(atPath: localPdfURL.path) {
|
|
return localPdfURL
|
|
}
|
|
|
|
if let tempURL = pdfItem.tempPDFURL {
|
|
if (try? PDFUtils.copyToLocal(url: tempURL)) != nil {
|
|
return tempURL
|
|
}
|
|
}
|
|
|
|
if let result = try? await dataService.loadPDFData(slug: pdfItem.slug, downloadURL: pdfItem.downloadURL) {
|
|
return result
|
|
}
|
|
|
|
// Downloading failed, try to get the article again, and then download
|
|
if let content = try? await dataService.loadArticleContentWithRetries(itemID: pdfItem.itemID, username: "me") {
|
|
// refetched the content, now try one more time then throw
|
|
if let result = try await dataService.loadPDFData(slug: pdfItem.slug, downloadURL: content.downloadURL) {
|
|
return result
|
|
}
|
|
}
|
|
return nil
|
|
} catch {
|
|
print("error downloading PDF", error)
|
|
return nil
|
|
}
|
|
}
|
|
}
|