diff --git a/apple/OmnivoreKit/Sources/App/PDFSupport/PDFViewerViewModel.swift b/apple/OmnivoreKit/Sources/App/PDFSupport/PDFViewerViewModel.swift index feead5189..550bc550e 100644 --- a/apple/OmnivoreKit/Sources/App/PDFSupport/PDFViewerViewModel.swift +++ b/apple/OmnivoreKit/Sources/App/PDFSupport/PDFViewerViewModel.swift @@ -8,20 +8,20 @@ public final class PDFViewerViewModel: ObservableObject { @Published public var errorMessage: String? @Published public var readerView: Bool = false - public var feedItem: FeedItemDep + public var linkedItem: LinkedItem var subscriptions = Set() let services: Services - public init(services: Services, feedItem: FeedItemDep) { + public init(services: Services, linkedItem: LinkedItem) { self.services = services - self.feedItem = feedItem + self.linkedItem = linkedItem } public func loadHighlights(completion onComplete: @escaping ([String]) -> Void) { let fetchRequest: NSFetchRequest = Highlight.fetchRequest() fetchRequest.predicate = NSPredicate( - format: "linkedItemId == %@", feedItem.id + format: "linkedItemId == %@", linkedItem.unwrappedID ) let highlights = (try? services.dataService.viewContext.fetch(fetchRequest)) ?? [] @@ -35,7 +35,7 @@ public final class PDFViewerViewModel: ObservableObject { highlightID: highlightID, quote: quote, patch: patch, - articleId: feedItem.id + articleId: linkedItem.unwrappedID ) .sink { [weak self] completion in guard case let .failure(error) = completion else { return } @@ -57,7 +57,7 @@ public final class PDFViewerViewModel: ObservableObject { highlightID: highlightID, quote: quote, patch: patch, - articleId: feedItem.id, + articleId: linkedItem.unwrappedID, overlapHighlightIdList: overlapHighlightIdList ) .sink { [weak self] completion in @@ -83,7 +83,7 @@ public final class PDFViewerViewModel: ObservableObject { public func updateItemReadProgress(percent: Double, anchorIndex: Int) { services.dataService .updateArticleReadingProgressPublisher( - itemID: feedItem.id, + itemID: linkedItem.unwrappedID, readingProgress: percent, anchorIndex: anchorIndex ) @@ -100,7 +100,7 @@ public final class PDFViewerViewModel: ObservableObject { var components = URLComponents(url: baseURL, resolvingAgainstBaseURL: false) if let username = services.dataService.currentViewer?.username { - components?.path = "/\(username)/\(feedItem.slug)/highlights/\(shortId)" + components?.path = "/\(username)/\(linkedItem.unwrappedSlug)/highlights/\(shortId)" } else { return nil } diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/Components/FeedCardNavigationLink.swift b/apple/OmnivoreKit/Sources/App/Views/Home/Components/FeedCardNavigationLink.swift index 14e3ccca8..006773aeb 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/Components/FeedCardNavigationLink.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/Components/FeedCardNavigationLink.swift @@ -6,7 +6,7 @@ import Views struct FeedCardNavigationLink: View { @EnvironmentObject var dataService: DataService - let item: FeedItemDep + let item: LinkedItem @ObservedObject var viewModel: HomeFeedViewModel @@ -34,7 +34,7 @@ struct GridCardNavigationLink: View { @State private var scale = 1.0 - let item: FeedItemDep + let item: LinkedItem let actionHandler: (GridCardAction) -> Void @Binding var isContextMenuOpen: Bool diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift index e53c6ba54..faa5589a6 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift @@ -45,7 +45,7 @@ import Views } .sheet(item: $viewModel.itemUnderLabelEdit) { item in ApplyLabelsView(mode: .item(item)) { labels in - viewModel.updateLabels(itemID: item.id, labels: labels) + viewModel.updateLabels(itemID: item.unwrappedID, labels: labels) } } } @@ -57,12 +57,13 @@ import Views viewModel.loadItems(dataService: dataService, isRefresh: true) } } - .onReceive(NotificationCenter.default.publisher(for: Notification.Name("PushFeedItem"))) { notification in - if let feedItem = notification.userInfo?["feedItem"] as? FeedItemDep { - viewModel.pushFeedItem(item: feedItem) - viewModel.selectedLinkItem = feedItem - } - } + // TODO: fix this +// .onReceive(NotificationCenter.default.publisher(for: Notification.Name("PushFeedItem"))) { notification in +// if let feedItem = notification.userInfo?["feedItem"] as? FeedItemD---ep { +// viewModel.pushFeedItem(item: feedItem) +// viewModel.selectedLinkItem = feedItem +// } +// } .formSheet(isPresented: $viewModel.snoozePresented) { SnoozeView(snoozePresented: $viewModel.snoozePresented, itemToSnoozeID: $viewModel.itemToSnoozeID) { viewModel.snoozeUntil( @@ -145,7 +146,7 @@ import Views @EnvironmentObject var dataService: DataService @Binding var prefersListLayout: Bool - @State private var itemToRemove: FeedItemDep? + @State private var itemToRemove: LinkedItem? @State private var confirmationShown = false @ObservedObject var viewModel: HomeFeedViewModel @@ -165,7 +166,7 @@ import Views ) Button(action: { withAnimation(.linear(duration: 0.4)) { - viewModel.setLinkArchived(dataService: dataService, linkId: item.id, archived: !item.isArchived) + viewModel.setLinkArchived(dataService: dataService, linkId: item.unwrappedID, archived: !item.isArchived) } }, label: { Label( @@ -193,7 +194,7 @@ import Views if !item.isArchived { Button { withAnimation(.linear(duration: 0.4)) { - viewModel.setLinkArchived(dataService: dataService, linkId: item.id, archived: true) + viewModel.setLinkArchived(dataService: dataService, linkId: item.unwrappedID, archived: true) } } label: { Label("Archive", systemImage: "archivebox") @@ -201,7 +202,7 @@ import Views } else { Button { withAnimation(.linear(duration: 0.4)) { - viewModel.setLinkArchived(dataService: dataService, linkId: item.id, archived: false) + viewModel.setLinkArchived(dataService: dataService, linkId: item.unwrappedID, archived: false) } } label: { Label("Unarchive", systemImage: "tray.and.arrow.down.fill") @@ -223,7 +224,7 @@ import Views Button("Remove Link", role: .destructive) { if let itemToRemove = itemToRemove { withAnimation { - viewModel.removeLink(dataService: dataService, linkId: itemToRemove.id) + viewModel.removeLink(dataService: dataService, linkId: itemToRemove.unwrappedID) } } self.itemToRemove = nil @@ -266,16 +267,16 @@ import Views struct HomeFeedGridView: View { @EnvironmentObject var dataService: DataService - @State private var itemToRemove: FeedItemDep? + @State private var itemToRemove: LinkedItem? @State private var confirmationShown = false @State var isContextMenuOpen = false @ObservedObject var viewModel: HomeFeedViewModel - func contextMenuActionHandler(item: FeedItemDep, action: GridCardAction) { + func contextMenuActionHandler(item: LinkedItem, action: GridCardAction) { switch action { case .toggleArchiveStatus: - viewModel.setLinkArchived(dataService: dataService, linkId: item.id, archived: !item.isArchived) + viewModel.setLinkArchived(dataService: dataService, linkId: item.unwrappedID, archived: !item.isArchived) case .delete: itemToRemove = item confirmationShown = true @@ -298,7 +299,7 @@ import Views Button("Remove Link", role: .destructive) { if let itemToRemove = itemToRemove { withAnimation { - viewModel.removeLink(dataService: dataService, linkId: itemToRemove.id) + viewModel.removeLink(dataService: dataService, linkId: itemToRemove.unwrappedID) } } self.itemToRemove = nil diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewMac.swift b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewMac.swift index 942c56ec3..f185006e8 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewMac.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewMac.swift @@ -9,7 +9,7 @@ import Views #if os(macOS) struct HomeFeedView: View { @EnvironmentObject var dataService: DataService - @State private var itemToRemove: FeedItemDep? + @State private var itemToRemove: LinkedItem? @State private var confirmationShown = false @ObservedObject var viewModel: HomeFeedViewModel diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift index d0a26c9e4..b678eb892 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift @@ -12,17 +12,17 @@ import Views var uncommittedReadingProgressUpdates = [String: Double]() /// Track label updates to be committed when user navigates back to grid view - var uncommittedLabelUpdates = [String: [FeedItemLabelDep]]() + var uncommittedLabelUpdates = [String: [LinkedItemLabel]]() - @Published var items = [FeedItemDep]() + @Published var items = [LinkedItem]() @Published var isLoading = false @Published var showPushNotificationPrimer = false - @Published var itemUnderLabelEdit: FeedItemDep? + @Published var itemUnderLabelEdit: LinkedItem? @Published var searchTerm = "" - @Published var selectedLabels = [FeedItemLabelDep]() + @Published var selectedLabels = [LinkedItemLabel]() @Published var snoozePresented = false @Published var itemToSnoozeID: String? - @Published var selectedLinkItem: FeedItemDep? + @Published var selectedLinkItem: LinkedItem? var cursor: String? @@ -35,7 +35,7 @@ import Views init() {} - func itemAppeared(item: FeedItemDep, dataService: DataService) { + func itemAppeared(item: LinkedItem, dataService: DataService) { if isLoading { return } let itemIndex = items.firstIndex(where: { $0.id == item.id }) let thresholdIndex = items.index(items.endIndex, offsetBy: -5) @@ -46,7 +46,7 @@ import Views } } - func pushFeedItem(item: FeedItemDep) { + func pushFeedItem(item: LinkedItem) { items.insert(item, at: 0) } @@ -73,7 +73,7 @@ import Views guard case .failure = completion else { return } self?.isLoading = false // return cachedItems found in CoreData when request fails - self?.items = dataService.cachedFeedItems() +// self?.items = dataService.cachedFeedItems() // TODO: fetch items from core data self?.cursor = nil }, receiveValue: { [weak self] result in @@ -86,9 +86,15 @@ import Views return } - dataService.prefetchPages(items: result.items) - - self?.items = isRefresh ? result.items : (self?.items ?? []) + result.items + self?.items = { + let itemIDs = isRefresh ? result.items : (self?.items ?? []).map(\.objectID) + result.items + var itemObjects = [LinkedItem]() + dataService.viewContext.performAndWait { + itemObjects = itemIDs.compactMap { dataService.viewContext.object(with: $0) as? LinkedItem } + } + return itemObjects + }() + dataService.prefetchPages(itemSlugs: (self?.items ?? []).map(\.unwrappedSlug)) self?.isLoading = false self?.receivedIdx = thisSearchIdx self?.cursor = result.cursor @@ -193,18 +199,19 @@ import Views } } - func updateLabels(itemID: String, labels: [FeedItemLabelDep]) { - // If item is being being displayed then delay the state update of labels until - // user is no longer reading the item. - if selectedLinkItem != nil { - uncommittedLabelUpdates[itemID] = labels - return - } - - guard let item = items.first(where: { $0.id == itemID }) else { return } - if let index = items.firstIndex(of: item) { - items[index].labels = labels - } + func updateLabels(itemID _: String, labels _: [LinkedItemLabel]) { + // TODO: fix +// // If item is being being displayed then delay the state update of labels until +// // user is no longer reading the item. +// if selectedLinkItem != nil { +// uncommittedLabelUpdates[itemID] = labels +// return +// } +// +// guard let item = items.first(where: { $0.id == itemID }) else { return } +// if let index = items.firstIndex(of: item) { +// items[index].labels = labels +// } } private var searchQuery: String? { @@ -216,7 +223,7 @@ import Views if !selectedLabels.isEmpty { query.append(" label:") - query.append(selectedLabels.map(\.name).joined(separator: ",")) + query.append(selectedLabels.map { $0.name ?? "" }.joined(separator: ",")) } return query diff --git a/apple/OmnivoreKit/Sources/App/Views/Labels/ApplyLabelsView.swift b/apple/OmnivoreKit/Sources/App/Views/Labels/ApplyLabelsView.swift index 99ffb4446..2df3a9872 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Labels/ApplyLabelsView.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Labels/ApplyLabelsView.swift @@ -5,8 +5,8 @@ import Views struct ApplyLabelsView: View { enum Mode { - case item(FeedItemDep) - case list([FeedItemLabelDep]) + case item(LinkedItem) + case list([LinkedItemLabel]) var navTitle: String { switch self { @@ -28,7 +28,7 @@ struct ApplyLabelsView: View { } let mode: Mode - let commitLabelChanges: ([FeedItemLabelDep]) -> Void + let commitLabelChanges: ([LinkedItemLabel]) -> Void @EnvironmentObject var dataService: DataService @Environment(\.presentationMode) private var presentationMode @@ -101,7 +101,7 @@ struct ApplyLabelsView: View { action: { switch mode { case let .item(feedItem): - viewModel.saveItemLabelChanges(itemID: feedItem.id, dataService: dataService) { labels in + viewModel.saveItemLabelChanges(itemID: feedItem.unwrappedID, dataService: dataService) { labels in commitLabelChanges(labels) presentationMode.wrappedValue.dismiss() } @@ -147,11 +147,11 @@ struct ApplyLabelsView: View { } } -private extension Sequence where Element == FeedItemLabelDep { - func applySearchFilter(_ searchFilter: String) -> [FeedItemLabelDep] { +private extension Sequence where Element == LinkedItemLabel { + func applySearchFilter(_ searchFilter: String) -> [LinkedItemLabel] { if searchFilter.isEmpty { return map { $0 } // return the identity of the sequence } - return filter { $0.name.lowercased().contains(searchFilter.lowercased()) } + return filter { ($0.name ?? "").lowercased().contains(searchFilter.lowercased()) } } } diff --git a/apple/OmnivoreKit/Sources/App/Views/Labels/LabelsViewModel.swift b/apple/OmnivoreKit/Sources/App/Views/Labels/LabelsViewModel.swift index fbdf01fdf..e40d8741a 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Labels/LabelsViewModel.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Labels/LabelsViewModel.swift @@ -4,12 +4,13 @@ import Services import SwiftUI import Views +// TODO: fix file final class LabelsViewModel: ObservableObject { private var hasLoadedInitialLabels = false @Published var isLoading = false - @Published var selectedLabels = [FeedItemLabelDep]() - @Published var unselectedLabels = [FeedItemLabelDep]() - @Published var labels = [FeedItemLabelDep]() + @Published var selectedLabels = [LinkedItemLabel]() + @Published var unselectedLabels = [LinkedItemLabel]() + @Published var labels = [LinkedItemLabel]() @Published var showCreateEmailModal = false var subscriptions = Set() @@ -20,55 +21,55 @@ final class LabelsViewModel: ObservableObject { /// - item: Optional `FeedItem` for applying labels to a single item /// - initiallySelectedLabels: Optional `[FeedItemLabel]` for filtering a list of items func loadLabels( - dataService: DataService, - item: FeedItemDep? = nil, - initiallySelectedLabels: [FeedItemLabelDep]? = nil + dataService _: DataService, + item _: LinkedItem? = nil, + initiallySelectedLabels _: [LinkedItemLabel]? = nil ) { guard !hasLoadedInitialLabels else { return } isLoading = true - dataService.labelsPublisher().sink( - receiveCompletion: { _ in }, - receiveValue: { [weak self] allLabels in - self?.isLoading = false - self?.labels = allLabels - self?.hasLoadedInitialLabels = true - if let item = item { - self?.selectedLabels = item.labels - self?.unselectedLabels = allLabels.filter { label in - !item.labels.contains(where: { $0.id == label.id }) - } - } - if let initiallySelectedLabels = initiallySelectedLabels { - self?.selectedLabels = initiallySelectedLabels - self?.unselectedLabels = allLabels.filter { label in - !initiallySelectedLabels.contains(where: { $0.id == label.id }) - } - } - } - ) - .store(in: &subscriptions) +// dataService.labelsPublisher().sink( +// receiveCompletion: { _ in }, +// receiveValue: { [weak self] allLabels in +// self?.isLoading = false +// self?.labels = allLabels +// self?.hasLoadedInitialLabels = true +// if let item = item { +// self?.selectedLabels = item.labels.asArray(of: LinkedItemLabel.self) +// self?.unselectedLabels = allLabels.filter { label in +// !item.labels.contains(where: { $0.id == label.id }) +// } +// } +// if let initiallySelectedLabels = initiallySelectedLabels { +// self?.selectedLabels = initiallySelectedLabels +// self?.unselectedLabels = allLabels.filter { label in +// !initiallySelectedLabels.contains(where: { $0.id == label.id }) +// } +// } +// } +// ) +// .store(in: &subscriptions) } - func createLabel(dataService: DataService, name: String, color: Color, description: String?) { - isLoading = true - - dataService.createLabelPublisher( - name: name, - color: color.hex ?? "", - description: description - ).sink( - receiveCompletion: { [weak self] _ in - self?.isLoading = false - }, - receiveValue: { [weak self] result in - self?.isLoading = false - self?.labels.insert(result, at: 0) - self?.unselectedLabels.insert(result, at: 0) - self?.showCreateEmailModal = false - } - ) - .store(in: &subscriptions) + func createLabel(dataService _: DataService, name _: String, color _: Color, description _: String?) { +// isLoading = true +// +// dataService.createLabelPublisher( +// name: name, +// color: color.hex ?? "", +// description: description +// ).sink( +// receiveCompletion: { [weak self] _ in +// self?.isLoading = false +// }, +// receiveValue: { [weak self] result in +// self?.isLoading = false +// self?.labels.insert(result, at: 0) +// self?.unselectedLabels.insert(result, at: 0) +// self?.showCreateEmailModal = false +// } +// ) +// .store(in: &subscriptions) } func deleteLabel(dataService: DataService, labelID: String) { @@ -87,27 +88,27 @@ final class LabelsViewModel: ObservableObject { } func saveItemLabelChanges( - itemID: String, - dataService: DataService, - onComplete: @escaping ([FeedItemLabelDep]) -> Void + itemID _: String, + dataService _: DataService, + onComplete _: @escaping ([LinkedItemLabel]) -> Void ) { - isLoading = true - dataService.updateArticleLabelsPublisher(itemID: itemID, labelIDs: selectedLabels.map(\.id)).sink( - receiveCompletion: { [weak self] _ in - self?.isLoading = false - }, - receiveValue: { onComplete($0) } - ) - .store(in: &subscriptions) +// isLoading = true +// dataService.updateArticleLabelsPublisher(itemID: itemID, labelIDs: selectedLabels.map(\.id)).sink( +// receiveCompletion: { [weak self] _ in +// self?.isLoading = false +// }, +// receiveValue: { onComplete($0) } +// ) +// .store(in: &subscriptions) } - func addLabelToItem(_ label: FeedItemLabelDep) { - selectedLabels.insert(label, at: 0) - unselectedLabels.removeAll { $0.id == label.id } + func addLabelToItem(_: LinkedItemLabel) { +// selectedLabels.insert(label, at: 0) +// unselectedLabels.removeAll { $0.id == label.id } } - func removeLabelFromItem(_ label: FeedItemLabelDep) { - unselectedLabels.insert(label, at: 0) - selectedLabels.removeAll { $0.id == label.id } + func removeLabelFromItem(_: LinkedItemLabel) { +// unselectedLabels.insert(label, at: 0) +// selectedLabels.removeAll { $0.id == label.id } } } diff --git a/apple/OmnivoreKit/Sources/App/Views/LinkItemDetailView.swift b/apple/OmnivoreKit/Sources/App/Views/LinkItemDetailView.swift index 09603a0c8..5d6bb1e73 100644 --- a/apple/OmnivoreKit/Sources/App/Views/LinkItemDetailView.swift +++ b/apple/OmnivoreKit/Sources/App/Views/LinkItemDetailView.swift @@ -6,33 +6,33 @@ import Utils import Views enum PDFProvider { - static var pdfViewerProvider: ((URL, FeedItemDep) -> AnyView)? + static var pdfViewerProvider: ((URL, LinkedItem) -> AnyView)? } @MainActor final class LinkItemDetailViewModel: ObservableObject { let homeFeedViewModel: HomeFeedViewModel - @Published var item: FeedItemDep + @Published var item: LinkedItem @Published var webAppWrapperViewModel: WebAppWrapperViewModel? var subscriptions = Set() - init(item: FeedItemDep, homeFeedViewModel: HomeFeedViewModel) { + init(item: LinkedItem, homeFeedViewModel: HomeFeedViewModel) { self.item = item self.homeFeedViewModel = homeFeedViewModel } func handleArchiveAction(dataService: DataService) { - homeFeedViewModel.setLinkArchived(dataService: dataService, linkId: item.id, archived: !item.isArchived) + homeFeedViewModel.setLinkArchived(dataService: dataService, linkId: item.unwrappedID, archived: !item.isArchived) } func handleDeleteAction(dataService: DataService) { - homeFeedViewModel.removeLink(dataService: dataService, linkId: item.id) + homeFeedViewModel.removeLink(dataService: dataService, linkId: item.unwrappedID) } func updateItemReadStatus(dataService: DataService) { dataService .updateArticleReadingProgressPublisher( - itemID: item.id, + itemID: item.unwrappedID, readingProgress: item.isRead ? 0 : 100, anchorIndex: 0 ) diff --git a/apple/OmnivoreKit/Sources/App/Views/RootView/RootViewModel.swift b/apple/OmnivoreKit/Sources/App/Views/RootView/RootViewModel.swift index 0ad448f62..3ed6b0654 100644 --- a/apple/OmnivoreKit/Sources/App/Views/RootView/RootViewModel.swift +++ b/apple/OmnivoreKit/Sources/App/Views/RootView/RootViewModel.swift @@ -33,9 +33,9 @@ public final class RootViewModel: ObservableObject { func configurePDFProvider(pdfViewerProvider: @escaping (URL, PDFViewerViewModel) -> AnyView) { guard PDFProvider.pdfViewerProvider == nil else { return } - PDFProvider.pdfViewerProvider = { [weak self] url, feedItem in + PDFProvider.pdfViewerProvider = { [weak self] url, linkedItem in guard let self = self else { return AnyView(Text("")) } - return pdfViewerProvider(url, PDFViewerViewModel(services: self.services, feedItem: feedItem)) + return pdfViewerProvider(url, PDFViewerViewModel(services: self.services, linkedItem: linkedItem)) } } diff --git a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReader.swift b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReader.swift index 79b21e94e..7e219b424 100644 --- a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReader.swift +++ b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReader.swift @@ -8,7 +8,7 @@ import WebKit struct WebReader: UIViewRepresentable { let htmlContent: String let highlightsJSONString: String - let item: FeedItemDep + let item: LinkedItem let openLinkAction: (URL) -> Void let webViewActionHandler: (WKScriptMessage, WKScriptMessageReplyHandler?) -> Void let navBarVisibilityRatioUpdater: (Double) -> Void diff --git a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift index 11d93d20e..ad26908e5 100644 --- a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift +++ b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift @@ -7,7 +7,7 @@ import WebKit #if os(iOS) struct WebReaderContainerView: View { - let item: FeedItemDep + let item: LinkedItem let homeFeedViewModel: HomeFeedViewModel @State private var showFontSizePopover = false @@ -37,7 +37,7 @@ import WebKit let messageBody = message.body as? [String: Double] if let messageBody = messageBody, let progress = messageBody["progress"] { - homeFeedViewModel.uncommittedReadingProgressUpdates[item.id] = Double(progress) + homeFeedViewModel.uncommittedReadingProgressUpdates[item.unwrappedID] = Double(progress) } } @@ -57,7 +57,7 @@ import WebKit if message.name == WebViewAction.readingProgressUpdate.rawValue { guard let messageBody = message.body as? [String: Double] else { return } guard let progress = messageBody["progress"] else { return } - homeFeedViewModel.uncommittedReadingProgressUpdates[item.id] = Double(progress) + homeFeedViewModel.uncommittedReadingProgressUpdates[item.unwrappedID] = Double(progress) } } @@ -107,7 +107,7 @@ import WebKit action: { homeFeedViewModel.setLinkArchived( dataService: dataService, - linkId: item.id, + linkId: item.unwrappedID, archived: !item.isArchived ) }, @@ -139,7 +139,7 @@ import WebKit } .alert("Are you sure?", isPresented: $showDeleteConfirmation) { Button("Remove Link", role: .destructive) { - homeFeedViewModel.removeLink(dataService: dataService, linkId: item.id) + homeFeedViewModel.removeLink(dataService: dataService, linkId: item.unwrappedID) } Button("Cancel", role: .cancel, action: {}) } @@ -206,7 +206,7 @@ import WebKit .contentShape(Rectangle()) .onAppear { if !viewModel.isLoading { - viewModel.loadContent(dataService: dataService, slug: item.slug) + viewModel.loadContent(dataService: dataService, slug: item.unwrappedSlug) } } } diff --git a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContent.swift b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContent.swift index 1c47fe344..779079c38 100644 --- a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContent.swift +++ b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContent.swift @@ -6,13 +6,13 @@ struct WebReaderContent { let textFontSize: Int let htmlContent: String let highlightsJSONString: String - let item: FeedItemDep + let item: LinkedItem let themeKey: String init( htmlContent: String, highlightsJSONString: String, - item: FeedItemDep, + item: LinkedItem, isDark: Bool, fontSize: Int ) { @@ -25,8 +25,8 @@ struct WebReaderContent { // swiftlint:disable line_length var styledContent: String { - let savedAt = "new Date(\(item.savedAt.timeIntervalSince1970 * 1000)).toISOString()" - let createdAt = "new Date(\(item.createdAt.timeIntervalSince1970 * 1000)).toISOString()" + let savedAt = "new Date(\(item.unwrappedSavedAt.timeIntervalSince1970 * 1000)).toISOString()" + let createdAt = "new Date(\(item.unwrappedCreatedAt.timeIntervalSince1970 * 1000)).toISOString()" let publishedAt = item.publishDate != nil ? "new Date(\(item.publishDate!.timeIntervalSince1970 * 1000)).toISOString()" : "undefined" return """ @@ -53,16 +53,16 @@ struct WebReaderContent { } window.omnivoreArticle = { - id: "\(item.id)", - linkId: "\(item.id)", - slug: "\(item.slug)", + id: "\(item.unwrappedID)", + linkId: "\(item.unwrappedID)", + slug: "\(item.unwrappedSlug)", createdAt: \(createdAt), savedAt: \(savedAt), publishedAt: \(publishedAt), - url: `\(item.pageURLString)`, - title: `\(item.title.replacingOccurrences(of: "`", with: "\\`"))`, + url: `\(item.unwrappedPageURLString)`, + title: `\(item.unwrappedTitle.replacingOccurrences(of: "`", with: "\\`"))`, content: document.getElementById('_omnivore-htmlContent').innerHTML, - originalArticleUrl: "\(item.pageURLString)", + originalArticleUrl: "\(item.unwrappedPageURLString)", contentReader: "WEB", readingProgressPercent: \(item.readingProgress), readingProgressAnchorIndex: \(item.readingProgressAnchor), diff --git a/apple/OmnivoreKit/Sources/Models/DataModels/FeedItem.swift b/apple/OmnivoreKit/Sources/Models/DataModels/FeedItem.swift index e49464a82..08f42eafb 100644 --- a/apple/OmnivoreKit/Sources/Models/DataModels/FeedItem.swift +++ b/apple/OmnivoreKit/Sources/Models/DataModels/FeedItem.swift @@ -2,105 +2,15 @@ import CoreData import Foundation public struct HomeFeedData { - public let items: [FeedItemDep] + public let items: [NSManagedObjectID] public let cursor: String? - public init(items: [FeedItemDep], cursor: String?) { + public init(items: [NSManagedObjectID], cursor: String?) { self.items = items self.cursor = cursor } } -public struct FeedItemDep: Identifiable, Hashable { - public let id: String - public let title: String - public let createdAt: Date - public let savedAt: Date - public var readingProgress: Double - public var readingProgressAnchor: Int - public let imageURLString: String? - public let onDeviceImageURLString: String? - public let documentDirectoryPath: String? - public let pageURLString: String - public let descriptionText: String? - public let publisherURLString: String? - public let author: String? - public let publishDate: Date? - public let slug: String - public let isArchived: Bool - public let contentReader: String? - public var labels: [FeedItemLabelDep] - - public init( - id: String, - title: String, - createdAt: Date, - savedAt: Date, - readingProgress: Double, - readingProgressAnchor: Int, - imageURLString: String?, - onDeviceImageURLString: String?, - documentDirectoryPath: String?, - pageURLString: String, - descriptionText: String?, - publisherURLString: String?, - author: String?, - publishDate: Date?, - slug: String, - isArchived: Bool, - contentReader: String?, - labels: [FeedItemLabelDep] - ) { - self.id = id - self.title = title - self.createdAt = createdAt - self.savedAt = savedAt - self.readingProgress = readingProgress - self.readingProgressAnchor = readingProgressAnchor - self.imageURLString = imageURLString - self.onDeviceImageURLString = onDeviceImageURLString - self.documentDirectoryPath = documentDirectoryPath - self.pageURLString = pageURLString - self.descriptionText = descriptionText - self.publisherURLString = publisherURLString - self.author = author - self.publishDate = publishDate - self.slug = slug - self.isArchived = isArchived - self.contentReader = contentReader - self.labels = labels - } - -// public static func fromJsonArticle(linkData: Data) -> FeedItemDe-----p? { -// try? JSONDecoder().decode(JSONArticle.self, from: linkData).feedItem -// } - - public var isRead: Bool { - readingProgress >= 0.98 - } - - public var isPDF: Bool { - if let contentReader = contentReader { - return contentReader == "PDF" - } - return pageURLString.hasSuffix("pdf") - } - - public var publisherHostname: String? { - URL(string: publisherURLString ?? pageURLString)?.host - } - - public var imageURL: URL? { - imageURLString.flatMap { URL(string: $0) } - } - - public var pdfURL: URL? { - guard isPDF else { return nil } - let documentDirectoryURL = documentDirectoryPath.flatMap { URL(string: $0) } - return documentDirectoryURL ?? URL(string: pageURLString) - } -} - // TODO: delete this // Internal model used for parsing a push notification object only // struct JSONArticle: Decodable { @@ -116,8 +26,8 @@ public struct FeedItemDep: Identifiable, Hashable { // let url: String // let isArchived: Bool // -// var feedItem: FeedItem-----Dep { -// FeedItem--------Dep( +// var feedItem: FeedItem-----De---p { +// FeedItem--------De----p( // id: id, // title: title, // createdAt: createdAt, @@ -140,80 +50,38 @@ public struct FeedItemDep: Identifiable, Hashable { // } // } -public extension FeedItemDep { - func asManagedObject(inContext context: NSManagedObjectContext) -> LinkedItem { - let existingItem = LinkedItem.lookup(byID: id, inContext: context) - let linkedItem = existingItem ?? LinkedItem(entity: LinkedItem.entity(), insertInto: context) - - linkedItem.id = id - linkedItem.title = title - linkedItem.createdAt = createdAt - linkedItem.savedAt = savedAt - linkedItem.readingProgress = readingProgress - linkedItem.readingProgressAnchor = Int64(readingProgressAnchor) - linkedItem.imageURLString = imageURLString - linkedItem.onDeviceImageURLString = onDeviceImageURLString - linkedItem.pageURLString = pageURLString - linkedItem.descriptionText = descriptionText - linkedItem.publisherURLString = publisherURLString - linkedItem.author = author - linkedItem.publishDate = publishDate - linkedItem.slug = slug - linkedItem.isArchived = isArchived - linkedItem.contentReader = contentReader - -// for label in labels { -// // TODO: fix -// } - - return linkedItem - } - - static func make(from item: LinkedItem) -> FeedItemDep { - FeedItemDep( - id: item.id ?? "", - title: item.title ?? "", - createdAt: item.createdAt ?? Date(), - savedAt: item.savedAt ?? Date(), - readingProgress: item.readingProgress, - readingProgressAnchor: Int(item.readingProgressAnchor), - imageURLString: item.imageURLString, - onDeviceImageURLString: item.onDeviceImageURLString, - documentDirectoryPath: nil, - pageURLString: item.pageURLString ?? "", - descriptionText: item.title, - publisherURLString: item.publisherURLString, - author: item.author, - publishDate: item.publishDate, - slug: item.slug ?? "", - isArchived: item.isArchived, - contentReader: item.contentReader, - labels: [] - ) - } -} - -public extension Sequence where Element == FeedItemDep { - func persist(context: NSManagedObjectContext) -> [LinkedItem]? { - var result: [LinkedItem]? - - context.performAndWait { - let linkedItems = map { $0.asManagedObject(inContext: context) } - - do { - try context.save() - result = linkedItems - logger.debug("LinkedItems saved succesfully") - } catch { - context.rollback() - logger.debug("Failed to save LinkedItems: \(error.localizedDescription)") - } - } - return result - } -} - public extension LinkedItem { + var unwrappedID: String { id ?? "" } + var unwrappedSlug: String { slug ?? "" } + var unwrappedTitle: String { title ?? "" } + var unwrappedPageURLString: String { pageURLString ?? "" } + var unwrappedSavedAt: Date { savedAt ?? Date() } + var unwrappedCreatedAt: Date { createdAt ?? Date() } + + var isRead: Bool { + readingProgress >= 0.98 + } + + var isPDF: Bool { + if let contentReader = contentReader { + return contentReader == "PDF" + } + return (pageURLString ?? "").hasSuffix("pdf") + } + + var publisherHostname: String? { + URL(string: publisherURLString ?? pageURLString ?? "")?.host + } + + var imageURL: URL? { + imageURLString.flatMap { URL(string: $0) } + } + + var pdfURL: URL? { + guard isPDF else { return nil } + return URL(string: pageURLString ?? "") + } + static func lookup(byID itemID: String, inContext context: NSManagedObjectContext) -> LinkedItem? { let fetchRequest: NSFetchRequest = LinkedItem.fetchRequest() fetchRequest.predicate = NSPredicate( diff --git a/apple/OmnivoreKit/Sources/Models/DataModels/FeedItemLabelDep.swift b/apple/OmnivoreKit/Sources/Models/DataModels/FeedItemLabelDep.swift index ef40ae284..a6d4ff479 100644 --- a/apple/OmnivoreKit/Sources/Models/DataModels/FeedItemLabelDep.swift +++ b/apple/OmnivoreKit/Sources/Models/DataModels/FeedItemLabelDep.swift @@ -1,23 +1 @@ -import Foundation - -public struct FeedItemLabelDep: Decodable, Hashable { - public let id: String - public let name: String - public let color: String - public let createdAt: Date? - public let labelDescription: String? - - public init( - id: String, - name: String, - color: String, - createdAt: Date?, - labelDescription: String? - ) { - self.id = id - self.name = name - self.color = color - self.createdAt = createdAt - self.labelDescription = labelDescription - } -} +// TODO: delete file diff --git a/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift b/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift index 10249f3b3..24a4b700f 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift @@ -52,11 +52,10 @@ public final class DataService: ObservableObject { } public extension DataService { - func prefetchPages(items: [FeedItemDep]) { + func prefetchPages(itemSlugs: [String]) { guard let username = currentViewer?.username else { return } - for item in items { - let slug = item.slug + for slug in itemSlugs { articleContentPublisher(username: username, slug: slug).sink( receiveCompletion: { _ in }, receiveValue: { _ in } diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/CreateLabelPublisher.swift b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/CreateLabelPublisher.swift index 62596c9f9..0921c9607 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/CreateLabelPublisher.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/CreateLabelPublisher.swift @@ -1,4 +1,5 @@ import Combine +import CoreData import Foundation import Models import SwiftGraphQL @@ -8,9 +9,9 @@ public extension DataService { name: String, color: String, description: String? - ) -> AnyPublisher { + ) -> AnyPublisher { enum MutationResult { - case saved(label: FeedItemLabelDep) + case saved(label: InternalLinkedItemLabel) case error(errorCode: Enums.CreateLabelErrorCode) } @@ -46,8 +47,9 @@ public extension DataService { switch payload.data { case let .saved(label: label): - // TODO: update CoreData - promise(.success(label)) + // TODO: update CoreData and fix this label thing +// promise(.success(label)) + promise(.failure(.message(messageText: ""))) case let .error(errorCode: errorCode): promise(.failure(.message(messageText: errorCode.rawValue))) } diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/UpdateArticleLabelsPublisher.swift b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/UpdateArticleLabelsPublisher.swift index 484b11dc3..07af48129 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/UpdateArticleLabelsPublisher.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/UpdateArticleLabelsPublisher.swift @@ -1,4 +1,5 @@ import Combine +import CoreData import Foundation import Models import SwiftGraphQL @@ -7,9 +8,9 @@ public extension DataService { func updateArticleLabelsPublisher( itemID: String, labelIDs: [String] - ) -> AnyPublisher<[FeedItemLabelDep], BasicError> { + ) -> AnyPublisher<[NSManagedObjectID], BasicError> { enum MutationResult { - case saved(feedItem: [FeedItemLabelDep]) + case saved(feedItem: [InternalLinkedItemLabel]) case error(errorCode: Enums.SetLabelsErrorCode) } @@ -44,8 +45,9 @@ public extension DataService { switch payload.data { case let .saved(labels): - // TODO: update CoreData - promise(.success(labels)) + // TODO: update CoreData and fix dis + promise(.failure(.message(messageText: "failed to set labels"))) +// promise(.success(labels)) case .error: promise(.failure(.message(messageText: "failed to set labels"))) } diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Queries/LabelsPublisher.swift b/apple/OmnivoreKit/Sources/Services/DataService/Queries/LabelsPublisher.swift index c110b92ab..799c79b99 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Queries/LabelsPublisher.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Queries/LabelsPublisher.swift @@ -1,12 +1,13 @@ import Combine +import CoreData import Foundation import Models import SwiftGraphQL public extension DataService { - func labelsPublisher() -> AnyPublisher<[FeedItemLabelDep], ServerError> { + func labelsPublisher() -> AnyPublisher<[NSManagedObjectID], ServerError> { enum QueryResult { - case success(result: [FeedItemLabelDep]) + case success(result: [InternalLinkedItemLabel]) case error(error: String) } @@ -33,8 +34,9 @@ public extension DataService { case let .success(payload): switch payload.data { case let .success(result: result): - // TODO: update CoreData - promise(.success(result)) + // TODO: update CoreData and fix this +// promise(.success(result)) + promise(.failure(.unknown)) case .error: promise(.failure(.unknown)) } diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Queries/LibraryItemsQuery.swift b/apple/OmnivoreKit/Sources/Services/DataService/Queries/LibraryItemsQuery.swift index 28050516a..4b68f1743 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Queries/LibraryItemsQuery.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Queries/LibraryItemsQuery.swift @@ -12,8 +12,13 @@ public extension DataService { searchQuery: String?, cursor: String? ) -> AnyPublisher { + struct InternalHomeFeedData { + let items: [InternalLinkedItem] + let cursor: String? + } + enum QueryResult { - case success(result: HomeFeedData) + case success(result: InternalHomeFeedData) case error(error: String) } @@ -21,7 +26,7 @@ public extension DataService { try $0.on( articlesSuccess: .init { QueryResult.success( - result: HomeFeedData( + result: InternalHomeFeedData( items: try $0.edges(selection: articleEdgeSelection.list), cursor: try $0.pageInfo(selection: Selection.PageInfo { try $0.endCursor() @@ -61,9 +66,11 @@ public extension DataService { case let .success(payload): switch payload.data { case let .success(result: result): - // save items to coredata - _ = result.items.persist(context: self.backgroundContext) - promise(.success(result)) + if let items = result.items.persist(context: self.backgroundContext) { + promise(.success(HomeFeedData(items: items.map(\.objectID), cursor: result.cursor))) + } else { + promise(.failure(.unknown)) + } case .error: promise(.failure(.unknown)) } @@ -77,22 +84,23 @@ public extension DataService { .eraseToAnyPublisher() } - func cachedFeedItems() -> [FeedItemDep] { - var result = [FeedItemDep]() - - backgroundContext.performAndWait { - let fetchRequest: NSFetchRequest = LinkedItem.fetchRequest() - fetchRequest.sortDescriptors = [NSSortDescriptor(keyPath: \LinkedItem.savedAt, ascending: false)] - let items = (try? backgroundContext.fetch(fetchRequest)) ?? [] - result = items.map { FeedItemDep.make(from: $0) } - } - - return result - } + // TODO: delete +// func cachedFeedItems() -> [FeedItem---D----ep] { +// var result = [FeedItem------D---ep]() +// +// backgroundContext.performAndWait { +// let fetchRequest: NSFetchRequest = LinkedItem.fetchRequest() +// fetchRequest.sortDescriptors = [NSSortDescriptor(keyPath: \LinkedItem.savedAt, ascending: false)] +// let items = (try? backgroundContext.fetch(fetchRequest)) ?? [] +// result = items.map { FeedItem-----D----ep.make(from: $0) } +// } +// +// return result +// } } let homeFeedItemSelection = Selection.Article { - FeedItemDep( + InternalLinkedItem( id: try $0.id(), title: try $0.title(), createdAt: try $0.createdAt().value ?? Date(), diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Selections/FeedItemLabelSelection.swift b/apple/OmnivoreKit/Sources/Services/DataService/Selections/FeedItemLabelSelection.swift index 656392464..5ae6fe426 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Selections/FeedItemLabelSelection.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Selections/FeedItemLabelSelection.swift @@ -2,7 +2,7 @@ import Models import SwiftGraphQL let feedItemLabelSelection = Selection.Label { - FeedItemLabelDep( + InternalLinkedItemLabel( id: try $0.id(), name: try $0.name(), color: try $0.color(), diff --git a/apple/OmnivoreKit/Sources/Services/InternalModels/InternalLinkedItem.swift b/apple/OmnivoreKit/Sources/Services/InternalModels/InternalLinkedItem.swift index 1e1a06ce7..725e884ae 100644 --- a/apple/OmnivoreKit/Sources/Services/InternalModels/InternalLinkedItem.swift +++ b/apple/OmnivoreKit/Sources/Services/InternalModels/InternalLinkedItem.swift @@ -77,16 +77,18 @@ struct InternalLinkedItem { extension Sequence where Element == InternalLinkedItem { // TODO: use batch update? func persist(context: NSManagedObjectContext) -> [LinkedItem]? { - let linkedItems = map { $0.asManagedObject(inContext: context) } + var linkedItems: [LinkedItem]? + context.performAndWait { + linkedItems = map { $0.asManagedObject(inContext: context) } - do { - try context.save() - print("LinkedItems saved succesfully") - return linkedItems - } catch { - context.rollback() - print("Failed to save LinkedItems: \(error.localizedDescription)") - return nil + do { + try context.save() + print("LinkedItems saved succesfully") + } catch { + context.rollback() + print("Failed to save LinkedItems: \(error.localizedDescription)") + } } + return linkedItems } } diff --git a/apple/OmnivoreKit/Sources/Services/NSNotification+Operation.swift b/apple/OmnivoreKit/Sources/Services/NSNotification+Operation.swift index af6a14bbf..285322828 100644 --- a/apple/OmnivoreKit/Sources/Services/NSNotification+Operation.swift +++ b/apple/OmnivoreKit/Sources/Services/NSNotification+Operation.swift @@ -33,7 +33,7 @@ public extension NSNotification { } // TODO: re-enable later -// static func pushFeedItem(feedItem: FeedItem-----Dep) { +// static func pushFeedItem(feedItem: FeedItem-----D---ep) { // NotificationCenter.default.post(name: NSNotification.PushFeedItem, object: nil, userInfo: ["feedItem": feedItem]) // } diff --git a/apple/OmnivoreKit/Sources/Views/FeedItem/GridCard.swift b/apple/OmnivoreKit/Sources/Views/FeedItem/GridCard.swift index a10a29459..c52a5f2fb 100644 --- a/apple/OmnivoreKit/Sources/Views/FeedItem/GridCard.swift +++ b/apple/OmnivoreKit/Sources/Views/FeedItem/GridCard.swift @@ -10,12 +10,12 @@ public enum GridCardAction { public struct GridCard: View { @Binding var isContextMenuOpen: Bool - let item: FeedItemDep + let item: LinkedItem let actionHandler: (GridCardAction) -> Void let tapAction: () -> Void public init( - item: FeedItemDep, + item: LinkedItem, isContextMenuOpen: Binding, actionHandler: @escaping (GridCardAction) -> Void, tapAction: @escaping () -> Void @@ -77,7 +77,7 @@ public struct GridCard: View { // Title, Subtitle, Menu Button VStack(alignment: .leading, spacing: 4) { HStack { - Text(item.title) + Text(item.unwrappedTitle) .font(.appHeadline) .foregroundColor(.appGrayTextContrast) .lineLimit(1) @@ -117,7 +117,7 @@ public struct GridCard: View { // Link description and image HStack(alignment: .top) { - Text(item.descriptionText ?? item.title) + Text(item.descriptionText ?? item.unwrappedTitle) .font(.appSubheadline) .foregroundColor(.appGrayTextContrast) .lineLimit(nil) @@ -152,7 +152,7 @@ public struct GridCard: View { if FeatureFlag.enableLabels { ScrollView(.horizontal, showsIndicators: false) { HStack { - ForEach(item.labels, id: \.self) { + ForEach(item.labels.asArray(of: LinkedItemLabel.self), id: \.self) { TextChip(feedItemLabel: $0) } Spacer() diff --git a/apple/OmnivoreKit/Sources/Views/FeedItem/HomeFeedCardView.swift b/apple/OmnivoreKit/Sources/Views/FeedItem/HomeFeedCardView.swift index 3c437557b..217f6f140 100644 --- a/apple/OmnivoreKit/Sources/Views/FeedItem/HomeFeedCardView.swift +++ b/apple/OmnivoreKit/Sources/Views/FeedItem/HomeFeedCardView.swift @@ -3,16 +3,16 @@ import SwiftUI import Utils public struct FeedCard: View { - let item: FeedItemDep + let item: LinkedItem - public init(item: FeedItemDep) { + public init(item: LinkedItem) { self.item = item } public var body: some View { HStack(alignment: .top, spacing: 6) { VStack(alignment: .leading, spacing: 6) { - Text(item.title) + Text(item.unwrappedTitle) .font(.appSubheadline) .foregroundColor(.appGrayTextContrast) .lineLimit(2) diff --git a/apple/OmnivoreKit/Sources/Views/TextChip.swift b/apple/OmnivoreKit/Sources/Views/TextChip.swift index 198d42d94..f318d7902 100644 --- a/apple/OmnivoreKit/Sources/Views/TextChip.swift +++ b/apple/OmnivoreKit/Sources/Views/TextChip.swift @@ -8,10 +8,10 @@ public struct TextChip: View { self.color = color } - public init?(feedItemLabel: FeedItemLabelDep) { - guard let color = Color(hex: feedItemLabel.color) else { return nil } + public init?(feedItemLabel: LinkedItemLabel) { + guard let color = Color(hex: feedItemLabel.color ?? "") else { return nil } - self.text = feedItemLabel.name + self.text = feedItemLabel.name ?? "" self.color = color } @@ -41,12 +41,12 @@ public struct TextChipButton: View { } public static func makeRemovableLabelButton( - feedItemLabel: FeedItemLabelDep, + feedItemLabel: LinkedItemLabel, onTap: @escaping () -> Void ) -> TextChipButton { TextChipButton( - title: feedItemLabel.name, - color: Color(hex: feedItemLabel.color) ?? .appButtonBackground, + title: feedItemLabel.name ?? "", + color: Color(hex: feedItemLabel.color ?? "") ?? .appButtonBackground, actionType: .remove, onTap: onTap ) diff --git a/apple/Sources/PDFViewer.swift b/apple/Sources/PDFViewer.swift index 463351e79..1ed68de0d 100644 --- a/apple/Sources/PDFViewer.swift +++ b/apple/Sources/PDFViewer.swift @@ -70,8 +70,8 @@ import Utils coordinator.viewer = self - if viewModel.feedItem.readingProgressAnchor > 0 { - let pageIndex = UInt(viewModel.feedItem.readingProgressAnchor) + if viewModel.linkedItem.readingProgressAnchor > 0 { + let pageIndex = UInt(viewModel.linkedItem.readingProgressAnchor) controller.setPageIndex(pageIndex, animated: false) } @@ -145,7 +145,7 @@ import Utils let pageIndex = Int(event.pageIndex) if let totalPageCount = controller.document?.pageCount { let percent = min(100, max(0, ((Double(pageIndex) + 1.0) / Double(totalPageCount)) * 100.0)) - if percent > self.viewModel.feedItem.readingProgress { + if percent > self.viewModel.linkedItem.readingProgress { self.viewModel.updateItemReadProgress(percent: percent, anchorIndex: pageIndex) } } @@ -199,7 +199,7 @@ import Utils "id": highlightID, "shortId": shortId, "quote": quote, - "articleId": viewModel.feedItem.id + "articleId": viewModel.linkedItem.unwrappedID ] ] document.add(annotations: [highlight]) diff --git a/apple/Sources/PushNotificationConfig.swift b/apple/Sources/PushNotificationConfig.swift index 1a49bb280..ce8a7d542 100644 --- a/apple/Sources/PushNotificationConfig.swift +++ b/apple/Sources/PushNotificationConfig.swift @@ -58,7 +58,7 @@ extension AppDelegate: UNUserNotificationCenterDelegate { // TODO: fix // if let linkData = userInfo["link"] as? String { // guard let jsonData = Data(base64Encoded: linkData) else { return } -// if let item = FeedItemDep.fromJsonArticle(linkData: jsonData) { +// if let item = FeedItem---D--ep.fromJsonArticle(linkData: jsonData) { // NSNotification.pushFeedItem(feedItem: item) // } // }