diff --git a/apple/OmnivoreKit/Sources/App/PDFSupport/PDFViewer.swift b/apple/OmnivoreKit/Sources/App/PDFSupport/PDFViewer.swift index b7696be7f..248665c95 100644 --- a/apple/OmnivoreKit/Sources/App/PDFSupport/PDFViewer.swift +++ b/apple/OmnivoreKit/Sources/App/PDFSupport/PDFViewer.swift @@ -237,7 +237,7 @@ import Utils } .fullScreenCover(isPresented: $showNotebookView, onDismiss: onNotebookViewDismissal) { NotebookView( - itemObjectID: viewModel.pdfItem.objectID, + viewModel: NotebookViewModel(item: viewModel.pdfItem.item), hasHighlightMutations: $hasPerformedHighlightMutations, onDeleteHighlight: { highlightId in coordinator.removeHighlightFromPDF(highlightId: highlightId) diff --git a/apple/OmnivoreKit/Sources/App/Views/Highlights/NotebookView.swift b/apple/OmnivoreKit/Sources/App/Views/Highlights/NotebookView.swift index 6e8bc2b92..802e20899 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Highlights/NotebookView.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Highlights/NotebookView.swift @@ -9,16 +9,16 @@ typealias DeleteHighlightAction = (String) -> Void struct NotebookView: View { + @StateObject var viewModel: NotebookViewModel + @EnvironmentObject var dataService: DataService @Environment(\.presentationMode) private var presentationMode - @StateObject var viewModel = NotebookViewModel() @State var showAnnotationModal = false @State var errorAlertMessage: String? @State var showErrorAlertMessage = false @State var noteAnnotation = "" - let itemObjectID: NSManagedObjectID @Binding var hasHighlightMutations: Bool @State var setLabelsHighlight: Highlight? @State var showShareView: Bool = false @@ -168,7 +168,7 @@ annotation: $noteAnnotation, onSave: { viewModel.updateNoteAnnotation( - itemObjectID: itemObjectID, + itemObjectID: viewModel.item.objectID, annotation: noteAnnotation, dataService: dataService ) @@ -224,7 +224,7 @@ #endif } .task { - viewModel.load(itemObjectID: itemObjectID, dataService: dataService) + viewModel.load(itemObjectID: viewModel.item.objectID, dataService: dataService) } } } diff --git a/apple/OmnivoreKit/Sources/App/Views/Highlights/NotebookViewModel.swift b/apple/OmnivoreKit/Sources/App/Views/Highlights/NotebookViewModel.swift index 33db22c4f..cdfa59039 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Highlights/NotebookViewModel.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Highlights/NotebookViewModel.swift @@ -21,9 +21,15 @@ struct NoteItemParams: Identifiable { } @MainActor final class NotebookViewModel: ObservableObject { + let item: Models.LibraryItem + @Published var noteItem: NoteItemParams? @Published var highlightItems = [HighlightListItemParams]() + init(item: Models.LibraryItem) { + self.item = item + } + func load(itemObjectID: NSManagedObjectID, dataService: DataService) { if let linkedItem = dataService.viewContext.object(with: itemObjectID) as? Models.LibraryItem { loadHighlights(item: linkedItem) @@ -102,7 +108,14 @@ struct NoteItemParams: Identifiable { } func highlightsAsMarkdown() -> String { - highlightItems.map { highlightAsMarkdown(item: $0) }.lazy.joined(separator: "\n\n") + var buffer = "\(item.unwrappedTitle)\n" + if let author = item.author { + buffer += "by: \(author)\n" + } + if let url = item.pageURLString { + buffer += "url: \(url)\n" + } + return buffer + "\n\n" + highlightItems.map { highlightAsMarkdown(item: $0) }.lazy.joined(separator: "\n\n") } private func loadHighlights(item: Models.LibraryItem) { diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/Components/LibraryItemListNavigationLink.swift b/apple/OmnivoreKit/Sources/App/Views/Home/Components/LibraryItemListNavigationLink.swift index b36c66a46..5fb630fce 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/Components/LibraryItemListNavigationLink.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/Components/LibraryItemListNavigationLink.swift @@ -22,9 +22,6 @@ struct MacFeedCardNavigationLink: View { EmptyView() }).opacity(0) } - .onAppear { - Task { await viewModel.itemAppeared(item: item, dataService: dataService) } - } } } @@ -55,9 +52,6 @@ struct LibraryItemListNavigationLink: View { } ) } - .task { - await viewModel.itemAppeared(item: item, dataService: dataService) - } } } @@ -92,9 +86,6 @@ struct LibraryItemGridCardNavigationLink: View { GridCard(item: LibraryItemData.make(from: item), isContextMenuOpen: $isContextMenuOpen, actionHandler: actionHandler) } ) - .task { - await viewModel.itemAppeared(item: item, dataService: dataService) - } .aspectRatio(1.0, contentMode: .fill) .background( Color.secondarySystemGroupedBackground diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift index 4f4e7a230..9dc85cde3 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift @@ -126,14 +126,11 @@ struct AnimatingCellHeight: AnimatableModifier { LinkedItemMetadataEditView(item: item) } .sheet(item: $viewModel.itemForHighlightsView) { item in - NotebookView(itemObjectID: item.objectID, hasHighlightMutations: $hasHighlightMutations) + NotebookView(viewModel: NotebookViewModel(item: item), hasHighlightMutations: $hasHighlightMutations) } .fullScreenCover(isPresented: $showExpandedAudioPlayer) { ExpandedAudioPlayer() } -// .onAppear { -// viewModel.refreshFeatureItems(dataService: dataService) -// } .toolbar { toolbarItems } @@ -710,6 +707,7 @@ struct AnimatingCellHeight: AnimatableModifier { }, header: { filtersHeader }) + BottomView(viewModel: viewModel) } .padding(0) .listStyle(.plain) @@ -934,6 +932,7 @@ struct AnimatingCellHeight: AnimatableModifier { ) } } + BottomView(viewModel: viewModel) Spacer() } .frame(maxHeight: .infinity) @@ -1037,3 +1036,18 @@ func fakeLibraryItems(dataService _: DataService) -> [LibraryItemData] { ) }) } + +struct BottomView: View { + @ObservedObject var viewModel: HomeFeedViewModel + @EnvironmentObject var dataService: DataService + + var body: some View { + Color.clear + .onAppear { + Task { + await viewModel.loadMore(dataService: dataService) + } + print("BOTTOM APPEARED") + } + } +} diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift index 60236702d..c02e72978 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift @@ -35,6 +35,8 @@ import Views @Published var negatedLabels = [LinkedItemLabel]() @Published var appliedSort = LinkedItemSort.newest.rawValue + @State var lastMoreFetched: Date? + @AppStorage(UserDefaultKey.hideFeatureSection.rawValue) var hideFeatureSection = false @AppStorage("LibraryTabView::hideFollowingTab") var hideFollowingTab = false @@ -81,17 +83,17 @@ import Views } } - func itemAppeared(item: Models.LibraryItem, dataService: DataService) async { + func loadMore(dataService: DataService) async { if isLoading { return } - let itemIndex = fetcher.items.firstIndex(where: { $0.id == item.id }) - let thresholdIndex = fetcher.items.index(fetcher.items.endIndex, offsetBy: -5) - // Check if user has scrolled to the last five items in the list - // Make sure we aren't currently loading though, as this would get triggered when the first set - // of items are presented to the user. - if let itemIndex = itemIndex, itemIndex > thresholdIndex { - await loadMoreItems(dataService: dataService, filterState: filterState, isRefresh: false) + let start = Date.now + if let lastMoreFetched, lastMoreFetched.timeIntervalSinceNow > -4 { + print("skipping fetching more as last fetch was too recent: ", lastMoreFetched) + return } + + await loadMoreItems(dataService: dataService, filterState: filterState, isRefresh: false) + lastMoreFetched = start } func pushFeedItem(item _: Models.LibraryItem) { diff --git a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift index 8bbe955fa..6fa9859c4 100644 --- a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift +++ b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift @@ -347,7 +347,7 @@ struct WebReaderContainerView: View { #if os(iOS) .sheet(isPresented: $showNotebookView, onDismiss: onNotebookViewDismissal) { NotebookView( - itemObjectID: item.objectID, + viewModel: NotebookViewModel(item: item), hasHighlightMutations: $hasPerformedHighlightMutations ) } diff --git a/apple/OmnivoreKit/Sources/Models/DataModels/PDFItem.swift b/apple/OmnivoreKit/Sources/Models/DataModels/PDFItem.swift index 4b5601d9e..3b6fcb7bc 100644 --- a/apple/OmnivoreKit/Sources/Models/DataModels/PDFItem.swift +++ b/apple/OmnivoreKit/Sources/Models/DataModels/PDFItem.swift @@ -1,8 +1,10 @@ import CoreData import Foundation +import Models import Utils public struct PDFItem { + public let item: Models.LibraryItem public let objectID: NSManagedObjectID public let itemID: String public let pdfURL: URL? @@ -21,6 +23,7 @@ public struct PDFItem { guard item.isPDF else { return nil } return PDFItem( + item: item, objectID: item.objectID, itemID: item.unwrappedID, pdfURL: URL(string: item.unwrappedPageURLString),