From 50b5f237c42d47c0d5eee120f82fbcdfcbcf44de Mon Sep 17 00:00:00 2001 From: Xin Liu Date: Sat, 23 Dec 2023 00:37:18 -0800 Subject: [PATCH] Scroll position management --- Planet/Entities/DraftModel.swift | 6 ++++++ Planet/Helper/Extensions.swift | 3 +++ Planet/Search/SearchView.swift | 3 +++ Planet/Views/Articles/ArticleListView.swift | 20 ++++++++++++++++++++ Planet/Views/Articles/ArticleView.swift | 6 ++++++ 5 files changed, 38 insertions(+) diff --git a/Planet/Entities/DraftModel.swift b/Planet/Entities/DraftModel.swift index df7e800d..cf4faf32 100644 --- a/Planet/Entities/DraftModel.swift +++ b/Planet/Entities/DraftModel.swift @@ -482,6 +482,9 @@ class DraftModel: Identifiable, Equatable, Hashable, Codable, ObservableObject { else { PlanetStore.shared.selectedArticle = article } + Task(priority: .userInitiated) { + NotificationCenter.default.post(name: .scrollToArticle, object: article) + } } } } @@ -493,6 +496,9 @@ class DraftModel: Identifiable, Equatable, Hashable, Codable, ObservableObject { else { PlanetStore.shared.selectedArticle = article } + Task(priority: .userInitiated) { + NotificationCenter.default.post(name: .scrollToArticle, object: article) + } } } } diff --git a/Planet/Helper/Extensions.swift b/Planet/Helper/Extensions.swift index a92cd44a..2abc2d4f 100644 --- a/Planet/Helper/Extensions.swift +++ b/Planet/Helper/Extensions.swift @@ -169,6 +169,9 @@ extension Notification.Name { static let myArticleBuilt = Notification.Name("PlanetMyArticleBuiltNotification") static let copiedIPNS = Notification.Name("PlanetCopiedIPNSNotification") + + static let scrollToTopArticleList = Notification.Name("PlanetScrollToTopArticleListNotification") + static let scrollToArticle = Notification.Name("PlanetScrollToArticleNotification") } // Writer diff --git a/Planet/Search/SearchView.swift b/Planet/Search/SearchView.swift index 8b5cce24..3648046f 100644 --- a/Planet/Search/SearchView.swift +++ b/Planet/Search/SearchView.swift @@ -112,6 +112,9 @@ struct SearchView: View { planetStore.selectedView = .myPlanet(article.planet) Task(priority: .userInitiated) { @MainActor in planetStore.selectedArticle = article + Task(priority: .userInitiated) { @MainActor in + NotificationCenter.default.post(name: .scrollToArticle, object: article) + } } } dismiss() diff --git a/Planet/Views/Articles/ArticleListView.swift b/Planet/Views/Articles/ArticleListView.swift index 01205487..22f57583 100644 --- a/Planet/Views/Articles/ArticleListView.swift +++ b/Planet/Views/Articles/ArticleListView.swift @@ -141,19 +141,39 @@ struct ArticleListView: View { if let myArticle = article as? MyArticleModel { if #available(macOS 13.0, *) { MyArticleItemView(article: myArticle) + .id(myArticle.id.uuidString) .listRowSeparator(.visible) } else { MyArticleItemView(article: myArticle) + .id(myArticle.id.uuidString) } } else if let followingArticle = article as? FollowingArticleModel { if #available(macOS 13.0, *) { FollowingArticleItemView(article: followingArticle) + .id(followingArticle.id.uuidString) .listRowSeparator(.visible) } else { FollowingArticleItemView(article: followingArticle) + .id(followingArticle.id.uuidString) + } + } + } + .onReceive(NotificationCenter.default.publisher(for: .scrollToTopArticleList)) { n in + if let article = articles.first { + debugPrint("Scrolling to top of Article List: \(article)") + withAnimation { + proxy.scrollTo(article.id.uuidString, anchor: .top) + } + } + } + .onReceive(NotificationCenter.default.publisher(for: .scrollToArticle)) { n in + if let article = n.object as? ArticleModel { + debugPrint("Scrolling to Article: \(article)") + withAnimation { + proxy.scrollTo(article.id.uuidString, anchor: .center) } } } diff --git a/Planet/Views/Articles/ArticleView.swift b/Planet/Views/Articles/ArticleView.swift index 3f6e9bf0..3a898b21 100644 --- a/Planet/Views/Articles/ArticleView.swift +++ b/Planet/Views/Articles/ArticleView.swift @@ -482,6 +482,7 @@ struct ArticleView: View { } label: { Image(systemName: "square.and.pencil") } + if let plausibleEnabled = planet.plausibleEnabled, plausibleEnabled { Button { isShowingAnalyticsPopover = true @@ -562,6 +563,11 @@ struct ArticleView: View { Image("custom.juicebox") }.help("Visit Juicebox Project") } + Button { + NotificationCenter.default.post(name: .scrollToTopArticleList, object: nil) + } label: { + Image(systemName: "arrow.up") + } default: Text("") }