From b79c71ff6541882ff9badde781003c994d6209e4 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Mon, 4 Apr 2022 12:05:06 -0700 Subject: [PATCH] update reading progress only when user has navigated back to the grid view --- .../Sources/App/Views/Home/HomeFeedViewIOS.swift | 5 ++++- .../App/Views/Home/HomeFeedViewModel.swift | 15 ++++++++++++++- .../Sources/App/Views/LinkItemDetailView.swift | 2 +- .../App/Views/WebReader/WebReaderContainer.swift | 4 ++-- apple/OmnivoreKit/Sources/Models/FeedItem.swift | 1 - 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift index 4c29dd93b..a6c17d60f 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift @@ -100,6 +100,9 @@ import Views viewModel.loadItems(dataService: dataService, searchQuery: searchQuery, isRefresh: true) } } + .onChange(of: selectedLinkItem) { _ in + viewModel.commitProgressUpdates() + } } } @@ -326,7 +329,7 @@ import Views var body: some View { ScrollView { LazyVGrid(columns: [GridItem(.adaptive(minimum: 325), spacing: 24)], spacing: 24) { - ForEach(viewModel.items, id: \.renderID) { item in + ForEach(viewModel.items) { item in let link = GridCardNavigationLink( item: item, searchQuery: searchQuery, diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift index 6a917f435..84408f83e 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift @@ -8,6 +8,9 @@ import Views final class HomeFeedViewModel: ObservableObject { var currentDetailViewModel: LinkItemDetailViewModel? + /// Track progress updates to be committed when user navigates back to grid view + var uncommittedReadingProgressUpdates = [String: Double]() + @Published var items = [FeedItem]() @Published var isLoading = false @Published var showPushNotificationPrimer = false @@ -163,7 +166,17 @@ final class HomeFeedViewModel: ObservableObject { .store(in: &subscriptions) } - func updateProgress(itemID: String, progress: Double) { + /// Update `FeedItem`s with the cached reading progress values so it can animate when the + /// user navigates back to the grid view (and also avoid mutations of the grid items + /// that can cause the `NavigationView` to pop. + func commitProgressUpdates() { + for (key, value) in uncommittedReadingProgressUpdates { + updateProgress(itemID: key, progress: value) + } + uncommittedReadingProgressUpdates = [:] + } + + private func updateProgress(itemID: String, progress: Double) { guard sendProgressUpdates, let item = items.first(where: { $0.id == itemID }) else { return } if let index = items.firstIndex(of: item) { items[index].readingProgress = progress diff --git a/apple/OmnivoreKit/Sources/App/Views/LinkItemDetailView.swift b/apple/OmnivoreKit/Sources/App/Views/LinkItemDetailView.swift index 06f94ea3c..2d83208f3 100644 --- a/apple/OmnivoreKit/Sources/App/Views/LinkItemDetailView.swift +++ b/apple/OmnivoreKit/Sources/App/Views/LinkItemDetailView.swift @@ -92,7 +92,7 @@ final class LinkItemDetailViewModel: ObservableObject { case let .shareHighlight(highlightID): print("show share modal for highlight with id: \(highlightID)") case let .updateReadingProgess(progress: progress): - self?.homeFeedViewModel.updateProgress(itemID: self?.item.id ?? "", progress: Double(progress)) + self?.homeFeedViewModel.uncommittedReadingProgressUpdates[self?.item.id ?? ""] = Double(progress) } } .store(in: &newWebAppWrapperViewModel.subscriptions) diff --git a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift index 7cc5bf938..51bc8fca4 100644 --- a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift +++ b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift @@ -36,7 +36,7 @@ struct WebReaderContainerView: View { let messageBody = message.body as? [String: Double] if let messageBody = messageBody, let progress = messageBody["progress"] { - homeFeedViewModel.updateProgress(itemID: item.id, progress: Double(progress)) + homeFeedViewModel.uncommittedReadingProgressUpdates[item.id] = Double(progress) } } @@ -56,7 +56,7 @@ struct WebReaderContainerView: View { if message.name == WebViewAction.readingProgressUpdate.rawValue { guard let messageBody = message.body as? [String: Double] else { return } guard let progress = messageBody["progress"] else { return } - homeFeedViewModel.updateProgress(itemID: item.id, progress: Double(progress)) + homeFeedViewModel.uncommittedReadingProgressUpdates[item.id] = Double(progress) } } diff --git a/apple/OmnivoreKit/Sources/Models/FeedItem.swift b/apple/OmnivoreKit/Sources/Models/FeedItem.swift index c8f5a418e..30960fbb7 100644 --- a/apple/OmnivoreKit/Sources/Models/FeedItem.swift +++ b/apple/OmnivoreKit/Sources/Models/FeedItem.swift @@ -12,7 +12,6 @@ public struct HomeFeedData { public struct FeedItem: Identifiable, Hashable, Decodable { public let id: String - public let renderID = UUID() public let title: String public let createdAt: Date public let savedAt: Date