Skip to content
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
144 changes: 134 additions & 10 deletions ownCloud/Client/Actions/Actions+Extensions/UploadMediaAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,126 @@ import UIKit
import ownCloudSDK
import ownCloudAppShared
import Photos
import PhotosUI

@available(iOS 14, *)
class PhotoPickerPresenter: NSObject, PHPickerViewControllerDelegate, PHPhotoLibraryChangeObserver {

typealias AssetSelectionHandler = ([PHAsset]) -> Void

var completionHandler: AssetSelectionHandler?
var parentViewController: UIViewController?

private var assetIdentifiers = [String]()

override init() {
super.init()
PHPhotoLibrary.shared().register(self)
}

var pickerViewController: UIViewController {
var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
configuration.preferredAssetRepresentationMode = .automatic
configuration.selectionLimit = 0
let pickerViewController = PHPickerViewController(configuration: configuration)
pickerViewController.delegate = self

return pickerViewController
}

// MARK: - PHPickerViewControllerDelegate

func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {

picker.dismiss(animated: true)

OnBackgroundQueue {

// Get asset identifiers
for result in results {
if let identifier = result.assetIdentifier {
self.assetIdentifiers.append(identifier)
}
}

// Fetch corresponding assets
let assets = self.attemptAssetsFetch()

OnMainThread {
if results.count == assets.count{
self.completionHandler?(assets)
} else {
self.presentLimitedLibraryPicker()
}
}
}
}

private func presentLimitedLibraryPicker() {
guard let viewController = self.parentViewController else { return }
let library = PHPhotoLibrary.shared()

let alert = ThemedAlertController(title: "Limited Photo Access".localized, message: "Access for the media selected for upload is limited".localized, preferredStyle: .alert)

alert.addAction(UIAlertAction(title: "Change".localized, style: .default, handler: {_ in
library.presentLimitedLibraryPicker(from: viewController)
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (_) in
self.assetIdentifiers.removeAll()
}))

self.parentViewController?.present(alert, animated: true)

}

private func attemptAssetsFetch() -> [PHAsset] {
// Fetch corresponding assets
var assets = [PHAsset]()

let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: assetIdentifiers, options: nil)
fetchResult.enumerateObjects({ (asset, _, _) in
assets.append(asset)
})

return assets
}

func present(in viewController:UIViewController, with completion:@escaping AssetSelectionHandler) {
self.parentViewController = viewController
self.completionHandler = completion
viewController.present(self.pickerViewController, animated: true)
}

// MARK: - PHPhotoLibraryChangeObserver

func photoLibraryDidChange(_ changeInstance: PHChange) {
OnMainThread {
let assets = self.attemptAssetsFetch()
if assets.count > 0 {
self.completionHandler?(assets)
} else {
let alert = ThemedAlertController(title: "Limited Photo Access".localized, message: "No Access to the media selected for upload".localized, preferredStyle: .alert)

alert.addAction(UIAlertAction(title: "OK".localized, style: .default, handler: nil))

self.parentViewController?.present(alert, animated: true)
}
}
}
}

class UploadMediaAction: UploadBaseAction {

override class var identifier : OCExtensionIdentifier? { return OCExtensionIdentifier("com.owncloud.action.uploadphotos") }
override class var category : ActionCategory? { return .normal }
override class var name : String { return "Upload from your photo library".localized }
override class var locations : [OCExtensionLocationIdentifier]? { return [.folderAction, .keyboardShortcut] }
override class var keyCommand : String? { return "M" }
override class var keyModifierFlags: UIKeyModifierFlags? { return [.command] }

// We need this to keep PhotoPickerPresenter alive in iOS14. Type is 'Any' since it is iOS14 only and you can't add @available() to stored properties
private var picker: Any?

private struct AssociatedKeys {
static var actionKey = "action"
}
Expand All @@ -52,20 +163,33 @@ class UploadMediaAction: UploadBaseAction {
}

private func presentImageGalleryPicker() {
if let viewController = self.context.viewController {
let photoAlbumViewController = PhotoAlbumTableViewController()
photoAlbumViewController.selectionCallback = {(assets) in
self.completed()

guard let path = self.context.items.first?.path else { return }
func addAssetsToQueue(assets:[PHAsset]) {
guard let path = self.context.items.first?.path else { return }
guard let bookmark = self.core?.bookmark else { return }

guard let bookmark = self.core?.bookmark else { return }
MediaUploadQueue.shared.addUploads(assets, for: bookmark, at: path)
}

MediaUploadQueue.shared.addUploads(assets, for: bookmark, at: path)
}
let navigationController = ThemeNavigationController(rootViewController: photoAlbumViewController)
if let viewController = self.context.viewController {

viewController.present(navigationController, animated: true)
if #available(iOS 14, *) {
picker = PhotoPickerPresenter()
(picker as? PhotoPickerPresenter)?.present(in: viewController, with: { [weak self] (assets) in
self?.completed()
addAssetsToQueue(assets: assets)
self?.picker = nil
})
} else {
let photoAlbumViewController = PhotoAlbumTableViewController()
photoAlbumViewController.selectionCallback = {(assets) in
self.completed()
addAssetsToQueue(assets: assets)
}
let navigationController = ThemeNavigationController(rootViewController: photoAlbumViewController)

viewController.present(navigationController, animated: true)
}
} else {
self.completed(with: NSError(ocError: .internal))
}
Expand Down
2 changes: 2 additions & 0 deletions ownCloud/Resources/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -153,5 +153,7 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>PHPhotoLibraryPreventAutomaticLimitedAccessAlert</key>
<true/>
</dict>
</plist>
5 changes: 5 additions & 0 deletions ownCloud/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -836,3 +836,8 @@
"Prefer unedited photos" = "Prefer unedited photos";
"Prefer RAW photos" = "Prefer RAW photos";
"Prefer original videos" = "Prefer original videos";

/* Limited photo library access */
"Limited Photo Access" = "Limited Photo Access";
"Access for the media selected for upload is limited" = "Access for the media selected for upload is limited";
"No Access to the media selected for upload" = "No Access to the media selected for upload";
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ - (instancetype)initWithItems:(NSArray<OCLicenseAppStoreItem *> *)items
__weak OCLicenseAppStoreProvider *weakSelf = self;

[OCIPNotificationCenter.sharedNotificationCenter addObserver:self forName:OCIPCNotificationNameLicenseAppStoreProviderDataChanged withHandler:^(OCIPNotificationCenter * _Nonnull notificationCenter, id _Nonnull observer, OCIPCNotificationName _Nonnull notificationName) {
OCWLogDebug(@"Received AppStoreProviderDataChanged notification");
OCLogDebug(@"Received AppStoreProviderDataChanged notification");
[weakSelf loadReceipt];
}];
}
Expand Down