mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2025-01-12 17:15:30 +00:00
Cleanup scrollToTop
This commit is contained in:
parent
7c2e8d6e80
commit
1ffb4ab901
12 changed files with 79 additions and 139 deletions
|
@ -19,9 +19,9 @@ extension View {
|
|||
navigationDestination(for: RouterDestination.self) { destination in
|
||||
switch destination {
|
||||
case let .accountDetail(id):
|
||||
AccountDetailView(accountId: id, scrollToTopSignal: .constant(0))
|
||||
AccountDetailView(accountId: id)
|
||||
case let .accountDetailWithAccount(account):
|
||||
AccountDetailView(account: account, scrollToTopSignal: .constant(0))
|
||||
AccountDetailView(account: account)
|
||||
case let .accountSettingsWithAccount(account, appAccount):
|
||||
AccountSettingsView(account: account, appAccount: appAccount)
|
||||
case let .statusDetail(id):
|
||||
|
@ -36,19 +36,16 @@ extension View {
|
|||
TimelineView(timeline: .constant(.hashtag(tag: tag, accountId: accountId)),
|
||||
pinnedFilters: .constant([]),
|
||||
selectedTagGroup: .constant(nil),
|
||||
scrollToTopSignal: .constant(0),
|
||||
canFilterTimeline: false)
|
||||
case let .list(list):
|
||||
TimelineView(timeline: .constant(.list(list: list)),
|
||||
pinnedFilters: .constant([]),
|
||||
selectedTagGroup: .constant(nil),
|
||||
scrollToTopSignal: .constant(0),
|
||||
canFilterTimeline: false)
|
||||
case let .linkTimeline(url, title):
|
||||
TimelineView(timeline: .constant(.link(url: url, title: title)),
|
||||
pinnedFilters: .constant([]),
|
||||
selectedTagGroup: .constant(nil),
|
||||
scrollToTopSignal: .constant(0),
|
||||
canFilterTimeline: false)
|
||||
case let .following(id):
|
||||
AccountsListView(mode: .following(accountId: id))
|
||||
|
@ -64,7 +61,6 @@ extension View {
|
|||
TimelineView(timeline: .constant(.trending),
|
||||
pinnedFilters: .constant([]),
|
||||
selectedTagGroup: .constant(nil),
|
||||
scrollToTopSignal: .constant(0),
|
||||
canFilterTimeline: false)
|
||||
case let .trendingLinks(cards):
|
||||
TrendingLinksListView(cards: cards)
|
||||
|
@ -74,8 +70,7 @@ extension View {
|
|||
NotificationsRequestsListView()
|
||||
case let .notificationForAccount(accountId):
|
||||
NotificationsListView(lockedType: nil,
|
||||
lockedAccountId: accountId,
|
||||
scrollToTopSignal: .constant(0))
|
||||
lockedAccountId: accountId)
|
||||
case .blockedAccounts:
|
||||
AccountsListView(mode: .blocked)
|
||||
case .mutedAccounts:
|
||||
|
|
|
@ -70,8 +70,10 @@ struct AppView: View {
|
|||
selectedTab = newTab
|
||||
})) {
|
||||
ForEach(availableTabs) { tab in
|
||||
Tab(value: tab) {
|
||||
tab.makeContentView(selectedTab: $selectedTab)
|
||||
.tabItem {
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .tabBar)
|
||||
} label: {
|
||||
if userPreferences.showiPhoneTabLabel {
|
||||
tab.label
|
||||
.environment(\.symbolVariants, tab == selectedTab ? .fill : .none)
|
||||
|
@ -79,9 +81,7 @@ struct AppView: View {
|
|||
Image(systemName: tab.iconName)
|
||||
}
|
||||
}
|
||||
.tag(tab)
|
||||
.badge(badgeFor(tab: tab))
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .tabBar)
|
||||
}
|
||||
}
|
||||
.id(appAccountsManager.currentClient.id)
|
||||
|
|
|
@ -13,11 +13,10 @@ struct ExploreTab: View {
|
|||
@Environment(CurrentAccount.self) private var currentAccount
|
||||
@Environment(Client.self) private var client
|
||||
@State private var routerPath = RouterPath()
|
||||
@State private var scrollToTopSignal: Int = 0
|
||||
|
||||
var body: some View {
|
||||
NavigationStack(path: $routerPath.path) {
|
||||
ExploreView(scrollToTopSignal: $scrollToTopSignal)
|
||||
ExploreView()
|
||||
.withAppRouter()
|
||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||
|
|
|
@ -15,11 +15,10 @@ struct MessagesTab: View {
|
|||
@Environment(CurrentAccount.self) private var currentAccount
|
||||
@Environment(AppAccountsManager.self) private var appAccount
|
||||
@State private var routerPath = RouterPath()
|
||||
@State private var scrollToTopSignal: Int = 0
|
||||
|
||||
var body: some View {
|
||||
NavigationStack(path: $routerPath.path) {
|
||||
ConversationsListView(scrollToTopSignal: $scrollToTopSignal)
|
||||
ConversationsListView()
|
||||
.withAppRouter()
|
||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||
.toolbar {
|
||||
|
|
|
@ -20,7 +20,6 @@ struct NotificationsTab: View {
|
|||
@Environment(UserPreferences.self) private var userPreferences
|
||||
@Environment(PushNotificationsService.self) private var pushNotificationsService
|
||||
@State private var routerPath = RouterPath()
|
||||
@State private var scrollToTopSignal: Int = 0
|
||||
|
||||
@Binding var selectedTab: AppTab
|
||||
|
||||
|
@ -28,7 +27,7 @@ struct NotificationsTab: View {
|
|||
|
||||
var body: some View {
|
||||
NavigationStack(path: $routerPath.path) {
|
||||
NotificationsListView(lockedType: lockedType, scrollToTopSignal: $scrollToTopSignal)
|
||||
NotificationsListView(lockedType: lockedType)
|
||||
.withAppRouter()
|
||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||
.toolbar {
|
||||
|
|
|
@ -14,18 +14,17 @@ struct ProfileTab: View {
|
|||
@Environment(Client.self) private var client
|
||||
@Environment(CurrentAccount.self) private var currentAccount
|
||||
@State private var routerPath = RouterPath()
|
||||
@State private var scrollToTopSignal: Int = 0
|
||||
|
||||
var body: some View {
|
||||
NavigationStack(path: $routerPath.path) {
|
||||
if let account = currentAccount.account {
|
||||
AccountDetailView(account: account, scrollToTopSignal: $scrollToTopSignal)
|
||||
AccountDetailView(account: account)
|
||||
.withAppRouter()
|
||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||
.id(account.id)
|
||||
} else {
|
||||
AccountDetailView(account: .placeholder(), scrollToTopSignal: $scrollToTopSignal)
|
||||
AccountDetailView(account: .placeholder())
|
||||
.redacted(reason: .placeholder)
|
||||
.allowsHitTesting(false)
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ struct TimelineTab: View {
|
|||
@State private var didAppear: Bool = false
|
||||
@State private var timeline: TimelineFilter = .home
|
||||
@State private var selectedTagGroup: TagGroup?
|
||||
@State private var scrollToTopSignal: Int = 0
|
||||
|
||||
@Query(sort: \LocalTimeline.creationDate, order: .reverse) var localTimelines: [LocalTimeline]
|
||||
@Query(sort: \TagGroup.creationDate, order: .reverse) var tagGroups: [TagGroup]
|
||||
|
@ -42,7 +41,6 @@ struct TimelineTab: View {
|
|||
TimelineView(timeline: $timeline,
|
||||
pinnedFilters: $pinnedFilters,
|
||||
selectedTagGroup: $selectedTagGroup,
|
||||
scrollToTopSignal: $scrollToTopSignal,
|
||||
canFilterTimeline: canFilterTimeline)
|
||||
.withAppRouter()
|
||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||
|
|
|
@ -28,18 +28,14 @@ public struct AccountDetailView: View {
|
|||
|
||||
@State private var displayTitle: Bool = false
|
||||
|
||||
@Binding var scrollToTopSignal: Int
|
||||
|
||||
/// When coming from a URL like a mention tap in a status.
|
||||
public init(accountId: String, scrollToTopSignal: Binding<Int>) {
|
||||
public init(accountId: String) {
|
||||
_viewModel = .init(initialValue: .init(accountId: accountId))
|
||||
_scrollToTopSignal = scrollToTopSignal
|
||||
}
|
||||
|
||||
/// When the account is already fetched by the parent caller.
|
||||
public init(account: Account, scrollToTopSignal: Binding<Int>) {
|
||||
public init(account: Account) {
|
||||
_viewModel = .init(initialValue: .init(account: account))
|
||||
_scrollToTopSignal = scrollToTopSignal
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
|
@ -89,11 +85,6 @@ public struct AccountDetailView: View {
|
|||
.scrollContentBackground(.hidden)
|
||||
.background(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
.onChange(of: scrollToTopSignal) {
|
||||
withAnimation {
|
||||
proxy.scrollTo(ScrollToView.Constants.scrollToTop, anchor: .top)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
guard reasons != .placeholder else { return }
|
||||
|
@ -403,6 +394,6 @@ extension View {
|
|||
|
||||
struct AccountDetailView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
AccountDetailView(account: .placeholder(), scrollToTopSignal: .constant(0))
|
||||
AccountDetailView(account: .placeholder())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,11 +14,7 @@ public struct ConversationsListView: View {
|
|||
|
||||
@State private var viewModel = ConversationsListViewModel()
|
||||
|
||||
@Binding var scrollToTopSignal: Int
|
||||
|
||||
public init(scrollToTopSignal: Binding<Int>) {
|
||||
_scrollToTopSignal = scrollToTopSignal
|
||||
}
|
||||
public init() { }
|
||||
|
||||
private var conversations: Binding<[Conversation]> {
|
||||
if viewModel.isLoadingFirstPage {
|
||||
|
@ -89,11 +85,6 @@ public struct ConversationsListView: View {
|
|||
viewModel.handleEvent(event: latestEvent)
|
||||
}
|
||||
}
|
||||
.onChange(of: scrollToTopSignal) {
|
||||
withAnimation {
|
||||
proxy.scrollTo(ScrollToView.Constants.scrollToTop, anchor: .top)
|
||||
}
|
||||
}
|
||||
.refreshable {
|
||||
// note: this Task wrapper should not be necessary, but it reportedly crashes without it
|
||||
// when refreshing on an empty list
|
||||
|
|
|
@ -14,11 +14,7 @@ public struct ExploreView: View {
|
|||
|
||||
@State private var viewModel = ExploreViewModel()
|
||||
|
||||
@Binding var scrollToTopSignal: Int
|
||||
|
||||
public init(scrollToTopSignal: Binding<Int>) {
|
||||
_scrollToTopSignal = scrollToTopSignal
|
||||
}
|
||||
public init() { }
|
||||
|
||||
public var body: some View {
|
||||
ScrollViewReader { proxy in
|
||||
|
@ -111,15 +107,6 @@ public struct ExploreView: View {
|
|||
.task(id: viewModel.searchQuery) {
|
||||
await viewModel.search()
|
||||
}
|
||||
.onChange(of: scrollToTopSignal) {
|
||||
if viewModel.scrollToTopVisible {
|
||||
viewModel.isSearchPresented.toggle()
|
||||
} else {
|
||||
withAnimation {
|
||||
proxy.scrollTo(ScrollToView.Constants.scrollToTop, anchor: .top)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,18 +17,15 @@ public struct NotificationsListView: View {
|
|||
|
||||
@State private var viewModel = NotificationsViewModel()
|
||||
@State private var isNotificationsPolicyPresented: Bool = false
|
||||
@Binding var scrollToTopSignal: Int
|
||||
|
||||
let lockedType: Models.Notification.NotificationType?
|
||||
let lockedAccountId: String?
|
||||
|
||||
public init(lockedType: Models.Notification.NotificationType? = nil,
|
||||
lockedAccountId: String? = nil,
|
||||
scrollToTopSignal: Binding<Int>)
|
||||
lockedAccountId: String? = nil)
|
||||
{
|
||||
self.lockedType = lockedType
|
||||
self.lockedAccountId = lockedAccountId
|
||||
_scrollToTopSignal = scrollToTopSignal
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
|
@ -44,11 +41,6 @@ public struct NotificationsListView: View {
|
|||
.id(account.account?.id)
|
||||
.environment(\.defaultMinListRowHeight, 1)
|
||||
.listStyle(.plain)
|
||||
.onChange(of: scrollToTopSignal) {
|
||||
withAnimation {
|
||||
proxy.scrollTo(ScrollToView.Constants.scrollToTop, anchor: .top)
|
||||
}
|
||||
}
|
||||
}
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .principal) {
|
||||
|
|
|
@ -27,7 +27,6 @@ public struct TimelineView: View {
|
|||
@Binding var timeline: TimelineFilter
|
||||
@Binding var pinnedFilters: [TimelineFilter]
|
||||
@Binding var selectedTagGroup: TagGroup?
|
||||
@Binding var scrollToTopSignal: Int
|
||||
|
||||
@Query(sort: \TagGroup.creationDate, order: .reverse) var tagGroups: [TagGroup]
|
||||
|
||||
|
@ -36,18 +35,15 @@ public struct TimelineView: View {
|
|||
public init(timeline: Binding<TimelineFilter>,
|
||||
pinnedFilters: Binding<[TimelineFilter]>,
|
||||
selectedTagGroup: Binding<TagGroup?>,
|
||||
scrollToTopSignal: Binding<Int>,
|
||||
canFilterTimeline: Bool)
|
||||
{
|
||||
_timeline = timeline
|
||||
_pinnedFilters = pinnedFilters
|
||||
_selectedTagGroup = selectedTagGroup
|
||||
_scrollToTopSignal = scrollToTopSignal
|
||||
self.canFilterTimeline = canFilterTimeline
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
ScrollViewReader { proxy in
|
||||
ZStack(alignment: .top) {
|
||||
List {
|
||||
scrollToTopView
|
||||
|
@ -108,12 +104,6 @@ public struct TimelineView: View {
|
|||
viewModel.scrollToIndex = nil
|
||||
}
|
||||
}
|
||||
.onChange(of: scrollToTopSignal) {
|
||||
withAnimation {
|
||||
proxy.scrollTo(ScrollToView.Constants.scrollToTop, anchor: .top)
|
||||
}
|
||||
}
|
||||
}
|
||||
.toolbar {
|
||||
toolbarTitleView
|
||||
toolbarTagGroupButton
|
||||
|
|
Loading…
Reference in a new issue