From e31101f5e9bc393df73d45ddbc327b5922047dae Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 26 Dec 2023 20:58:55 +0800 Subject: [PATCH] Improve initial loading refresh --- .../Home/Components/LibraryItemFetcher.swift | 15 ++++++++---- .../Home/Components/LibrarySyncManager.swift | 5 +--- .../App/Views/Home/HomeFeedViewIOS.swift | 23 +++++++++---------- .../App/Views/Home/HomeFeedViewModel.swift | 21 +++++++++++++---- .../Sources/App/Views/LibrarySplitView.swift | 5 ++++ .../Public/LinkedItemLoading.swift | 6 +++++ .../Queries/LinkedItemNetworkQuery.swift | 5 ++++ 7 files changed, 55 insertions(+), 25 deletions(-) diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/Components/LibraryItemFetcher.swift b/apple/OmnivoreKit/Sources/App/Views/Home/Components/LibraryItemFetcher.swift index 35255fc16..446166546 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/Components/LibraryItemFetcher.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/Components/LibraryItemFetcher.swift @@ -26,7 +26,9 @@ import Views var receivedIdx = 0 func setItems(_ context: NSManagedObjectContext, _ items: [Models.LibraryItem]) { + print("setting items, old count", self.items.count, "new count", items.count) self.items = items + if let filter = FeaturedItemFilter(rawValue: featureFilter) { updateFeatureFilter(context: context, filter: filter) } @@ -77,9 +79,6 @@ import Views return itemObjects }() - print("SYNCCURSOR LOAD CURSOR: ", loadCursor, " new cursor: ", queryResult.cursor) - print("SYNCCURSOR NEW ITEMS: ", newItems.count) - if filterState.searchTerm.replacingOccurrences(of: " ", with: "").isEmpty, appliedFilter.allowLocalFetch { updateFetchController(dataService: dataService, filterState: filterState) } else { @@ -101,7 +100,7 @@ import Views } } - func loadItems(dataService: DataService, filterState: FetcherFilterState, isRefresh: Bool) async { + func loadItems(dataService: DataService, filterState: FetcherFilterState, isRefresh: Bool, forceRemote: Bool = false) async { await withTaskGroup(of: Void.self) { group in group.addTask { await self.loadCurrentViewer(dataService: dataService) } group.addTask { await self.loadLabels(dataService: dataService) } @@ -110,7 +109,7 @@ import Views } if let appliedFilter = filterState.appliedFilter { - let shouldRemoteSearch = items.count < 1 || isRefresh && appliedFilter.shouldRemoteSearch + let shouldRemoteSearch = forceRemote || items.count < 1 || isRefresh && appliedFilter.shouldRemoteSearch if shouldRemoteSearch { await loadSearchQuery(dataService: dataService, filterState: filterState, isRefresh: isRefresh) } else { @@ -123,6 +122,12 @@ import Views BadgeCountHandler.updateBadgeCount(dataService: dataService) } + func loadNewItems(dataService: DataService, filterState: FetcherFilterState) async { + let lastSyncDate = dataService.lastItemSyncTime + _ = try? await dataService.syncLinkedItems(since: lastSyncDate, cursor: nil) + updateFetchController(dataService: dataService, filterState: filterState) + } + func loadMoreItems(dataService: DataService, filterState: FetcherFilterState, loadCursor: String? = nil) async { var useCursor = loadCursor if let appliedFilter = filterState.appliedFilter, appliedFilter.shouldRemoteSearch { diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/Components/LibrarySyncManager.swift b/apple/OmnivoreKit/Sources/App/Views/Home/Components/LibrarySyncManager.swift index f14d174b0..bef76d6df 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/Components/LibrarySyncManager.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/Components/LibrarySyncManager.swift @@ -15,10 +15,7 @@ class LibrarySyncManager { try? await dataService.syncOfflineItemsWithServerIfNeeded() - let syncResult = try? await dataService.syncLinkedItems(since: lastSyncDate, - cursor: nil) - - syncCursor = syncResult?.cursor + let syncResult = try? await dataService.syncLinkedItems(since: lastSyncDate, cursor: nil) if let syncResult = syncResult, syncResult.hasMore { dataService.syncLinkedItemsInBackground(since: lastSyncDate) { // do nothing diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift index ec86a4930..7f413663d 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift @@ -228,7 +228,9 @@ struct AnimatingCellHeight: AnimatableModifier { toolbarItems } .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in - loadItems(isRefresh: false) + Task { + await viewModel.loadNewItems(dataService: dataService) + } } .onReceive(NotificationCenter.default.publisher(for: Notification.Name("PushJSONArticle"))) { notification in guard let jsonArticle = notification.userInfo?["article"] as? JSONArticle else { return } @@ -246,9 +248,6 @@ struct AnimatingCellHeight: AnimatableModifier { LibraryAddLinkView() } } - .introspectNavigationController { nav in - nav.delegate = viewModel - } .task { await viewModel.loadFilters(dataService: dataService) } @@ -656,7 +655,7 @@ struct AnimatingCellHeight: AnimatableModifier { } var listItems: some View { - ForEach(Array(viewModel.fetcher.items.enumerated()), id: \.1.unwrappedID) { idx, item in + ForEach(viewModel.fetcher.items, id: \.unwrappedID) { item in let horizontalInset = CGFloat(UIDevice.isIPad ? 20 : 10) LibraryItemListNavigationLink( @@ -689,13 +688,13 @@ struct AnimatingCellHeight: AnimatableModifier { swipeActionButton(action: action, item: item) } } - .onAppear { - if idx >= viewModel.fetcher.items.count - 5 { - Task { - await viewModel.loadMore(dataService: dataService) - } - } - } +// .onAppear { +// if idx >= viewModel.fetcher.items.count - 5 { +// Task { +// await viewModel.loadMore(dataService: dataService) +// } +// } +// } } } diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift index fdbe7e2a7..a1c21f18f 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift @@ -5,9 +5,9 @@ import SwiftUI import Utils import Views -@MainActor final class HomeFeedViewModel: NSObject, ObservableObject, UINavigationControllerDelegate { +@MainActor final class HomeFeedViewModel: NSObject, ObservableObject { let folder: String - let fetcher: LibraryItemFetcher + @ObservedObject var fetcher: LibraryItemFetcher let listConfig: LibraryListConfig private var fetchedResultsController: NSFetchedResultsController? @@ -133,11 +133,24 @@ import Views } } - func loadItems(dataService: DataService, isRefresh: Bool) async { + func loadNewItems(dataService: DataService) async { + await fetcher.loadNewItems( + dataService: dataService, + filterState: filterState + ) + objectWillChange.send() + } + + func loadItems(dataService: DataService, isRefresh: Bool, forceRemote: Bool = false) async { isLoading = true showLoadingBar = isRefresh - await fetcher.loadItems(dataService: dataService, filterState: filterState, isRefresh: isRefresh) + await fetcher.loadItems( + dataService: dataService, + filterState: filterState, + isRefresh: isRefresh, + forceRemote: forceRemote + ) isLoading = false showLoadingBar = false diff --git a/apple/OmnivoreKit/Sources/App/Views/LibrarySplitView.swift b/apple/OmnivoreKit/Sources/App/Views/LibrarySplitView.swift index a60d4274a..5d426a6bb 100644 --- a/apple/OmnivoreKit/Sources/App/Views/LibrarySplitView.swift +++ b/apple/OmnivoreKit/Sources/App/Views/LibrarySplitView.swift @@ -71,6 +71,11 @@ public struct LibrarySplitView: View { } // selectedTab = "inbox" } + .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in + Task { + await syncManager.syncUpdates(dataService: dataService) + } + } .onReceive(NSNotification.performSyncPublisher) { _ in Task { await syncManager.syncUpdates(dataService: dataService) diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Public/LinkedItemLoading.swift b/apple/OmnivoreKit/Sources/Services/DataService/Public/LinkedItemLoading.swift index a90e58cc1..2a16bbe94 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Public/LinkedItemLoading.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Public/LinkedItemLoading.swift @@ -15,6 +15,12 @@ public extension DataService { LibraryItem.deleteItems(ids: fetchResult.deletedItemIDs, context: backgroundContext) + if !fetchResult.newItems.isEmpty { + if fetchResult.newItems.persist(context: backgroundContext) == nil { + throw BasicError.message(messageText: "CoreData error") + } + } + if !fetchResult.updatedItems.isEmpty { if fetchResult.updatedItems.persist(context: backgroundContext) == nil { throw BasicError.message(messageText: "CoreData error") diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Queries/LinkedItemNetworkQuery.swift b/apple/OmnivoreKit/Sources/Services/DataService/Queries/LinkedItemNetworkQuery.swift index 5c7b38f31..103a67816 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Queries/LinkedItemNetworkQuery.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Queries/LinkedItemNetworkQuery.swift @@ -11,6 +11,7 @@ struct InternalLinkedItemQueryResult { struct InternalLinkedItemUpdatesQueryResult { let deletedItemIDs: [String] + let newItems: [InternalLibraryItem] let updatedItems: [InternalLibraryItem] let cursor: String? let hasMoreItems: Bool @@ -92,6 +93,7 @@ extension DataService { switch payload.data { case let .success(result: result): + var newItems = [InternalLibraryItem]() var updatedItems = [InternalLibraryItem]() var deletedItemIDs = [String]() @@ -100,12 +102,15 @@ extension DataService { deletedItemIDs.append(edge.itemID) } else if let item = edge.item, edge.isUpdatedItem { updatedItems.append(item) + } else if let item = edge.item { + newItems.append(item) } } continuation.resume( returning: InternalLinkedItemUpdatesQueryResult( deletedItemIDs: deletedItemIDs, + newItems: newItems, updatedItems: updatedItems, cursor: result.cursor, hasMoreItems: result.hasMoreItems,