Restore ScrollToTop on timeline tab

This commit is contained in:
Thomas Ricouard 2024-09-14 08:09:51 +02:00
parent 594fb3ea07
commit 122e57d8ac
3 changed files with 48 additions and 25 deletions

View File

@ -26,6 +26,7 @@ struct AppView: View {
@State var iosTabs = iOSTabs.shared
@State var sidebarTabs = SidebarTabs.shared
@State var selectedTabScrollToTop: Int = -1
var body: some View {
#if os(visionOS)
@ -75,6 +76,7 @@ struct AppView: View {
}
.id(appAccountsManager.currentClient.id)
.withSheetDestinations(sheetDestinations: $appRouterPath.presentedSheet)
.environment(\.selectedTabScrollToTop, selectedTabScrollToTop)
}
private func updateTab(with newTab: AppTab) {
@ -90,6 +92,15 @@ struct AppView: View {
HapticManager.shared.fireHaptic(.tabSelection)
SoundEffectManager.shared.playSound(.tabSelection)
if selectedTab == newTab {
selectedTabScrollToTop = newTab.rawValue
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
selectedTabScrollToTop = -1
}
} else {
selectedTabScrollToTop = -1
}
selectedTab = newTab
}

View File

@ -12,4 +12,5 @@ extension EnvironmentValues {
@Entry public var isStatusFocused: Bool = false
@Entry public var isHomeTimeline: Bool = false
@Entry public var indentationLevel: UInt = 0
@Entry public var selectedTabScrollToTop: Int = -1
}

View File

@ -11,6 +11,8 @@ import SwiftUIIntrospect
@MainActor
public struct TimelineView: View {
@Environment(\.scenePhase) private var scenePhase
@Environment(\.selectedTabScrollToTop) private var selectedTabScrollToTop
@Environment(Theme.self) private var theme
@Environment(CurrentAccount.self) private var account
@Environment(StreamWatcher.self) private var watcher
@ -45,33 +47,42 @@ public struct TimelineView: View {
public var body: some View {
ZStack(alignment: .top) {
List {
scrollToTopView
TimelineTagGroupheaderView(group: $selectedTagGroup, timeline: $timeline)
TimelineTagHeaderView(tag: $viewModel.tag)
switch viewModel.timeline {
case .remoteLocal:
StatusesListView(fetcher: viewModel, client: client, routerPath: routerPath, isRemote: true)
default:
StatusesListView(fetcher: viewModel, client: client, routerPath: routerPath)
.environment(\.isHomeTimeline, timeline == .home)
}
}
.id(client.id)
.environment(\.defaultMinListRowHeight, 1)
.listStyle(.plain)
#if !os(visionOS)
.scrollContentBackground(.hidden)
.background(theme.primaryBackgroundColor)
#endif
.introspect(.list, on: .iOS(.v17, .v18)) { (collectionView: UICollectionView) in
DispatchQueue.main.async {
self.collectionView = collectionView
ScrollViewReader { proxy in
List {
scrollToTopView
TimelineTagGroupheaderView(group: $selectedTagGroup, timeline: $timeline)
TimelineTagHeaderView(tag: $viewModel.tag)
switch viewModel.timeline {
case .remoteLocal:
StatusesListView(fetcher: viewModel, client: client, routerPath: routerPath, isRemote: true)
default:
StatusesListView(fetcher: viewModel, client: client, routerPath: routerPath)
.environment(\.isHomeTimeline, timeline == .home)
}
prefetcher.viewModel = viewModel
collectionView.isPrefetchingEnabled = true
collectionView.prefetchDataSource = prefetcher
}
.id(client.id)
.environment(\.defaultMinListRowHeight, 1)
.listStyle(.plain)
.onChange(of: selectedTabScrollToTop) { _, newValue in
if newValue == 0, routerPath.path.isEmpty {
withAnimation {
proxy.scrollTo(ScrollToView.Constants.scrollToTop, anchor: .top)
}
}
}
#if !os(visionOS)
.scrollContentBackground(.hidden)
.background(theme.primaryBackgroundColor)
#endif
.introspect(.list, on: .iOS(.v17, .v18)) { (collectionView: UICollectionView) in
DispatchQueue.main.async {
self.collectionView = collectionView
}
prefetcher.viewModel = viewModel
collectionView.isPrefetchingEnabled = true
collectionView.prefetchDataSource = prefetcher
}
}
if viewModel.timeline.supportNewestPagination {
TimelineUnreadStatusesView(observer: viewModel.pendingStatusesObserver)
}