Files
bundesmessenger-ios/Riot/Modules/MediaPickerV2/MediaPickerPresenter.swift
T
Doug 1b74f87b35 Add Email/Terms/ReCaptcha into the Authentication flow
Replace ReCaptcha navigation delegate with a WKUserContentController.
Move callback property closures onto the MainActor.
Show a loading indicator whilst waiting for the authentication service to start.
Move nextUncompletedStage into FlowResult.
Handle text field actions during authentication.
Remove scroll view tweaks in server selection screen following EMS banner removal.
2022-05-19 11:43:38 +01:00

106 lines
3.8 KiB
Swift

//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import UIKit
import PhotosUI
import CommonKit
protocol MediaPickerPresenterDelegate: AnyObject {
func mediaPickerPresenter(_ presenter: MediaPickerPresenter, didPickImage image: UIImage)
func mediaPickerPresenterDidCancel(_ presenter: MediaPickerPresenter)
}
/// A picker for photos and videos from the user's photo library on iOS 14+ using the
/// new `PHPickerViewController` that doesn't require permission to be granted.
final class MediaPickerPresenter: NSObject {
// MARK: - Properties
// MARK: Private
private weak var pickerViewController: UIViewController?
private var indicatorPresenter: UserIndicatorTypePresenterProtocol?
private var loadingIndicator: UserIndicator?
// MARK: Public
weak var delegate: MediaPickerPresenterDelegate?
// MARK: - Public
// TODO: Support videos and multi-selection
func presentPicker(from presentingViewController: UIViewController, with filter: PHPickerFilter?, animated: Bool) {
var configuration = PHPickerConfiguration(photoLibrary: .shared())
configuration.selectionLimit = 1
configuration.filter = filter
let pickerViewController = PHPickerViewController(configuration: configuration)
pickerViewController.delegate = self
self.pickerViewController = pickerViewController
indicatorPresenter = UserIndicatorTypePresenter(presentingViewController: pickerViewController)
presentingViewController.present(pickerViewController, animated: true, completion: nil)
}
func dismiss(animated: Bool, completion: (() -> Void)?) {
guard let pickerViewController = pickerViewController else { return }
pickerViewController.dismiss(animated: animated, completion: completion)
}
// MARK: - Private
private func showLoadingIndicator() {
loadingIndicator = indicatorPresenter?.present(.loading(label: VectorL10n.loading, isInteractionBlocking: true))
}
private func hideLoadingIndicator() {
loadingIndicator = nil
}
}
// MARK: - PHPickerViewControllerDelegate
@available(iOS 14, *)
extension MediaPickerPresenter: PHPickerViewControllerDelegate {
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
// TODO: Handle videos and multi-selection
guard let provider = results.first?.itemProvider, provider.canLoadObject(ofClass: UIImage.self) else {
self.delegate?.mediaPickerPresenterDidCancel(self)
return
}
showLoadingIndicator()
provider.loadObject(ofClass: UIImage.self) { [weak self] image, error in
guard let self = self else { return }
guard let image = image as? UIImage else {
DispatchQueue.main.async {
self.hideLoadingIndicator()
self.delegate?.mediaPickerPresenterDidCancel(self)
}
return
}
DispatchQueue.main.async {
self.hideLoadingIndicator()
self.delegate?.mediaPickerPresenter(self, didPickImage: image)
}
}
}
}