Improve initial loading refresh

This commit is contained in:
Jackson Harper
2023-12-26 20:58:55 +08:00
parent 470006017d
commit e31101f5e9
7 changed files with 55 additions and 25 deletions

View File

@ -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 {

View File

@ -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

View File

@ -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)
// }
// }
// }
}
}

View File

@ -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<Models.LibraryItem>?
@ -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

View File

@ -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)

View File

@ -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")

View File

@ -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,