Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bring back default controls for QuickLook based media viewers #3254

Merged
merged 2 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ 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<MediaPreviewItem?>, shouldHideControls: Bool = false) -> some View {
modifier(InteractiveQuickLookModifier(item: item, shouldHideControls: shouldHideControls))
func interactiveQuickLook(item: Binding<MediaPreviewItem?>, 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<Void, Never>()

func body(content: Content) -> some View {
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.
Expand All @@ -39,13 +39,13 @@ private struct InteractiveQuickLookModifier: ViewModifier {

private struct MediaPreviewViewController: UIViewControllerRepresentable {
let previewItem: MediaPreviewItem
let shouldHideControls: Bool
let allowEditing: Bool
let dismissalPublisher: PassthroughSubject<Void, Never>
let onDismiss: () -> Void

func makeUIViewController(context: Context) -> PreviewHostingController {
PreviewHostingController(previewItem: previewItem,
shouldHideControls: shouldHideControls,
allowEditing: allowEditing,
dismissalPublisher: dismissalPublisher,
onDismiss: onDismiss)
}
Expand All @@ -58,19 +58,19 @@ 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?

var previewController: QLPreviewController?

init(previewItem: MediaPreviewItem,
shouldHideControls: Bool,
allowEditing: Bool,
dismissalPublisher: PassthroughSubject<Void, Never>,
onDismiss: @escaping () -> Void) {
self.previewItem = previewItem
self.shouldHideControls = shouldHideControls
self.allowEditing = allowEditing
self.onDismiss = onDismiss

super.init(nibName: nil, bundle: nil)
Expand Down Expand Up @@ -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)
Expand All @@ -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()
}
Expand All @@ -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 {
Expand All @@ -170,7 +152,7 @@ struct PreviewView_Previews: PreviewProvider {

static var previews: some View {
MediaPreviewViewController(previewItem: previewItem,
shouldHideControls: false,
allowEditing: false,
dismissalPublisher: .init()) { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading