Refactor macOS / iPad sidebar

This commit is contained in:
Thomas Ricouard 2023-01-16 19:51:05 +01:00
parent c05768c793
commit 666e2b4d5f
3 changed files with 81 additions and 53 deletions

View file

@ -54,6 +54,7 @@
9FAD85A2297456A400496AB1 /* Env in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD85A1297456A400496AB1 /* Env */; };
9FAD85A4297456A800496AB1 /* DesignSystem in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD85A3297456A800496AB1 /* DesignSystem */; };
9FAD85A8297582F100496AB1 /* QuickLookRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAD85A7297582F100496AB1 /* QuickLookRepresentable.swift */; };
9FAD85CF2975B68900496AB1 /* SideBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAD85CE2975B68900496AB1 /* SideBarView.swift */; };
9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAE4ACA293783B000772766 /* SettingsTab.swift */; };
9FAE4ACE29379A5A00772766 /* KeychainSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAE4ACD29379A5A00772766 /* KeychainSwift */; };
9FBFE63D292A715500C250E9 /* IceCubesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBFE63C292A715500C250E9 /* IceCubesApp.swift */; };
@ -139,6 +140,7 @@
9FAD858F29743F7400496AB1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9FAD859629743F7E00496AB1 /* IceCubesShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = IceCubesShareExtension.entitlements; sourceTree = "<group>"; };
9FAD85A7297582F100496AB1 /* QuickLookRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickLookRepresentable.swift; sourceTree = "<group>"; };
9FAD85CE2975B68900496AB1 /* SideBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideBarView.swift; sourceTree = "<group>"; };
9FAE4AC8293774FF00772766 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
9FAE4ACA293783B000772766 /* SettingsTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTab.swift; sourceTree = "<group>"; };
9FBFE639292A715500C250E9 /* IceCubesApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IceCubesApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -221,6 +223,7 @@
9F398AA52935FE8A00A889F2 /* AppRouteur.swift */,
639CDF9B296AC82F00C35E58 /* SafariRouteur.swift */,
9FAD85A7297582F100496AB1 /* QuickLookRepresentable.swift */,
9FAD85CE2975B68900496AB1 /* SideBarView.swift */,
);
path = App;
sourceTree = "<group>";
@ -526,6 +529,7 @@
9FE151A6293C90F900E9683D /* IconSelectorView.swift in Sources */,
9F2B92FC295DA94500DE16D0 /* InstanceInfoView.swift in Sources */,
9F35DB4C2952005C00B3281A /* MessagesTab.swift in Sources */,
9FAD85CF2975B68900496AB1 /* SideBarView.swift in Sources */,
9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */,
9F7335F92968576500AFF0BA /* DisplaySettingsView.swift in Sources */,
9F2A540729699698009B2D7C /* SupportAppView.swift in Sources */,

View file

@ -25,6 +25,7 @@ struct IceCubesApp: App {
@State private var selectedTab: Tab = .timeline
@State private var selectSidebarItem: Tab? = .timeline
@State private var popToRootTab: Tab = .other
@State private var sideBarLoadedTabs: [Tab] = []
private var availableTabs: [Tab] {
appAccountsManager.currentClient.isAuth ? Tab.loggedInTabs() : Tab.loggedOutTab()
@ -81,48 +82,31 @@ struct IceCubesApp: App {
}
private var sidebarView: some View {
HStack(spacing: 0) {
VStack(alignment: .center) {
if let account = currentAccount.account {
AvatarView(url: account.avatar)
.frame(width: 70, height: 50)
.background(selectedTab == .profile ? theme.secondaryBackgroundColor : .clear)
.onTapGesture {
selectedTab = .profile
}
}
SideBarView(selectedTab: $selectedTab,
popToRootTab: $popToRootTab,
tabs: availableTabs) { selectedTab in
ZStack {
ForEach(availableTabs) { tab in
Button {
if tab == selectedTab {
popToRootTab = .other
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
popToRootTab = tab
}
}
selectedTab = tab
} label: {
Image(systemName: tab.iconName)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 24, height: 24)
.foregroundColor(tab == selectedTab ? theme.tintColor : .gray)
}
.frame(width: 70, height: 50)
.background(tab == selectedTab ? theme.secondaryBackgroundColor : .clear)
}
Spacer()
}
.frame(width: 70)
.background(.clear)
Divider()
.edgesIgnoringSafeArea(.top)
if selectedTab == .profile, let account = currentAccount.account {
if let account = currentAccount.account {
AccountDetailView(account: account)
.opacity(selectedTab == .profile ? 1 : 0)
}
if tab == selectedTab || sideBarLoadedTabs.contains(tab) {
tab
.makeContentView(popToRootTab: $popToRootTab)
.opacity(tab == selectedTab ? 1 : 0)
.id(tab)
.onAppear {
if !sideBarLoadedTabs.contains(tab) {
sideBarLoadedTabs.append(tab)
}
}
} else {
selectedTab.makeContentView(popToRootTab: $popToRootTab)
EmptyView()
}
}
}
}
.background(.thinMaterial)
}
private var tabBarView: some View {
@ -150,21 +134,6 @@ struct IceCubesApp: App {
}
}
private var splitView: some View {
NavigationSplitView {
List(availableTabs, selection: $selectSidebarItem) { tab in
NavigationLink(value: tab) {
tab.label
}
}
.scrollContentBackground(.hidden)
.background(theme.secondaryBackgroundColor)
.navigationSplitViewColumnWidth(200)
} detail: {
selectSidebarItem?.makeContentView(popToRootTab: $popToRootTab)
}
}
private func setNewClientsInEnv(client: Client) {
currentAccount.setClient(client: client)
currentInstance.setClient(client: client)

View file

@ -0,0 +1,55 @@
import SwiftUI
import Env
import Account
import DesignSystem
struct SideBarView<Content: View>: View {
@EnvironmentObject private var currentAccount: CurrentAccount
@EnvironmentObject private var theme: Theme
@Binding var selectedTab: Tab
@Binding var popToRootTab: Tab
var tabs: [Tab]
@ViewBuilder var content: (Tab) -> Content
var body: some View {
HStack(spacing: 0) {
VStack(alignment: .center) {
if let account = currentAccount.account {
AvatarView(url: account.avatar)
.frame(width: 70, height: 50)
.background(selectedTab == .profile ? theme.secondaryBackgroundColor : .clear)
.onTapGesture {
selectedTab = .profile
}
}
ForEach(tabs) { tab in
Button {
if tab == selectedTab {
popToRootTab = .other
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
popToRootTab = tab
}
}
selectedTab = tab
} label: {
Image(systemName: tab.iconName)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 24, height: 24)
.foregroundColor(tab == selectedTab ? theme.tintColor : .gray)
}
.frame(width: 70, height: 50)
.background(tab == selectedTab ? theme.secondaryBackgroundColor : .clear)
}
Spacer()
}
.frame(width: 70)
.background(.clear)
Divider()
.edgesIgnoringSafeArea(.top)
content(selectedTab)
}
.background(.thinMaterial)
}
}