Files
element-x-ios/ElementX/Sources/Screens/MediaPicker/MediaPickerCoordinator.swift
T
Stefan Ceriu 5f6edacc1a Implements #745, #746, #747 - Initial media uploading flows
- room composer contextual menu for selecting source
- coordinator for presenting the different sources
- system picker handling and URL passback
- file preview after selection
- feature flag
2023-03-31 17:00:36 +03:00

90 lines
2.7 KiB
Swift

//
// Copyright 2023 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 SwiftUI
enum MediaPickerSource {
case camera
case photoLibrary
case documents
}
enum MediaPickerCoordinatorAction {
case selectMediaAtURL(URL)
case cancel
case error(Error?)
}
class MediaPickerCoordinator: CoordinatorProtocol {
private let source: MediaPickerSource
private let callback: ((MediaPickerCoordinatorAction) -> Void)?
init(source: MediaPickerSource, callback: @escaping (MediaPickerCoordinatorAction) -> Void) {
self.source = source
self.callback = callback
}
func toPresentable() -> AnyView {
AnyView(mediaPicker)
}
@ViewBuilder
private var mediaPicker: some View {
switch source {
case .camera:
cameraPicker
case .photoLibrary:
PhotoLibraryPicker { [weak self] action in
switch action {
case .cancel:
self?.callback?(.cancel)
case .error(let error):
self?.callback?(.error(error))
case .selectFile(let url):
self?.callback?(.selectMediaAtURL(url))
}
}
case .documents:
// The document picker automatically dismisses everything on selection
// Strongly retain self in the callback to forward actions correctly
DocumentPicker { action in
switch action {
case .cancel:
self.callback?(.cancel)
case .error(let error):
self.callback?(.error(error))
case .selectFile(let url):
self.callback?(.selectMediaAtURL(url))
}
}
}
}
private var cameraPicker: some View {
CameraPicker { [weak self] action in
switch action {
case .cancel:
self?.callback?(.cancel)
case .error(let error):
self?.callback?(.error(error))
case .selectFile(let url):
self?.callback?(.selectMediaAtURL(url))
}
}
.background(.black, ignoresSafeAreaEdges: .bottom)
}
}