From ff5b22cecf1b13d0be53dcc0b6cf86bcf215877a Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 11 Sep 2024 12:11:30 +0300 Subject: [PATCH] Bring back default controls for QuickLook based media viewers (#3254) * Fixes #3243 - Bring back default controls for QuickLook based media viewers --- .../InteractiveQuickLook.swift | 48 ++++++------------- .../View/RoomDetailsScreen.swift | 2 +- .../View/RoomMemberDetailsScreen.swift | 2 +- .../View/UserProfileScreen.swift | 2 +- 4 files changed, 18 insertions(+), 36 deletions(-) diff --git a/ElementX/Sources/Screens/FilePreviewScreen/InteractiveQuickLook.swift b/ElementX/Sources/Screens/FilePreviewScreen/InteractiveQuickLook.swift index 695777e57..422a68419 100644 --- a/ElementX/Sources/Screens/FilePreviewScreen/InteractiveQuickLook.swift +++ b/ElementX/Sources/Screens/FilePreviewScreen/InteractiveQuickLook.swift @@ -12,14 +12,14 @@ import SwiftUI extension View { /// Preview a media file using a QuickLook Preview Controller. The preview is interactive with /// the dismiss gesture working as expected if it was presented from UIKit. - func interactiveQuickLook(item: Binding, shouldHideControls: Bool = false) -> some View { - modifier(InteractiveQuickLookModifier(item: item, shouldHideControls: shouldHideControls)) + func interactiveQuickLook(item: Binding, allowEditing: Bool = true) -> some View { + modifier(InteractiveQuickLookModifier(item: item, allowEditing: allowEditing)) } } private struct InteractiveQuickLookModifier: ViewModifier { @Binding var item: MediaPreviewItem? - let shouldHideControls: Bool + let allowEditing: Bool @State private var dismissalPublisher = PassthroughSubject() @@ -27,7 +27,7 @@ private struct InteractiveQuickLookModifier: ViewModifier { content.background { if let item { MediaPreviewViewController(previewItem: item, - shouldHideControls: shouldHideControls, + allowEditing: allowEditing, dismissalPublisher: dismissalPublisher) { self.item = nil } } else { // Work around QLPreviewController dismissal issues, see below. @@ -39,13 +39,13 @@ private struct InteractiveQuickLookModifier: ViewModifier { private struct MediaPreviewViewController: UIViewControllerRepresentable { let previewItem: MediaPreviewItem - let shouldHideControls: Bool + let allowEditing: Bool let dismissalPublisher: PassthroughSubject let onDismiss: () -> Void func makeUIViewController(context: Context) -> PreviewHostingController { PreviewHostingController(previewItem: previewItem, - shouldHideControls: shouldHideControls, + allowEditing: allowEditing, dismissalPublisher: dismissalPublisher, onDismiss: onDismiss) } @@ -58,7 +58,7 @@ private struct MediaPreviewViewController: UIViewControllerRepresentable { /// animations and interactions which don't work if you represent it directly to SwiftUI 🤷‍♂️ class PreviewHostingController: UIViewController, QLPreviewControllerDataSource, QLPreviewControllerDelegate { let previewItem: MediaPreviewItem - let shouldHideControls: Bool + let allowEditing: Bool let onDismiss: () -> Void private var dismissalObserver: AnyCancellable? @@ -66,11 +66,11 @@ private struct MediaPreviewViewController: UIViewControllerRepresentable { var previewController: QLPreviewController? init(previewItem: MediaPreviewItem, - shouldHideControls: Bool, + allowEditing: Bool, dismissalPublisher: PassthroughSubject, onDismiss: @escaping () -> Void) { self.previewItem = previewItem - self.shouldHideControls = shouldHideControls + self.allowEditing = allowEditing self.onDismiss = onDismiss super.init(nibName: nil, bundle: nil) @@ -100,7 +100,7 @@ private struct MediaPreviewViewController: UIViewControllerRepresentable { guard self.previewController == nil else { return } - let previewController = (shouldHideControls ? NoControlsPreviewController() : QLPreviewController()) + let previewController = QLPreviewController() previewController.dataSource = self previewController.delegate = self present(previewController, animated: true) @@ -120,6 +120,10 @@ private struct MediaPreviewViewController: UIViewControllerRepresentable { // MARK: QLPreviewControllerDelegate + func previewController(_ controller: QLPreviewController, editingModeFor previewItem: QLPreviewItem) -> QLPreviewItemEditingMode { + allowEditing ? .createCopy : .disabled + } + func previewControllerDidDismiss(_ controller: QLPreviewController) { onDismiss() } @@ -139,28 +143,6 @@ class MediaPreviewItem: NSObject, QLPreviewItem { } } -private class NoControlsPreviewController: QLPreviewController { - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - - guard let navigationController = children.first as? UINavigationController else { - return - } - - // Remove top file details bar - navigationController.navigationBar.isHidden = true - - // Remove the toolbars and their buttons - navigationController.view.subviews.compactMap { $0 as? UIToolbar }.forEach { toolbar in - toolbar.subviews.forEach { item in - item.isHidden = true - } - - toolbar.isHidden = true - } - } -} - // MARK: - Previews struct PreviewView_Previews: PreviewProvider { @@ -170,7 +152,7 @@ struct PreviewView_Previews: PreviewProvider { static var previews: some View { MediaPreviewViewController(previewItem: previewItem, - shouldHideControls: false, + allowEditing: false, dismissalPublisher: .init()) { } } } diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift b/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift index ff6c5d59e..73a8446f9 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift @@ -57,7 +57,7 @@ struct RoomDetailsScreen: View { .navigationTitle(L10n.screenRoomDetailsTitle) .navigationBarTitleDisplayMode(.inline) .track(screen: .RoomDetails) - .interactiveQuickLook(item: $context.mediaPreviewItem, shouldHideControls: true) + .interactiveQuickLook(item: $context.mediaPreviewItem, allowEditing: false) } // MARK: - Private diff --git a/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift b/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift index 39c2cda68..1861cd1de 100644 --- a/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift +++ b/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift @@ -24,7 +24,7 @@ struct RoomMemberDetailsScreen: View { .alert(item: $context.ignoreUserAlert, actions: blockUserAlertActions, message: blockUserAlertMessage) .alert(item: $context.alertInfo) .track(screen: .User) - .interactiveQuickLook(item: $context.mediaPreviewItem, shouldHideControls: true) + .interactiveQuickLook(item: $context.mediaPreviewItem, allowEditing: false) } // MARK: - Private diff --git a/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift b/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift index 5d76819a6..43201a3bb 100644 --- a/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift +++ b/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift @@ -21,7 +21,7 @@ struct UserProfileScreen: View { .toolbar { toolbar } .alert(item: $context.alertInfo) .track(screen: .User) - .interactiveQuickLook(item: $context.mediaPreviewItem, shouldHideControls: true) + .interactiveQuickLook(item: $context.mediaPreviewItem, allowEditing: false) } // MARK: - Private