omnivore/apple/OmnivoreKit/Sources/App/Views/LinkItemDetailView.swift
Jackson Harper e63b4f9b2c Abstract out fetching from view model so we can better handle multiple fetch folders
Rename LinkedItem to LibraryItem

More on following

Add new fetcher

Tab bar
2023-12-07 17:15:52 +08:00

117 lines
3.2 KiB
Swift

import CoreData
import Models
import Services
import SwiftUI
import Utils
import Views
@MainActor final class LinkItemDetailViewModel: ObservableObject {
@Published var pdfItem: PDFItem?
@Published var item: Models.LibraryItem?
func loadItem(linkedItemObjectID: NSManagedObjectID, dataService: DataService) async {
let item = await dataService.viewContext.perform {
dataService.viewContext.object(with: linkedItemObjectID) as? Models.LibraryItem
}
if let item = item {
pdfItem = PDFItem.make(item: item)
self.item = item
}
trackReadEvent()
}
func handleArchiveAction(dataService: DataService) {
guard let objectID = item?.objectID ?? pdfItem?.objectID else { return }
dataService.archiveLink(objectID: objectID, archived: !isItemArchived)
showInLibrarySnackbar(!isItemArchived ? "Link archived" : "Link moved to Inbox")
}
func handleDeleteAction(dataService: DataService) {
guard let objectID = item?.objectID ?? pdfItem?.objectID else { return }
removeLibraryItemAction(dataService: dataService, objectID: objectID)
}
func updateItemReadStatus(dataService: DataService) {
guard let itemID = item?.unwrappedID ?? pdfItem?.itemID else { return }
dataService.updateLinkReadingProgress(
itemID: itemID,
readingProgress: isItemRead ? 0 : 100,
anchorIndex: 0,
force: false
)
}
private func trackReadEvent() {
guard let itemID = item?.unwrappedID ?? pdfItem?.itemID else { return }
guard let slug = item?.unwrappedSlug ?? pdfItem?.slug else { return }
guard let originalArticleURL = item?.unwrappedPageURLString ?? pdfItem?.downloadURL else { return }
EventTracker.track(
.linkRead(
linkID: itemID,
slug: slug,
originalArticleURL: originalArticleURL
)
)
}
var isItemRead: Bool {
item?.isRead ?? pdfItem?.isRead ?? false
}
var isItemArchived: Bool {
item?.isArchived ?? pdfItem?.isArchived ?? false
}
}
struct LinkItemDetailView: View {
@EnvironmentObject var authenticator: Authenticator
@EnvironmentObject var dataService: DataService
let linkedItemObjectID: NSManagedObjectID
let isPDF: Bool
@StateObject private var viewModel = LinkItemDetailViewModel()
@State var isEnabled = true
@Environment(\.dismiss) var dismiss
init(linkedItemObjectID: NSManagedObjectID, isPDF: Bool) {
self.linkedItemObjectID = linkedItemObjectID
self.isPDF = isPDF
}
var body: some View {
Group {
if isPDF {
pdfContainerView
} else if let item = viewModel.item {
WebReaderContainerView(item: item, pop: { dismiss() })
}
}
.ignoresSafeArea(.all, edges: .bottom)
.task {
await viewModel.loadItem(linkedItemObjectID: linkedItemObjectID, dataService: dataService)
}
}
@ViewBuilder private var pdfContainerView: some View {
if let pdfItem = viewModel.pdfItem, let pdfURL = pdfItem.pdfURL {
#if os(iOS)
PDFViewer(viewModel: PDFViewerViewModel(pdfItem: pdfItem))
.navigationBarTitleDisplayMode(.inline)
#elseif os(macOS)
PDFWrapperView(pdfURL: pdfURL)
#endif
} else {
HStack(alignment: .center) {
Spacer()
Text(LocalText.genericLoading)
Spacer()
}
}
}
}