From f451d7cb8c942730db61e9dff21dff84d50b5c1e Mon Sep 17 00:00:00 2001 From: Thomas Ricouard Date: Tue, 14 Nov 2023 19:48:14 +0100 Subject: [PATCH] Bigger media viewer window --- IceCubesApp/App/Main/IceCubesApp+Menu.swift | 2 +- IceCubesApp/App/Main/IceCubesApp+Scene.swift | 23 +++++++++++++-- IceCubesApp/App/SideBarView.swift | 2 +- .../Account/AccountDetailHeaderView.swift | 4 +-- .../Detail/ConversationMessageView.swift | 2 +- .../Views/StatusEditorToolbarItem.swift | 2 +- Packages/Env/Sources/Env/Router.swift | 7 +++-- .../Explore/Sources/Explore/ExploreView.swift | 2 +- .../MediaUI/Sources/MediaUI/MediaUIView.swift | 29 +++++++++++++++++++ .../Sources/Status/Row/StatusRowView.swift | 2 +- .../Row/Subviews/StatusRowActionsView.swift | 2 +- .../Row/Subviews/StatusRowContextMenu.swift | 6 ++-- .../Subviews/StatusRowMediaPreviewView.swift | 2 +- Packages/Timeline/Package.swift | 2 +- 14 files changed, 68 insertions(+), 19 deletions(-) diff --git a/IceCubesApp/App/Main/IceCubesApp+Menu.swift b/IceCubesApp/App/Main/IceCubesApp+Menu.swift index 522bcfee..2ed709bb 100644 --- a/IceCubesApp/App/Main/IceCubesApp+Menu.swift +++ b/IceCubesApp/App/Main/IceCubesApp+Menu.swift @@ -11,7 +11,7 @@ extension IceCubesApp { .keyboardShortcut("n", modifiers: .shift) Button("menu.new-post") { if ProcessInfo.processInfo.isMacCatalystApp { - openWindow(value: WindowDestination.newStatusEditor(visibility: userPreferences.postVisibility)) + openWindow(value: WindowDestinationEditor.newStatusEditor(visibility: userPreferences.postVisibility)) } else { sidebarRouterPath.presentedSheet = .newStatusEditor(visibility: userPreferences.postVisibility) } diff --git a/IceCubesApp/App/Main/IceCubesApp+Scene.swift b/IceCubesApp/App/Main/IceCubesApp+Scene.swift index 2f065257..f11fcf3e 100644 --- a/IceCubesApp/App/Main/IceCubesApp+Scene.swift +++ b/IceCubesApp/App/Main/IceCubesApp+Scene.swift @@ -72,8 +72,9 @@ extension IceCubesApp { } } + @SceneBuilder var otherScenes: some Scene { - WindowGroup(for: WindowDestination.self) { destination in + WindowGroup(for: WindowDestinationEditor.self) { destination in Group { switch destination.wrappedValue { case let .newStatusEditor(visibility): @@ -84,6 +85,21 @@ extension IceCubesApp { StatusEditorView(mode: .quote(status: status)) case let .replyToStatusEditor(status): StatusEditorView(mode: .replyTo(status: status)) + case .none: + EmptyView() + } + } + .withEnvironments() + .withModelContainer() + .applyTheme(theme) + .frame(minWidth: 300, minHeight: 400) + } + .defaultSize(width: 600, height: 800) + .windowResizability(.contentMinSize) + + WindowGroup(for: WindowDestinationMedia.self) { destination in + Group { + switch destination.wrappedValue { case let .mediaViewer(attachments, selectedAttachment): MediaUIView(selectedAttachment: selectedAttachment, attachments: attachments) @@ -94,8 +110,9 @@ extension IceCubesApp { .withEnvironments() .withModelContainer() .applyTheme(theme) + .frame(minWidth: 300, minHeight: 400) } - .defaultSize(width: 600, height: 800) - .windowResizability(.automatic) + .defaultSize(width: 1200, height: 1000) + .windowResizability(.contentMinSize) } } diff --git a/IceCubesApp/App/SideBarView.swift b/IceCubesApp/App/SideBarView.swift index 1df0e879..1433cbd3 100644 --- a/IceCubesApp/App/SideBarView.swift +++ b/IceCubesApp/App/SideBarView.swift @@ -58,7 +58,7 @@ struct SideBarView: View { private var postButton: some View { Button { if ProcessInfo.processInfo.isMacCatalystApp { - openWindow(value: WindowDestination.newStatusEditor(visibility: userPreferences.postVisibility)) + openWindow(value: WindowDestinationEditor.newStatusEditor(visibility: userPreferences.postVisibility)) } else { routerPath.presentedSheet = .newStatusEditor(visibility: userPreferences.postVisibility) } diff --git a/Packages/Account/Sources/Account/AccountDetailHeaderView.swift b/Packages/Account/Sources/Account/AccountDetailHeaderView.swift index 6c8ea777..77d3c009 100644 --- a/Packages/Account/Sources/Account/AccountDetailHeaderView.swift +++ b/Packages/Account/Sources/Account/AccountDetailHeaderView.swift @@ -83,7 +83,7 @@ struct AccountDetailHeaderView: View { let attachement = MediaAttachment.imageWith(url: account.header) if ProcessInfo.processInfo.isMacCatalystApp { - openWindow(value: WindowDestination.mediaViewer(attachments: [attachement], + openWindow(value: WindowDestinationMedia.mediaViewer(attachments: [attachement], selectedAttachment: attachement)) } else { quickLook.prepareFor(selectedMediaAttachment: attachement, mediaAttachments: [attachement]) @@ -118,7 +118,7 @@ struct AccountDetailHeaderView: View { } let attachement = MediaAttachment.imageWith(url: account.avatar) if ProcessInfo.processInfo.isMacCatalystApp { - openWindow(value: WindowDestination.mediaViewer(attachments: [attachement], + openWindow(value: WindowDestinationMedia.mediaViewer(attachments: [attachement], selectedAttachment: attachement)) } else { quickLook.prepareFor(selectedMediaAttachment: attachement, mediaAttachments: [attachement]) diff --git a/Packages/Conversations/Sources/Conversations/Detail/ConversationMessageView.swift b/Packages/Conversations/Sources/Conversations/Detail/ConversationMessageView.swift index 66cbaedd..6abd0ec7 100644 --- a/Packages/Conversations/Sources/Conversations/Detail/ConversationMessageView.swift +++ b/Packages/Conversations/Sources/Conversations/Detail/ConversationMessageView.swift @@ -202,7 +202,7 @@ struct ConversationMessageView: View { .contentShape(Rectangle()) .onTapGesture { if ProcessInfo.processInfo.isMacCatalystApp { - openWindow(value: WindowDestination.mediaViewer(attachments: [attachement], + openWindow(value: WindowDestinationMedia.mediaViewer(attachments: [attachement], selectedAttachment: attachement)) } else { quickLook.prepareFor(selectedMediaAttachment: attachement, mediaAttachments: [attachement]) diff --git a/Packages/DesignSystem/Sources/DesignSystem/Views/StatusEditorToolbarItem.swift b/Packages/DesignSystem/Sources/DesignSystem/Views/StatusEditorToolbarItem.swift index 591bfdd5..906516aa 100644 --- a/Packages/DesignSystem/Sources/DesignSystem/Views/StatusEditorToolbarItem.swift +++ b/Packages/DesignSystem/Sources/DesignSystem/Views/StatusEditorToolbarItem.swift @@ -27,7 +27,7 @@ public struct StatusEditorToolbarItem: ToolbarContent { Button { Task { @MainActor in if ProcessInfo.processInfo.isMacCatalystApp { - openWindow(value: WindowDestination.newStatusEditor(visibility: visibility)) + openWindow(value: WindowDestinationEditor.newStatusEditor(visibility: visibility)) } else { routerPath.presentedSheet = .newStatusEditor(visibility: visibility) HapticManager.shared.fireHaptic(.buttonPress) diff --git a/Packages/Env/Sources/Env/Router.swift b/Packages/Env/Sources/Env/Router.swift index 23052bb2..28fd3ca8 100644 --- a/Packages/Env/Sources/Env/Router.swift +++ b/Packages/Env/Sources/Env/Router.swift @@ -25,14 +25,17 @@ public enum RouterDestination: Hashable { case tagsList(tags: [Tag]) } -public enum WindowDestination: Hashable, Codable { +public enum WindowDestinationEditor: Hashable, Codable { case newStatusEditor(visibility: Models.Visibility) - case mediaViewer(attachments: [MediaAttachment], selectedAttachment: MediaAttachment) case editStatusEditor(status: Status) case replyToStatusEditor(status: Status) case quoteStatusEditor(status: Status) } +public enum WindowDestinationMedia: Hashable, Codable { + case mediaViewer(attachments: [MediaAttachment], selectedAttachment: MediaAttachment) +} + public enum SheetDestination: Identifiable { case newStatusEditor(visibility: Models.Visibility) case editStatusEditor(status: Status) diff --git a/Packages/Explore/Sources/Explore/ExploreView.swift b/Packages/Explore/Sources/Explore/ExploreView.swift index 1c6af0a7..675bfd2f 100644 --- a/Packages/Explore/Sources/Explore/ExploreView.swift +++ b/Packages/Explore/Sources/Explore/ExploreView.swift @@ -89,7 +89,7 @@ public struct ExploreView: View { SoundEffectManager.shared.playSound(.refresh) } } - .listStyle(.grouped) + .listStyle(.plain) .scrollContentBackground(.hidden) .background(theme.secondaryBackgroundColor) .navigationTitle("explore.navigation-title") diff --git a/Packages/MediaUI/Sources/MediaUI/MediaUIView.swift b/Packages/MediaUI/Sources/MediaUI/MediaUIView.swift index 23647bc5..77fa3931 100644 --- a/Packages/MediaUI/Sources/MediaUI/MediaUIView.swift +++ b/Packages/MediaUI/Sources/MediaUI/MediaUIView.swift @@ -7,6 +7,7 @@ public struct MediaUIView: View, @unchecked Sendable { private let data: [DisplayData] private let initialItem: DisplayData? @State private var scrolledItem: DisplayData? + @FocusState private var isFocused: Bool public var body: some View { NavigationStack { @@ -20,6 +21,17 @@ public struct MediaUIView: View, @unchecked Sendable { } .scrollTargetLayout() } + .focusable() + .focused($isFocused) + .focusEffectDisabled() + .onKeyPress(.leftArrow, action: { + scrollToPrevious() + return .handled + }) + .onKeyPress(.rightArrow, action: { + scrollToNext() + return .handled + }) .scrollTargetBehavior(.viewAligned) .scrollPosition(id: $scrolledItem) .toolbar { @@ -30,6 +42,7 @@ public struct MediaUIView: View, @unchecked Sendable { .onAppear { DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) { scrolledItem = initialItem + isFocused = true } } } @@ -39,6 +52,22 @@ public struct MediaUIView: View, @unchecked Sendable { data = attachments.compactMap { DisplayData(from: $0) } initialItem = DisplayData(from: selectedAttachment) } + + private func scrollToPrevious() { + if let scrolledItem, let index = data.firstIndex(of: scrolledItem), index > 0 { + withAnimation { + self.scrolledItem = data[index - 1] + } + } + } + + private func scrollToNext() { + if let scrolledItem, let index = data.firstIndex(of: scrolledItem), index < data.count - 1{ + withAnimation { + self.scrolledItem = data[index + 1] + } + } + } } private struct MediaToolBar: ToolbarContent { diff --git a/Packages/Status/Sources/Status/Row/StatusRowView.swift b/Packages/Status/Sources/Status/Row/StatusRowView.swift index a3e7bcf4..86303cf1 100644 --- a/Packages/Status/Sources/Status/Row/StatusRowView.swift +++ b/Packages/Status/Sources/Status/Row/StatusRowView.swift @@ -210,7 +210,7 @@ public struct StatusRowView: View { HapticManager.shared.fireHaptic(.notification(.success)) let attachments = viewModel.finalStatus.mediaAttachments if ProcessInfo.processInfo.isMacCatalystApp { - openWindow(value: WindowDestination.mediaViewer(attachments: attachments, + openWindow(value: WindowDestinationMedia.mediaViewer(attachments: attachments, selectedAttachment: attachments[0])) } else { quickLook.prepareFor(selectedMediaAttachment: attachments[0], mediaAttachments: attachments) diff --git a/Packages/Status/Sources/Status/Row/Subviews/StatusRowActionsView.swift b/Packages/Status/Sources/Status/Row/Subviews/StatusRowActionsView.swift index 3b758ecc..295fb6d2 100644 --- a/Packages/Status/Sources/Status/Row/Subviews/StatusRowActionsView.swift +++ b/Packages/Status/Sources/Status/Row/Subviews/StatusRowActionsView.swift @@ -206,7 +206,7 @@ struct StatusRowActionsView: View { case .respond: SoundEffectManager.shared.playSound(.share) if ProcessInfo.processInfo.isMacCatalystApp { - openWindow(value: WindowDestination.replyToStatusEditor(status: viewModel.localStatus ?? viewModel.status)) + openWindow(value: WindowDestinationEditor.replyToStatusEditor(status: viewModel.localStatus ?? viewModel.status)) } else { viewModel.routerPath.presentedSheet = .replyToStatusEditor(status: viewModel.localStatus ?? viewModel.status) } diff --git a/Packages/Status/Sources/Status/Row/Subviews/StatusRowContextMenu.swift b/Packages/Status/Sources/Status/Row/Subviews/StatusRowContextMenu.swift index 4a26c51d..0196e1ed 100644 --- a/Packages/Status/Sources/Status/Row/Subviews/StatusRowContextMenu.swift +++ b/Packages/Status/Sources/Status/Row/Subviews/StatusRowContextMenu.swift @@ -54,7 +54,7 @@ struct StatusRowContextMenu: View { } Button { if ProcessInfo.processInfo.isMacCatalystApp { - openWindow(value: WindowDestination.replyToStatusEditor(status: viewModel.status)) + openWindow(value: WindowDestinationEditor.replyToStatusEditor(status: viewModel.status)) } else { viewModel.routerPath.presentedSheet = .replyToStatusEditor(status: viewModel.status) } @@ -63,7 +63,7 @@ struct StatusRowContextMenu: View { } Button { if ProcessInfo.processInfo.isMacCatalystApp { - openWindow(value: WindowDestination.quoteStatusEditor(status: viewModel.status)) + openWindow(value: WindowDestinationEditor.quoteStatusEditor(status: viewModel.status)) } else { viewModel.routerPath.presentedSheet = .quoteStatusEditor(status: viewModel.status) } @@ -164,7 +164,7 @@ struct StatusRowContextMenu: View { if currentInstance.isEditSupported { Button { if ProcessInfo.processInfo.isMacCatalystApp { - openWindow(value: WindowDestination.editStatusEditor(status: viewModel.status.reblogAsAsStatus ?? viewModel.status)) + openWindow(value: WindowDestinationEditor.editStatusEditor(status: viewModel.status.reblogAsAsStatus ?? viewModel.status)) } else { viewModel.routerPath.presentedSheet = .editStatusEditor(status: viewModel.status.reblogAsAsStatus ?? viewModel.status) } diff --git a/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift b/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift index d4a04b50..6131a164 100644 --- a/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift +++ b/Packages/Status/Sources/Status/Row/Subviews/StatusRowMediaPreviewView.swift @@ -116,7 +116,7 @@ public struct StatusRowMediaPreviewView: View { private func tabAction(for index: Int) { if ProcessInfo.processInfo.isMacCatalystApp { openWindow( - value: WindowDestination.mediaViewer( + value: WindowDestinationMedia.mediaViewer( attachments: attachments, selectedAttachment: attachments[index] ) diff --git a/Packages/Timeline/Package.swift b/Packages/Timeline/Package.swift index 68898599..5b6c904f 100644 --- a/Packages/Timeline/Package.swift +++ b/Packages/Timeline/Package.swift @@ -22,7 +22,7 @@ let package = Package( .package(name: "Status", path: "../Status"), .package(name: "DesignSystem", path: "../DesignSystem"), .package(url: "https://github.com/siteline/SwiftUI-Introspect.git", from: "1.0.0"), - .package(url: "https://github.com/mergesort/Bodega", from: "2.0.2"), + .package(url: "https://github.com/mergesort/Bodega", exact: "2.1.0"), ], targets: [ .target(