From 73f3fef7388eb7e548e1be368aa0e99b182e6ecb Mon Sep 17 00:00:00 2001 From: Thomas Ricouard Date: Wed, 4 Jan 2023 12:50:57 +0100 Subject: [PATCH] Basic splitView on iPad + Disable macOS for now --- IceCubesApp.xcodeproj/project.pbxproj | 8 +- IceCubesApp/App/IceCubesApp.swift | 79 +++++++++++++------ .../App/Tabs/Settings/SettingsTab.swift | 2 +- IceCubesApp/App/Tabs/Tabs.swift | 2 +- .../Status/Row/StatusMediaPreviewView.swift | 9 ++- 5 files changed, 71 insertions(+), 29 deletions(-) diff --git a/IceCubesApp.xcodeproj/project.pbxproj b/IceCubesApp.xcodeproj/project.pbxproj index 921bb24f..99e50af2 100644 --- a/IceCubesApp.xcodeproj/project.pbxproj +++ b/IceCubesApp.xcodeproj/project.pbxproj @@ -446,7 +446,9 @@ PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.IceCubesApp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = auto; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -492,7 +494,9 @@ PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.IceCubesApp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = auto; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/IceCubesApp/App/IceCubesApp.swift b/IceCubesApp/App/IceCubesApp.swift index e22d55e2..355e6dea 100644 --- a/IceCubesApp/App/IceCubesApp.swift +++ b/IceCubesApp/App/IceCubesApp.swift @@ -17,33 +17,16 @@ struct IceCubesApp: App { @StateObject private var quickLook = QuickLook() @StateObject private var theme = Theme() - @State private var selectedTab: Tab = .timeline + @State private var selectedTab: Tab? = .timeline @State private var popToRootTab: Tab = .other + private var availableTabs: [Tab] { + appAccountsManager.currentClient.isAuth ? Tab.loggedInTabs() : Tab.loggedOutTab() + } + var body: some Scene { WindowGroup { - 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 - } - } - selectedTab = newTab - })) { - ForEach(appAccountsManager.currentClient.isAuth ? Tab.loggedInTabs() : Tab.loggedOutTab()) { tab in - tab.makeContentView(popToRootTab: $popToRootTab) - .tabItem { - tab.label - } - .tag(tab) - .badge(tab == .notifications ? watcher.unreadNotificationsCount : 0) - .toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .tabBar) - } - } + appView .tint(theme.tintColor) .onAppear { setNewClientsInEnv(client: appAccountsManager.currentClient) @@ -73,6 +56,56 @@ struct IceCubesApp: App { } } + @ViewBuilder + private var appView: some View { + if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac { + splitView + } else { + tabBarView + } + } + + private 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) { + if let selectedTab { + popToRootTab = selectedTab + } + } + } + selectedTab = newTab + })) { + ForEach(availableTabs) { tab in + tab.makeContentView(popToRootTab: $popToRootTab) + .tabItem { + tab.label + } + .tag(tab) + .badge(tab == .notifications ? watcher.unreadNotificationsCount : 0) + .toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .tabBar) + } + } + } + + private var splitView: some View { + NavigationSplitView { + List(availableTabs, selection: $selectedTab) { tab in + NavigationLink(value: tab) { + tab.label + } + } + .scrollContentBackground(.hidden) + .background(theme.secondaryBackgroundColor) + } detail: { + selectedTab?.makeContentView(popToRootTab: $popToRootTab) + } + } + private func setNewClientsInEnv(client: Client) { currentAccount.setClient(client: client) currentInstance.setClient(client: client) diff --git a/IceCubesApp/App/Tabs/Settings/SettingsTab.swift b/IceCubesApp/App/Tabs/Settings/SettingsTab.swift index a632a0c1..e8a20261 100644 --- a/IceCubesApp/App/Tabs/Settings/SettingsTab.swift +++ b/IceCubesApp/App/Tabs/Settings/SettingsTab.swift @@ -18,7 +18,7 @@ struct SettingsTabs: View { @State private var isThemeSelectorPresented = false var body: some View { - NavigationStack { + NavigationStack(path: $routeurPath.path) { Form { appSection accountsSection diff --git a/IceCubesApp/App/Tabs/Tabs.swift b/IceCubesApp/App/Tabs/Tabs.swift index f3ffd2e3..37d6bef0 100644 --- a/IceCubesApp/App/Tabs/Tabs.swift +++ b/IceCubesApp/App/Tabs/Tabs.swift @@ -4,7 +4,7 @@ import Account import Explore import SwiftUI -enum Tab: Int, Identifiable { +enum Tab: Int, Identifiable, Hashable { case timeline, notifications, explore, account, settings, other var id: Int { diff --git a/Packages/Status/Sources/Status/Row/StatusMediaPreviewView.swift b/Packages/Status/Sources/Status/Row/StatusMediaPreviewView.swift index 252c16cc..d6163451 100644 --- a/Packages/Status/Sources/Status/Row/StatusMediaPreviewView.swift +++ b/Packages/Status/Sources/Status/Row/StatusMediaPreviewView.swift @@ -104,7 +104,9 @@ public struct StatusMediaPreviewView: View { private func makeFeaturedImagePreview(attachement: MediaAttachement) -> some View { switch attachement.supportedType { case .image: - if let size = size(for: attachement) { + if let size = size(for: attachement), + UIDevice.current.userInterfaceIdiom != .pad, + UIDevice.current.userInterfaceIdiom != .mac { let avatarColumnWidth = theme.avatarPosition == .leading ? AvatarView.Size.status.size.width + .statusColumnsSpacing : 0 let availableWidth = UIScreen.main.bounds.width - (.layoutPadding * 2) - avatarColumnWidth let newSize = imageSize(from: size, @@ -142,12 +144,15 @@ public struct StatusMediaPreviewView: View { image .resizable() .aspectRatio(contentMode: .fill) + .frame(maxHeight: imageMaxHeight) + .frame(maxWidth: imageMaxHeight) .cornerRadius(4) }, placeholder: { RoundedRectangle(cornerRadius: 4) .fill(Color.gray) - .frame(height: imageMaxHeight) + .frame(maxHeight: imageMaxHeight) + .frame(maxWidth: imageMaxHeight) .shimmering() }) }