diff --git a/IceCubesApp.xcodeproj/project.pbxproj b/IceCubesApp.xcodeproj/project.pbxproj index d3edaa11..580ca4a6 100644 --- a/IceCubesApp.xcodeproj/project.pbxproj +++ b/IceCubesApp.xcodeproj/project.pbxproj @@ -58,6 +58,8 @@ 9F55C68D2955968700F94077 /* ExploreTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F55C68C2955968700F94077 /* ExploreTab.swift */; }; 9F55C6902955993C00F94077 /* Explore in Frameworks */ = {isa = PBXBuildFile; productRef = 9F55C68F2955993C00F94077 /* Explore */; }; 9F5E581929545BE700A53960 /* Env in Frameworks */ = {isa = PBXBuildFile; productRef = 9F5E581829545BE700A53960 /* Env */; }; + 9F6028562B3F36AE00476078 /* AppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F6028552B3F36AE00476078 /* AppView.swift */; }; + 9F6028582B3F3B7600476078 /* ToolbarTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F6028572B3F3B7600476078 /* ToolbarTab.swift */; }; 9F654BEF299AC45B00D27FA5 /* ReportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F654BEE299AC45B00D27FA5 /* ReportView.swift */; }; 9F7335EA2966B3F800AFF0BA /* Conversations in Frameworks */ = {isa = PBXBuildFile; productRef = 9F7335E92966B3F800AFF0BA /* Conversations */; }; 9F7335ED2967463400AFF0BA /* AVKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F7335EB2967461B00AFF0BA /* AVKit.framework */; }; @@ -84,8 +86,6 @@ 9FB143D12983104700A27BB1 /* glass.caf in Resources */ = {isa = PBXBuildFile; fileRef = 9F2A542B296B1177009B2D7C /* glass.caf */; }; 9FB143D22983104A00A27BB1 /* glass.wav in Resources */ = {isa = PBXBuildFile; fileRef = 9F2A542D296B1CC0009B2D7C /* glass.wav */; }; 9FB183222AE9268800BBB692 /* IceCubesApp+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB183212AE9268800BBB692 /* IceCubesApp+Menu.swift */; }; - 9FB183252AE926E900BBB692 /* IceCubesApp+Sidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB183242AE926E900BBB692 /* IceCubesApp+Sidebar.swift */; }; - 9FB183272AE9279F00BBB692 /* IceCubesApp+Tabbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB183262AE9279F00BBB692 /* IceCubesApp+Tabbar.swift */; }; 9FB183292AE9449100BBB692 /* IceCubesApp+Scene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB183282AE9449100BBB692 /* IceCubesApp+Scene.swift */; }; 9FBFE63D292A715500C250E9 /* IceCubesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBFE63C292A715500C250E9 /* IceCubesApp.swift */; }; 9FBFE64E292A72BD00C250E9 /* Network in Frameworks */ = {isa = PBXBuildFile; productRef = 9FBFE64D292A72BD00C250E9 /* Network */; }; @@ -206,6 +206,8 @@ 9F55C68C2955968700F94077 /* ExploreTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreTab.swift; sourceTree = ""; }; 9F55C68E295598F900F94077 /* Explore */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Explore; path = Packages/Explore; sourceTree = ""; }; 9F5E581729545B5500A53960 /* Env */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Env; path = Packages/Env; sourceTree = ""; }; + 9F6028552B3F36AE00476078 /* AppView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppView.swift; sourceTree = ""; }; + 9F6028572B3F3B7600476078 /* ToolbarTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolbarTab.swift; sourceTree = ""; }; 9F62216829A68DA4007B77CA /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/InfoPlist.strings; sourceTree = ""; }; 9F654BEE299AC45B00D27FA5 /* ReportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportView.swift; sourceTree = ""; }; 9F7335E82966B3DC00AFF0BA /* Conversations */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Conversations; path = Packages/Conversations; sourceTree = ""; }; @@ -225,8 +227,6 @@ 9FAE4AC8293774FF00772766 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 9FAE4ACA293783B000772766 /* SettingsTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTab.swift; sourceTree = ""; }; 9FB183212AE9268800BBB692 /* IceCubesApp+Menu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IceCubesApp+Menu.swift"; sourceTree = ""; }; - 9FB183242AE926E900BBB692 /* IceCubesApp+Sidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IceCubesApp+Sidebar.swift"; sourceTree = ""; }; - 9FB183262AE9279F00BBB692 /* IceCubesApp+Tabbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IceCubesApp+Tabbar.swift"; sourceTree = ""; }; 9FB183282AE9449100BBB692 /* IceCubesApp+Scene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IceCubesApp+Scene.swift"; sourceTree = ""; }; 9FBFE639292A715500C250E9 /* Ice Cubes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Ice Cubes.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 9FBFE63C292A715500C250E9 /* IceCubesApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IceCubesApp.swift; sourceTree = ""; }; @@ -432,6 +432,7 @@ 9F4A48182976B21900A1A038 /* ProfileTab.swift */, 9F15D5FF2B3D6A850008C220 /* NavigationTab.swift */, 9F15D6032B3DC2180008C220 /* NavigationSheet.swift */, + 9F6028572B3F3B7600476078 /* ToolbarTab.swift */, ); path = Tabs; sourceTree = ""; @@ -441,9 +442,8 @@ children = ( 9FBFE63C292A715500C250E9 /* IceCubesApp.swift */, 9FB183212AE9268800BBB692 /* IceCubesApp+Menu.swift */, - 9FB183242AE926E900BBB692 /* IceCubesApp+Sidebar.swift */, - 9FB183262AE9279F00BBB692 /* IceCubesApp+Tabbar.swift */, 9FB183282AE9449100BBB692 /* IceCubesApp+Scene.swift */, + 9F6028552B3F36AE00476078 /* AppView.swift */, ); path = Main; sourceTree = ""; @@ -822,14 +822,12 @@ files = ( 9FE151A6293C90F900E9683D /* IconSelectorView.swift in Sources */, 9FB183222AE9268800BBB692 /* IceCubesApp+Menu.swift in Sources */, - 9FB183252AE926E900BBB692 /* IceCubesApp+Sidebar.swift in Sources */, 9F7D939A29805DBD00EE6B7A /* AccountSettingView.swift in Sources */, 069709AA298C9AD7006E4CB5 /* AboutView.swift in Sources */, 9F2B92FC295DA94500DE16D0 /* InstanceInfoView.swift in Sources */, C9B22677297F6C2E001F9EFE /* ContentSettingsView.swift in Sources */, 9F15D6042B3DC2180008C220 /* NavigationSheet.swift in Sources */, 9FA6FD6229C04A8800E2312C /* TranslationSettingsView.swift in Sources */, - 9FB183272AE9279F00BBB692 /* IceCubesApp+Tabbar.swift in Sources */, 9F35DB4C2952005C00B3281A /* MessagesTab.swift in Sources */, 9FAD85CF2975B68900496AB1 /* SideBarView.swift in Sources */, 9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */, @@ -850,9 +848,11 @@ 9F654BEF299AC45B00D27FA5 /* ReportView.swift in Sources */, D08A9C3529956CFA00204A4A /* SwipeActionsSettingsView.swift in Sources */, 9F7335F22967608F00AFF0BA /* AddRemoteTimelineView.swift in Sources */, + 9F6028562B3F36AE00476078 /* AppView.swift in Sources */, 9F55C68D2955968700F94077 /* ExploreTab.swift in Sources */, 9F1E8B47298EBCBB00609F80 /* HapticSettingsView.swift in Sources */, 9F2A5411296A1429009B2D7C /* PushNotificationsView.swift in Sources */, + 9F6028582B3F3B7600476078 /* ToolbarTab.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/IceCubesApp/App/Main/AppView.swift b/IceCubesApp/App/Main/AppView.swift new file mode 100644 index 00000000..884b5b85 --- /dev/null +++ b/IceCubesApp/App/Main/AppView.swift @@ -0,0 +1,135 @@ +import Account +import AppAccount +import AVFoundation +import DesignSystem +import Env +import KeychainSwift +import MediaUI +import Network +import RevenueCat +import Status +import SwiftUI +import Timeline + +@MainActor +struct AppView: View { + @Environment(AppAccountsManager.self) private var appAccountsManager + @Environment(UserPreferences.self) private var userPreferences + @Environment(Theme.self) private var theme + @Environment(StreamWatcher.self) private var watcher + + @Environment(\.horizontalSizeClass) var horizontalSizeClass + + @Binding var selectedTab: Tab + @Binding var sidebarRouterPath: RouterPath + + @State var popToRootTab: Tab = .other + @State var iosTabs = iOSTabs.shared + @State var sideBarLoadedTabs: Set = Set() + + var body: some View { + if (UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac) && + horizontalSizeClass == .regular { + sidebarView + } else { + tabBarView + } + } + + var availableTabs: [Tab] { + if UIDevice.current.userInterfaceIdiom == .phone || horizontalSizeClass == .compact { + return appAccountsManager.currentClient.isAuth ? iosTabs.tabs : Tab.loggedOutTab() + } + return appAccountsManager.currentClient.isAuth ? Tab.loggedInTabs() : Tab.loggedOutTab() + } + + var tabBarView: some View { + TabView(selection: .init(get: { + selectedTab + }, set: { newTab in + if newTab == selectedTab { + /// Stupid hack to trigger onChange binding in tab views. + popToRootTab = .other + DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { + popToRootTab = selectedTab + } + } + + HapticManager.shared.fireHaptic(.tabSelection) + SoundEffectManager.shared.playSound(.tabSelection) + + selectedTab = newTab + })) { + ForEach(availableTabs) { tab in + tab.makeContentView(selectedTab: $selectedTab, popToRootTab: $popToRootTab) + .tabItem { + if userPreferences.showiPhoneTabLabel { + tab.label + } else { + Image(systemName: tab.iconName) + } + } + .tag(tab) + .badge(badgeFor(tab: tab)) + .toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .tabBar) + } + } + .id(appAccountsManager.currentClient.id) + } + + private func badgeFor(tab: Tab) -> Int { + if tab == .notifications, selectedTab != tab, + let token = appAccountsManager.currentAccount.oauthToken + { + return watcher.unreadNotificationsCount + (userPreferences.notificationsCount[token] ?? 0) + } + return 0 + } + + var sidebarView: some View { + SideBarView(selectedTab: $selectedTab, + popToRootTab: $popToRootTab, + tabs: availableTabs) + { + HStack(spacing: 0) { + ZStack { + if selectedTab == .profile { + ProfileTab(popToRootTab: $popToRootTab) + } + ForEach(availableTabs) { tab in + if tab == selectedTab || sideBarLoadedTabs.contains(tab) { + tab + .makeContentView(selectedTab: $selectedTab, popToRootTab: $popToRootTab) + .opacity(tab == selectedTab ? 1 : 0) + .transition(.opacity) + .id("\(tab)\(appAccountsManager.currentAccount.id)") + .onAppear { + sideBarLoadedTabs.insert(tab) + } + } else { + EmptyView() + } + } + } + if appAccountsManager.currentClient.isAuth, + userPreferences.showiPadSecondaryColumn + { + Divider().edgesIgnoringSafeArea(.all) + notificationsSecondaryColumn + } + } + }.onChange(of: appAccountsManager.currentAccount.id) { + sideBarLoadedTabs.removeAll() + } + .environment(sidebarRouterPath) + } + + var notificationsSecondaryColumn: some View { + NotificationsTab(selectedTab: .constant(.notifications), + popToRootTab: $popToRootTab, lockedType: nil) + .environment(\.isSecondaryColumn, true) + .frame(maxWidth: .secondaryColumnWidth) + .id(appAccountsManager.currentAccount.id) + } +} + diff --git a/IceCubesApp/App/Main/IceCubesApp+Scene.swift b/IceCubesApp/App/Main/IceCubesApp+Scene.swift index ac549052..c036c1ab 100644 --- a/IceCubesApp/App/Main/IceCubesApp+Scene.swift +++ b/IceCubesApp/App/Main/IceCubesApp+Scene.swift @@ -6,7 +6,7 @@ import SwiftUI extension IceCubesApp { var appScene: some Scene { WindowGroup(id: "MainWindow") { - appView + AppView(selectedTab: $selectedTab, sidebarRouterPath: $sidebarRouterPath) .applyTheme(theme) .onAppear { setNewClientsInEnv(client: appAccountsManager.currentClient) @@ -63,15 +63,6 @@ extension IceCubesApp { } } - @ViewBuilder - private var appView: some View { - if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac { - sidebarView - } else { - tabBarView - } - } - @SceneBuilder var otherScenes: some Scene { WindowGroup(for: WindowDestinationEditor.self) { destination in diff --git a/IceCubesApp/App/Main/IceCubesApp+Sidebar.swift b/IceCubesApp/App/Main/IceCubesApp+Sidebar.swift deleted file mode 100644 index 74afe6e3..00000000 --- a/IceCubesApp/App/Main/IceCubesApp+Sidebar.swift +++ /dev/null @@ -1,50 +0,0 @@ -import Env -import SwiftUI - -extension IceCubesApp { - var sidebarView: some View { - SideBarView(selectedTab: $selectedTab, - popToRootTab: $popToRootTab, - tabs: availableTabs) - { - HStack(spacing: 0) { - ZStack { - if selectedTab == .profile { - ProfileTab(popToRootTab: $popToRootTab) - } - ForEach(availableTabs) { tab in - if tab == selectedTab || sideBarLoadedTabs.contains(tab) { - tab - .makeContentView(selectedTab: $selectedTab, popToRootTab: $popToRootTab) - .opacity(tab == selectedTab ? 1 : 0) - .transition(.opacity) - .id("\(tab)\(appAccountsManager.currentAccount.id)") - .onAppear { - sideBarLoadedTabs.insert(tab) - } - } else { - EmptyView() - } - } - } - if appAccountsManager.currentClient.isAuth, - userPreferences.showiPadSecondaryColumn - { - Divider().edgesIgnoringSafeArea(.all) - notificationsSecondaryColumn - } - } - }.onChange(of: $appAccountsManager.currentAccount.id) { - sideBarLoadedTabs.removeAll() - } - .environment(sidebarRouterPath) - } - - var notificationsSecondaryColumn: some View { - NotificationsTab(selectedTab: .constant(.notifications), - popToRootTab: $popToRootTab, lockedType: nil) - .environment(\.isSecondaryColumn, true) - .frame(maxWidth: .secondaryColumnWidth) - .id(appAccountsManager.currentAccount.id) - } -} diff --git a/IceCubesApp/App/Main/IceCubesApp+Tabbar.swift b/IceCubesApp/App/Main/IceCubesApp+Tabbar.swift deleted file mode 100644 index 32ccd4a0..00000000 --- a/IceCubesApp/App/Main/IceCubesApp+Tabbar.swift +++ /dev/null @@ -1,47 +0,0 @@ -import Env -import SwiftUI - -extension IceCubesApp { - var tabBarView: some View { - TabView(selection: .init(get: { - selectedTab - }, set: { newTab in - if newTab == selectedTab { - /// Stupid hack to trigger onChange binding in tab views. - popToRootTab = .other - DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { - popToRootTab = selectedTab - } - } - - HapticManager.shared.fireHaptic(.tabSelection) - SoundEffectManager.shared.playSound(.tabSelection) - - selectedTab = newTab - })) { - ForEach(availableTabs) { tab in - tab.makeContentView(selectedTab: $selectedTab, popToRootTab: $popToRootTab) - .tabItem { - if userPreferences.showiPhoneTabLabel { - tab.label - } else { - Image(systemName: tab.iconName) - } - } - .tag(tab) - .badge(badgeFor(tab: tab)) - .toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .tabBar) - } - } - .id(appAccountsManager.currentClient.id) - } - - private func badgeFor(tab: Tab) -> Int { - if tab == .notifications, selectedTab != tab, - let token = appAccountsManager.currentAccount.oauthToken - { - return watcher.unreadNotificationsCount + (userPreferences.notificationsCount[token] ?? 0) - } - return 0 - } -} diff --git a/IceCubesApp/App/Main/IceCubesApp.swift b/IceCubesApp/App/Main/IceCubesApp.swift index 53659af5..37662820 100644 --- a/IceCubesApp/App/Main/IceCubesApp.swift +++ b/IceCubesApp/App/Main/IceCubesApp.swift @@ -26,21 +26,12 @@ struct IceCubesApp: App { @State var watcher = StreamWatcher() @State var quickLook = QuickLook.shared @State var theme = Theme.shared - @State var sidebarRouterPath = RouterPath() - + @State var selectedTab: Tab = .timeline - @State var popToRootTab: Tab = .other - @State var iosTabs = iOSTabs.shared - @State var sideBarLoadedTabs: Set = Set() + @State var sidebarRouterPath = RouterPath() + @State var isSupporter: Bool = false - var availableTabs: [Tab] { - if UIDevice.current.userInterfaceIdiom == .phone { - return appAccountsManager.currentClient.isAuth ? iosTabs.tabs : Tab.loggedOutTab() - } - return appAccountsManager.currentClient.isAuth ? Tab.loggedInTabs() : Tab.loggedOutTab() - } - var body: some Scene { appScene otherScenes diff --git a/IceCubesApp/App/Tabs/ExploreTab.swift b/IceCubesApp/App/Tabs/ExploreTab.swift index 75c4cf88..844f36e8 100644 --- a/IceCubesApp/App/Tabs/ExploreTab.swift +++ b/IceCubesApp/App/Tabs/ExploreTab.swift @@ -24,16 +24,7 @@ struct ExploreTab: View { .withSheetDestinations(sheetDestinations: $routerPath.presentedSheet) .toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar) .toolbar { - statusEditorToolbarItem(routerPath: routerPath, - visibility: preferences.postVisibility) - if UIDevice.current.userInterfaceIdiom != .pad { - ToolbarItem(placement: .navigationBarLeading) { - AppAccountsSelectorView(routerPath: routerPath) - } - } - if UIDevice.current.userInterfaceIdiom == .pad, !preferences.showiPadSecondaryColumn { - SecondaryColumnToolbarItem() - } + ToolbarTab(routerPath: $routerPath) } } .withSafariRouter() diff --git a/IceCubesApp/App/Tabs/MessagesTab.swift b/IceCubesApp/App/Tabs/MessagesTab.swift index d7740951..8c881f58 100644 --- a/IceCubesApp/App/Tabs/MessagesTab.swift +++ b/IceCubesApp/App/Tabs/MessagesTab.swift @@ -25,11 +25,7 @@ struct MessagesTab: View { .withAppRouter() .withSheetDestinations(sheetDestinations: $routerPath.presentedSheet) .toolbar { - if UIDevice.current.userInterfaceIdiom != .pad { - ToolbarItem(placement: .navigationBarLeading) { - AppAccountsSelectorView(routerPath: routerPath) - } - } + ToolbarTab(routerPath: $routerPath) } .toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar) .id(client.id) diff --git a/IceCubesApp/App/Tabs/NavigationTab.swift b/IceCubesApp/App/Tabs/NavigationTab.swift index 11193a86..39b58c13 100644 --- a/IceCubesApp/App/Tabs/NavigationTab.swift +++ b/IceCubesApp/App/Tabs/NavigationTab.swift @@ -27,20 +27,7 @@ struct NavigationTab: View { .withAppRouter() .withSheetDestinations(sheetDestinations: $routerPath.presentedSheet) .toolbar { - if !isSecondaryColumn { - statusEditorToolbarItem(routerPath: routerPath, - visibility: userPreferences.postVisibility) - if UIDevice.current.userInterfaceIdiom != .pad { - ToolbarItem(placement: .navigationBarLeading) { - AppAccountsSelectorView(routerPath: routerPath) - } - } - } - if UIDevice.current.userInterfaceIdiom == .pad { - if (!isSecondaryColumn && !userPreferences.showiPadSecondaryColumn) || isSecondaryColumn { - SecondaryColumnToolbarItem() - } - } + ToolbarTab(routerPath: $routerPath) } .toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar) } diff --git a/IceCubesApp/App/Tabs/NotificationTab.swift b/IceCubesApp/App/Tabs/NotificationTab.swift index 4fb6c81f..e76b9abd 100644 --- a/IceCubesApp/App/Tabs/NotificationTab.swift +++ b/IceCubesApp/App/Tabs/NotificationTab.swift @@ -40,20 +40,7 @@ struct NotificationsTab: View { Image(systemName: "bell.badge") } } - if !isSecondaryColumn { - statusEditorToolbarItem(routerPath: routerPath, - visibility: userPreferences.postVisibility) - if UIDevice.current.userInterfaceIdiom != .pad { - ToolbarItem(placement: .navigationBarLeading) { - AppAccountsSelectorView(routerPath: routerPath) - } - } - } - if UIDevice.current.userInterfaceIdiom == .pad { - if (!isSecondaryColumn && !userPreferences.showiPadSecondaryColumn) || isSecondaryColumn { - SecondaryColumnToolbarItem() - } - } + ToolbarTab(routerPath: $routerPath) } .toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar) .id(client.id) diff --git a/IceCubesApp/App/Tabs/Settings/SettingsTab.swift b/IceCubesApp/App/Tabs/Settings/SettingsTab.swift index a6235c3a..1a4279d8 100644 --- a/IceCubesApp/App/Tabs/Settings/SettingsTab.swift +++ b/IceCubesApp/App/Tabs/Settings/SettingsTab.swift @@ -14,6 +14,7 @@ import Timeline struct SettingsTabs: View { @Environment(\.dismiss) private var dismiss @Environment(\.modelContext) private var context + @Environment(\.horizontalSizeClass) private var horizontalSizeClass @Environment(PushNotificationsService.self) private var pushNotifications @Environment(UserPreferences.self) private var preferences @@ -160,7 +161,7 @@ struct SettingsTabs: View { NavigationLink(destination: SwipeActionsSettingsView()) { Label("settings.general.swipeactions", systemImage: "hand.draw") } - if UIDevice.current.userInterfaceIdiom == .phone { + if UIDevice.current.userInterfaceIdiom == .phone || horizontalSizeClass == .compact { NavigationLink(destination: TabbarEntriesSettingsView()) { Label("settings.general.tabbarEntries", systemImage: "platter.filled.bottom.iphone") } diff --git a/IceCubesApp/App/Tabs/Timeline/TimelineTab.swift b/IceCubesApp/App/Tabs/Timeline/TimelineTab.swift index fdcf138f..02ed9b0d 100644 --- a/IceCubesApp/App/Tabs/Timeline/TimelineTab.swift +++ b/IceCubesApp/App/Tabs/Timeline/TimelineTab.swift @@ -228,17 +228,7 @@ struct TimelineTab: View { } } if client.isAuth { - if UIDevice.current.userInterfaceIdiom != .pad { - ToolbarItem(placement: .navigationBarLeading) { - AppAccountsSelectorView(routerPath: routerPath) - .id(currentAccount.account?.id) - } - } - statusEditorToolbarItem(routerPath: routerPath, - visibility: preferences.postVisibility) - if UIDevice.current.userInterfaceIdiom == .pad, !preferences.showiPadSecondaryColumn { - SecondaryColumnToolbarItem() - } + ToolbarTab(routerPath: $routerPath) } else { ToolbarItem(placement: .navigationBarTrailing) { addAccountButton diff --git a/IceCubesApp/App/Tabs/ToolbarTab.swift b/IceCubesApp/App/Tabs/ToolbarTab.swift new file mode 100644 index 00000000..ff36b40d --- /dev/null +++ b/IceCubesApp/App/Tabs/ToolbarTab.swift @@ -0,0 +1,32 @@ +import SwiftUI +import Env +import AppAccount +import DesignSystem + +@MainActor +struct ToolbarTab: ToolbarContent { + @Environment(\.isSecondaryColumn) private var isSecondaryColumn: Bool + @Environment(\.horizontalSizeClass) private var horizontalSizeClass + + @Environment(UserPreferences.self) private var userPreferences + + @Binding var routerPath: RouterPath + + var body: some ToolbarContent { + if !isSecondaryColumn { + statusEditorToolbarItem(routerPath: routerPath, + visibility: userPreferences.postVisibility) + if UIDevice.current.userInterfaceIdiom != .pad || + (UIDevice.current.userInterfaceIdiom == .pad && horizontalSizeClass == .compact) { + ToolbarItem(placement: .navigationBarLeading) { + AppAccountsSelectorView(routerPath: routerPath) + } + } + } + if UIDevice.current.userInterfaceIdiom == .pad && horizontalSizeClass == .regular { + if (!isSecondaryColumn && !userPreferences.showiPadSecondaryColumn) || isSecondaryColumn { + SecondaryColumnToolbarItem() + } + } + } +} diff --git a/Packages/DesignSystem/Sources/DesignSystem/Views/StatusEditorToolbarItem.swift b/Packages/DesignSystem/Sources/DesignSystem/Views/StatusEditorToolbarItem.swift index 496d24ae..29e0cdad 100644 --- a/Packages/DesignSystem/Sources/DesignSystem/Views/StatusEditorToolbarItem.swift +++ b/Packages/DesignSystem/Sources/DesignSystem/Views/StatusEditorToolbarItem.swift @@ -11,6 +11,15 @@ public extension View { } } +@MainActor +public extension ToolbarContent { + func statusEditorToolbarItem(routerPath _: RouterPath, + visibility: Models.Visibility) -> some ToolbarContent + { + StatusEditorToolbarItem(visibility: visibility) + } +} + @MainActor public struct StatusEditorToolbarItem: ToolbarContent { @Environment(\.openWindow) private var openWindow