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 iosTabs = iOSTabs.shared
@State var sidebarTabs = SidebarTabs.shared @State var sidebarTabs = SidebarTabs.shared
@State var selectedTabScrollToTop: Int = -1
var body: some View { var body: some View {
#if os(visionOS) #if os(visionOS)
@ -75,6 +76,7 @@ struct AppView: View {
} }
.id(appAccountsManager.currentClient.id) .id(appAccountsManager.currentClient.id)
.withSheetDestinations(sheetDestinations: $appRouterPath.presentedSheet) .withSheetDestinations(sheetDestinations: $appRouterPath.presentedSheet)
.environment(\.selectedTabScrollToTop, selectedTabScrollToTop)
} }
private func updateTab(with newTab: AppTab) { private func updateTab(with newTab: AppTab) {
@ -90,6 +92,15 @@ struct AppView: View {
HapticManager.shared.fireHaptic(.tabSelection) HapticManager.shared.fireHaptic(.tabSelection)
SoundEffectManager.shared.playSound(.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 selectedTab = newTab
} }

View file

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

View file

@ -11,6 +11,8 @@ import SwiftUIIntrospect
@MainActor @MainActor
public struct TimelineView: View { public struct TimelineView: View {
@Environment(\.scenePhase) private var scenePhase @Environment(\.scenePhase) private var scenePhase
@Environment(\.selectedTabScrollToTop) private var selectedTabScrollToTop
@Environment(Theme.self) private var theme @Environment(Theme.self) private var theme
@Environment(CurrentAccount.self) private var account @Environment(CurrentAccount.self) private var account
@Environment(StreamWatcher.self) private var watcher @Environment(StreamWatcher.self) private var watcher
@ -45,33 +47,42 @@ public struct TimelineView: View {
public var body: some View { public var body: some View {
ZStack(alignment: .top) { ZStack(alignment: .top) {
List { ScrollViewReader { proxy in
scrollToTopView List {
TimelineTagGroupheaderView(group: $selectedTagGroup, timeline: $timeline) scrollToTopView
TimelineTagHeaderView(tag: $viewModel.tag) TimelineTagGroupheaderView(group: $selectedTagGroup, timeline: $timeline)
switch viewModel.timeline { TimelineTagHeaderView(tag: $viewModel.tag)
case .remoteLocal: switch viewModel.timeline {
StatusesListView(fetcher: viewModel, client: client, routerPath: routerPath, isRemote: true) case .remoteLocal:
default: StatusesListView(fetcher: viewModel, client: client, routerPath: routerPath, isRemote: true)
StatusesListView(fetcher: viewModel, client: client, routerPath: routerPath) default:
.environment(\.isHomeTimeline, timeline == .home) 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
} }
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 { if viewModel.timeline.supportNewestPagination {
TimelineUnreadStatusesView(observer: viewModel.pendingStatusesObserver) TimelineUnreadStatusesView(observer: viewModel.pendingStatusesObserver)
} }