diff --git a/IceCubesApp/App/IceCubesApp.swift b/IceCubesApp/App/IceCubesApp.swift index a8aec878..c7eb82f0 100644 --- a/IceCubesApp/App/IceCubesApp.swift +++ b/IceCubesApp/App/IceCubesApp.swift @@ -133,8 +133,7 @@ struct IceCubesApp: App { } } } - if proxy.frame(in: .global).width > (.maxColumnWidth + .secondaryColumnWidth), - appAccountsManager.currentClient.isAuth, + if appAccountsManager.currentClient.isAuth, userPreferences.showiPadSecondaryColumn { Divider().edgesIgnoringSafeArea(.all) diff --git a/IceCubesApp/App/Tabs/ExploreTab.swift b/IceCubesApp/App/Tabs/ExploreTab.swift index 8a337e3e..ea0efa45 100644 --- a/IceCubesApp/App/Tabs/ExploreTab.swift +++ b/IceCubesApp/App/Tabs/ExploreTab.swift @@ -29,6 +29,9 @@ struct ExploreTab: View { AppAccountsSelectorView(routerPath: routerPath) } } + if UIDevice.current.userInterfaceIdiom == .pad && !preferences.showiPadSecondaryColumn { + SecondaryColumnToolbarItem() + } } } .withSafariRouter() diff --git a/IceCubesApp/App/Tabs/NotificationTab.swift b/IceCubesApp/App/Tabs/NotificationTab.swift index e232455a..585684e3 100644 --- a/IceCubesApp/App/Tabs/NotificationTab.swift +++ b/IceCubesApp/App/Tabs/NotificationTab.swift @@ -38,6 +38,11 @@ struct NotificationsTab: View { } } } + if UIDevice.current.userInterfaceIdiom == .pad { + if (!isSecondaryColumn && !userPreferences.showiPadSecondaryColumn) || isSecondaryColumn { + SecondaryColumnToolbarItem() + } + } } .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 a372cfeb..cfa071d6 100644 --- a/IceCubesApp/App/Tabs/Settings/SettingsTab.swift +++ b/IceCubesApp/App/Tabs/Settings/SettingsTab.swift @@ -46,6 +46,9 @@ struct SettingsTabs: View { } } } + if UIDevice.current.userInterfaceIdiom == .pad && !preferences.showiPadSecondaryColumn { + SecondaryColumnToolbarItem() + } } .withAppRouter() .withSheetDestinations(sheetDestinations: $routerPath.presentedSheet) diff --git a/IceCubesApp/App/Tabs/Timeline/TimelineTab.swift b/IceCubesApp/App/Tabs/Timeline/TimelineTab.swift index d4309471..6d86e225 100644 --- a/IceCubesApp/App/Tabs/Timeline/TimelineTab.swift +++ b/IceCubesApp/App/Tabs/Timeline/TimelineTab.swift @@ -178,6 +178,9 @@ struct TimelineTab: View { } statusEditorToolbarItem(routerPath: routerPath, visibility: preferences.postVisibility) + if UIDevice.current.userInterfaceIdiom == .pad && !preferences.showiPadSecondaryColumn { + SecondaryColumnToolbarItem() + } } else { ToolbarItem(placement: .navigationBarTrailing) { addAccountButton diff --git a/Packages/Conversations/Sources/Conversations/Detail/ConversationMessageView.swift b/Packages/Conversations/Sources/Conversations/Detail/ConversationMessageView.swift index 42a38851..4bdb858c 100644 --- a/Packages/Conversations/Sources/Conversations/Detail/ConversationMessageView.swift +++ b/Packages/Conversations/Sources/Conversations/Detail/ConversationMessageView.swift @@ -124,22 +124,38 @@ struct ConversationMessageView: View { } } + private func makeImageRequest(for url: URL, size: CGSize) -> ImageRequest { + ImageRequest(url: url, processors: [.resize(size: size)]) + } + + private func mediaWidth(proxy: GeometryProxy) -> CGFloat { + var width = proxy.frame(in: .local).width + if UIDevice.current.userInterfaceIdiom == .pad { + width = width * 0.60 + } + return width + } + private func makeMediaView(_ attachement: MediaAttachment) -> some View { GeometryReader { proxy in - LazyImage(url: attachement.url) { state in - if let image = state.image { - image - .resizable() - .aspectRatio(contentMode: .fill) - .frame(height: 200) - .frame(maxWidth: proxy.frame(in: .local).width) - .clipped() - .cornerRadius(8) - .padding(8) - } else if state.isLoading { - RoundedRectangle(cornerRadius: 8) - .fill(Color.gray) - .frame(height: 200) + let width = mediaWidth(proxy: proxy) + if let url = attachement.url { + LazyImage(request: makeImageRequest(for: url, + size: .init(width: width, height: 200))) { state in + if let image = state.image { + image + .resizable() + .aspectRatio(contentMode: .fill) + .frame(height: 200) + .frame(maxWidth: width) + .clipped() + .cornerRadius(8) + .padding(8) + } else if state.isLoading { + RoundedRectangle(cornerRadius: 8) + .fill(Color.gray) + .frame(height: 200) + } } } } diff --git a/Packages/Conversations/Sources/Conversations/List/ConversationsListView.swift b/Packages/Conversations/Sources/Conversations/List/ConversationsListView.swift index 00aad9e0..2ad41a85 100644 --- a/Packages/Conversations/Sources/Conversations/List/ConversationsListView.swift +++ b/Packages/Conversations/Sources/Conversations/List/ConversationsListView.swift @@ -6,6 +6,7 @@ import Shimmer import SwiftUI public struct ConversationsListView: View { + @EnvironmentObject private var preferences: UserPreferences @EnvironmentObject private var routerPath: RouterPath @EnvironmentObject private var watcher: StreamWatcher @EnvironmentObject private var client: Client @@ -76,6 +77,9 @@ public struct ConversationsListView: View { .navigationBarTitleDisplayMode(.inline) .toolbar { StatusEditorToolbarItem(visibility: .direct) + if UIDevice.current.userInterfaceIdiom == .pad && !preferences.showiPadSecondaryColumn { + SecondaryColumnToolbarItem() + } } .onChange(of: watcher.latestEvent?.id) { _ in if let latestEvent = watcher.latestEvent { diff --git a/Packages/DesignSystem/Sources/DesignSystem/DesignSystem.swift b/Packages/DesignSystem/Sources/DesignSystem/DesignSystem.swift index e05dfefd..29459ace 100644 --- a/Packages/DesignSystem/Sources/DesignSystem/DesignSystem.swift +++ b/Packages/DesignSystem/Sources/DesignSystem/DesignSystem.swift @@ -4,8 +4,7 @@ public extension CGFloat { static var layoutPadding: CGFloat = 20 static let dividerPadding: CGFloat = 2 static let statusColumnsSpacing: CGFloat = 8 - static let maxColumnWidth: CGFloat = 650 - static let secondaryColumnWidth: CGFloat = 360 + static let secondaryColumnWidth: CGFloat = 400 static let sidebarWidth: CGFloat = 80 static let pollBarHeight: CGFloat = 30 } diff --git a/Packages/DesignSystem/Sources/DesignSystem/Views/StatusEditorToolbarItem.swift b/Packages/DesignSystem/Sources/DesignSystem/Views/StatusEditorToolbarItem.swift index 8913e248..1a866aa5 100644 --- a/Packages/DesignSystem/Sources/DesignSystem/Views/StatusEditorToolbarItem.swift +++ b/Packages/DesignSystem/Sources/DesignSystem/Views/StatusEditorToolbarItem.swift @@ -36,3 +36,22 @@ public struct StatusEditorToolbarItem: ToolbarContent { } } } + +public struct SecondaryColumnToolbarItem: ToolbarContent { + @Environment(\.isSecondaryColumn) private var isSecondaryColumn + @EnvironmentObject private var preferences: UserPreferences + + public init() {} + + public var body: some ToolbarContent { + ToolbarItem(placement: isSecondaryColumn ? .navigationBarLeading : .navigationBarTrailing) { + Button { + withAnimation { + preferences.showiPadSecondaryColumn.toggle() + } + } label: { + Image(systemName: "sidebar.right") + } + } + } +} diff --git a/Packages/Status/Sources/Status/Row/Subviews/StatusRowCardView.swift b/Packages/Status/Sources/Status/Row/Subviews/StatusRowCardView.swift index dec04926..c9190db5 100644 --- a/Packages/Status/Sources/Status/Row/Subviews/StatusRowCardView.swift +++ b/Packages/Status/Sources/Status/Row/Subviews/StatusRowCardView.swift @@ -67,7 +67,6 @@ public struct StatusRowCardView: View { RoundedRectangle(cornerRadius: 16) .stroke(.gray.opacity(0.35), lineWidth: 1) ) - .frame(maxWidth: .maxColumnWidth) .onTapGesture { openURL(url) } diff --git a/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift b/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift index 4c9c5740..0683b07c 100644 --- a/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift +++ b/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift @@ -27,8 +27,9 @@ public struct StatusRowMediaPreviewView: View { @State private var isHidingMedia: Bool = false var availableWidth: CGFloat { - if sceneDelegate.windowWidth > .maxColumnWidth { - return .maxColumnWidth + if UIDevice.current.userInterfaceIdiom == .phone && + (UIDevice.current.orientation == .landscapeLeft || UIDevice.current.orientation == .landscapeRight) { + return sceneDelegate.windowWidth * 0.80 } return sceneDelegate.windowWidth } @@ -36,10 +37,16 @@ public struct StatusRowMediaPreviewView: View { var appLayoutWidth: CGFloat { let avatarColumnWidth = theme.avatarPosition == .leading ? AvatarView.Size.status.size.width + .statusColumnsSpacing : 0 var sidebarWidth: CGFloat = 0 - if UIDevice.current.userInterfaceIdiom == .pad && sceneDelegate.windowWidth < (.maxColumnWidth + .sidebarWidth) { + var secondaryColumnWidth: CGFloat = 0 + var layoutPading: CGFloat = .layoutPadding * 2 + if UIDevice.current.userInterfaceIdiom == .pad { sidebarWidth = .sidebarWidth + if preferences.showiPadSecondaryColumn { + secondaryColumnWidth = .secondaryColumnWidth + layoutPading = 0 + } } - return (.layoutPadding * 2) + avatarColumnWidth + sidebarWidth + extraLeadingInset + return layoutPading + avatarColumnWidth + sidebarWidth + extraLeadingInset + secondaryColumnWidth } private var imageMaxHeight: CGFloat {