Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/nextcloud/ios into 2399-…
Browse files Browse the repository at this point in the history
…aspect-ratio-in-media-view
  • Loading branch information
mpivchev committed Oct 19, 2023
2 parents 9747ad8 + 1023a19 commit 4ca1fbe
Show file tree
Hide file tree
Showing 11 changed files with 211 additions and 163 deletions.
8 changes: 4 additions & 4 deletions Nextcloud.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@
F769CA1A2966EA3C00039397 /* ComponentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F769CA182966EA3C00039397 /* ComponentView.swift */; };
F76B3CCE1EAE01BD00921AC9 /* NCBrand.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76B3CCD1EAE01BD00921AC9 /* NCBrand.swift */; };
F76B3CCF1EAE01BD00921AC9 /* NCBrand.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76B3CCD1EAE01BD00921AC9 /* NCBrand.swift */; };
F76B649C2ADFFAED00014640 /* NCMediaManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76B649B2ADFFAED00014640 /* NCMediaManager.swift */; };
F76B649C2ADFFAED00014640 /* NCMediaCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76B649B2ADFFAED00014640 /* NCMediaCache.swift */; };
F76B649E2ADFFDEC00014640 /* LRUCache in Frameworks */ = {isa = PBXBuildFile; productRef = F76B649D2ADFFDEC00014640 /* LRUCache */; };
F76C26A62850D3A500E42BDF /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F7F67BB81A24D27800EE80DA /* Images.xcassets */; };
F76D364628A4F8BF00214537 /* NCActivityIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76D364528A4F8BF00214537 /* NCActivityIndicator.swift */; };
Expand Down Expand Up @@ -1108,7 +1108,7 @@
F769CA162965AB7C00039397 /* NCUploadAssets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCUploadAssets.swift; sourceTree = "<group>"; };
F769CA182966EA3C00039397 /* ComponentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComponentView.swift; sourceTree = "<group>"; };
F76B3CCD1EAE01BD00921AC9 /* NCBrand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCBrand.swift; sourceTree = "<group>"; };
F76B649B2ADFFAED00014640 /* NCMediaManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCMediaManager.swift; sourceTree = "<group>"; };
F76B649B2ADFFAED00014640 /* NCMediaCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCMediaCache.swift; sourceTree = "<group>"; };
F76D364528A4F8BF00214537 /* NCActivityIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCActivityIndicator.swift; sourceTree = "<group>"; };
F76D3CF02428B40E005DFA87 /* NCViewerPDFSearch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCViewerPDFSearch.swift; sourceTree = "<group>"; };
F76D3CF22428B94E005DFA87 /* NCViewerPDFSearchCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCViewerPDFSearchCell.xib; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2440,7 +2440,7 @@
F720B5B72507B9A5008C94E5 /* Cell */,
F7501C302212E57400FB1415 /* NCMedia.storyboard */,
F7501C312212E57400FB1415 /* NCMedia.swift */,
F76B649B2ADFFAED00014640 /* NCMediaManager.swift */,
F76B649B2ADFFAED00014640 /* NCMediaCache.swift */,
F7F1E54B2492369A00E42386 /* NCMediaCommandView.xib */,
F7501C312212E57400FB1415 /* NCMedia.swift */,
F3F7ACFD2A98C56C00AE12CF /* NCMediaNew.swift */,
Expand Down Expand Up @@ -3754,7 +3754,7 @@
F72A47EC2487B06B005AD489 /* NCOperationQueue.swift in Sources */,
F769454622E9F1B0000A798A /* NCShareCommon.swift in Sources */,
F70753F12542A9A200972D44 /* NCViewerMedia.swift in Sources */,
F76B649C2ADFFAED00014640 /* NCMediaManager.swift in Sources */,
F76B649C2ADFFAED00014640 /* NCMediaCache.swift in Sources */,
F78A18B823CDE2B300F681F3 /* NCViewerRichWorkspace.swift in Sources */,
F30A6BF22AB4B31200148857 /* PreferenceKeys.swift in Sources */,
F7A60F86292D215000FCE1F2 /* NCShareAccounts.swift in Sources */,
Expand Down
25 changes: 22 additions & 3 deletions iOSClient/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import TOPasscodeViewController
import LocalAuthentication
import Firebase
import WidgetKit
import Queuer

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, TOPasscodeViewControllerDelegate, NCAccountRequestDelegate, NCViewCertificateDetailsDelegate, NCUserBaseUrl {
Expand Down Expand Up @@ -58,9 +59,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD

private var privacyProtectionWindow: UIWindow?

let downloadQueue = Queuer(name: "downloadQueue", maxConcurrentOperationCount: NCGlobal.shared.maxConcurrentOperationCountDownload, qualityOfService: .default)
let downloadThumbnailQueue = Queuer(name: "downloadThumbnailQueue", maxConcurrentOperationCount: 10, qualityOfService: .default)
let downloadThumbnailActivityQueue = Queuer(name: "downloadThumbnailActivityQueue", maxConcurrentOperationCount: 10, qualityOfService: .default)
let downloadAvatarQueue = Queuer(name: "downloadAvatarQueue", maxConcurrentOperationCount: 10, qualityOfService: .default)
let unifiedSearchQueue = Queuer(name: "unifiedSearchQueue", maxConcurrentOperationCount: 1, qualityOfService: .default)
let saveLivePhotoQueue = Queuer(name: "saveLivePhotoQueue", maxConcurrentOperationCount: 1, qualityOfService: .default)

var isUiTestingEnabled: Bool {
return ProcessInfo.processInfo.arguments.contains("UI_TESTING")
}
}

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if isUiTestingEnabled {
Expand Down Expand Up @@ -126,7 +134,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD

NCBrandColor.shared.settingThemingColor(account: activeAccount.account)

DispatchQueue.global().async { NCMediaManager.shared.createCache(account: self.account) }
DispatchQueue.global().async { NCMediaCache.shared.createCache(account: self.account) }

} else {

Expand Down Expand Up @@ -596,7 +604,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
NextcloudKit.shared.nkCommonInstance.writeLog("[INFO] Initialize Auto upload with \(items) uploads")
}

DispatchQueue.global().async { NCMediaManager.shared.createCache(account: account) }
DispatchQueue.global().async { NCMediaCache.shared.createCache(account: account) }

NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterChangeUser)
}
Expand Down Expand Up @@ -803,6 +811,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
}
}

// MARK: - Queue

@objc func cancelAllQueue() {
downloadQueue.cancelAll()
downloadThumbnailQueue.cancelAll()
downloadThumbnailActivityQueue.cancelAll()
downloadAvatarQueue.cancelAll()
unifiedSearchQueue.cancelAll()
saveLivePhotoQueue.cancelAll()
}

// MARK: - Universal Links

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
Expand Down
70 changes: 67 additions & 3 deletions iOSClient/Main/Collection Common/NCCollectionViewCommon.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import Realm
import NextcloudKit
import EasyTipView
import JGProgressHUD
import Queuer

class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UISearchResultsUpdating, UISearchControllerDelegate, UISearchBarDelegate, NCListCellDelegate, NCGridCellDelegate, NCSectionHeaderMenuDelegate, NCSectionFooterDelegate, UIAdaptivePresentationControllerDelegate, NCEmptyDataSetDelegate, UIContextMenuInteractionDelegate, NCAccountRequestDelegate, NCSelectableNavigationView {

Expand Down Expand Up @@ -1201,7 +1202,15 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
if let image = NCUtility.shared.createFilePreviewImage(ocId: metadata.ocId, etag: metadata.etag, fileNameView: metadata.fileNameView, classFile: metadata.classFile, status: metadata.status, createPreviewMedia: !metadata.hasPreview) {
(cell as? NCCellProtocol)?.filePreviewImageView?.image = image
} else {
NCOperationQueue.shared.downloadThumbnail(metadata: metadata, placeholder: true, cell: cell, view: collectionView)
if metadata.iconName.isEmpty {
(cell as? NCCellProtocol)?.filePreviewImageView?.image = NCBrandColor.cacheImages.file
} else {
(cell as? NCCellProtocol)?.filePreviewImageView?.image = UIImage(named: metadata.iconName)
}
if metadata.hasPreview && metadata.status == NCGlobal.shared.metadataStatusNormal && (!CCUtility.fileProviderStoragePreviewIconExists(metadata.ocId, etag: metadata.etag)) {
for case let operation as NCCollectionViewDownloadThumbnail in appDelegate.downloadThumbnailQueue.operations where operation.metadata.ocId == metadata.ocId { return }
appDelegate.downloadThumbnailQueue.addOperation(NCCollectionViewDownloadThumbnail(metadata: metadata, cell: (cell as? NCCellProtocol), view: view))
}
}
} else {
// Unified search
Expand Down Expand Up @@ -1245,10 +1254,12 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
}
}

func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if !collectionView.indexPathsForVisibleItems.contains(indexPath) {
guard let metadata = dataSource.cellForItemAt(indexPath: indexPath) else { return }
NCOperationQueue.shared.cancelDownloadThumbnail(metadata: metadata)
for case let operation as NCCollectionViewDownloadThumbnail in appDelegate.downloadThumbnailQueue.operations where operation.metadata.ocId == metadata.ocId {
operation.cancel()
}
}
}

Expand Down Expand Up @@ -1694,3 +1705,56 @@ extension NCCollectionViewCommon: EasyTipViewDelegate {
self.tipView?.dismiss()
}
}

class NCCollectionViewDownloadThumbnail: ConcurrentOperation {

var metadata: tableMetadata
var cell: NCCellProtocol?
var view: UIView?
var fileNamePath: String
var fileNamePreviewLocalPath: String
var fileNameIconLocalPath: String

init(metadata: tableMetadata, cell: NCCellProtocol?, view: UIView?) {
self.metadata = tableMetadata.init(value: metadata)
self.cell = cell
self.view = view
self.fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, account: metadata.account)!
self.fileNamePreviewLocalPath = CCUtility.getDirectoryProviderStoragePreviewOcId(metadata.ocId, etag: metadata.etag)!
self.fileNameIconLocalPath = CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)!
}

override func start() {

guard !isCancelled else { return self.finish() }

var etagResource: String?
if FileManager.default.fileExists(atPath: fileNameIconLocalPath) && FileManager.default.fileExists(atPath: fileNamePreviewLocalPath) {
etagResource = metadata.etagResource
}

NextcloudKit.shared.downloadPreview(fileNamePathOrFileId: fileNamePath,
fileNamePreviewLocalPath: fileNamePreviewLocalPath,
widthPreview: NCGlobal.shared.sizePreview,
heightPreview: NCGlobal.shared.sizePreview,
fileNameIconLocalPath: fileNameIconLocalPath,
sizeIcon: NCGlobal.shared.sizeIcon,
etag: etagResource,
options: NKRequestOptions(queue: NextcloudKit.shared.nkCommonInstance.backgroundQueue)) { _, _, imageIcon, _, etag, error in

if error == .success, let image = imageIcon {
NCManageDatabase.shared.setMetadataEtagResource(ocId: self.metadata.ocId, etagResource: etag)
DispatchQueue.main.async {
if self.metadata.ocId == self.cell?.fileObjectId, let filePreviewImageView = self.cell?.filePreviewImageView {
UIView.transition(with: filePreviewImageView,
duration: 0.75,
options: .transitionCrossDissolve,
animations: { filePreviewImageView.image = image },
completion: nil)
}
}
}
self.finish()
}
}
}
70 changes: 66 additions & 4 deletions iOSClient/Media/NCMedia.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import UIKit
import NextcloudKit
import JGProgressHUD
import Queuer

class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {

Expand Down Expand Up @@ -370,24 +371,29 @@ extension NCMedia: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
guard let cell = (cell as? NCGridMediaCell), indexPath.row < self.metadatas.count else { return }
let metadata = self.metadatas[indexPath.row]
if let image = NCMediaManager.shared.getImage(ocId: metadata.ocId) {
if let image = NCMediaCache.shared.getImage(ocId: metadata.ocId) {
cell.imageItem.backgroundColor = nil
cell.imageItem.image = image
} else if FileManager().fileExists(atPath: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)) {
if let image = UIImage(contentsOfFile: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)) {
cell.imageItem.backgroundColor = nil
cell.imageItem.image = image
NCMediaManager.shared.setImage(ocId: metadata.ocId, image: image)
NCMediaCache.shared.setImage(ocId: metadata.ocId, image: image)
}
} else {
NCOperationQueue.shared.downloadThumbnail(metadata: metadata, placeholder: false, cell: cell, view: collectionView)
if metadata.hasPreview && metadata.status == NCGlobal.shared.metadataStatusNormal && (!CCUtility.fileProviderStoragePreviewIconExists(metadata.ocId, etag: metadata.etag)) {
for case let operation as NCMediaDownloadThumbnaill in appDelegate.downloadThumbnailQueue.operations where operation.metadata.ocId == metadata.ocId { return }
appDelegate.downloadThumbnailQueue.addOperation(NCMediaDownloadThumbnaill(metadata: metadata, cell: cell, view: view))
}
}
}

func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if !collectionView.indexPathsForVisibleItems.contains(indexPath) && indexPath.row < metadatas.count {
let metadata = metadatas[indexPath.row]
NCOperationQueue.shared.cancelDownloadThumbnail(metadata: metadata)
for case let operation as NCMediaDownloadThumbnaill in appDelegate.downloadThumbnailQueue.operations where operation.metadata.ocId == metadata.ocId {
operation.cancel()
}
}
}

Expand Down Expand Up @@ -848,3 +854,59 @@ class NCGridMediaLayout: UICollectionViewFlowLayout {
return proposedContentOffset
}
}

// MARK: -

class NCMediaDownloadThumbnaill: ConcurrentOperation {

var metadata: tableMetadata
var cell: NCCellProtocol?
var view: UIView?
var fileNamePath: String
var fileNamePreviewLocalPath: String
var fileNameIconLocalPath: String

init(metadata: tableMetadata, cell: NCCellProtocol?, view: UIView?) {
self.metadata = tableMetadata.init(value: metadata)
self.cell = cell
self.view = view
self.fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, account: metadata.account)!
self.fileNamePreviewLocalPath = CCUtility.getDirectoryProviderStoragePreviewOcId(metadata.ocId, etag: metadata.etag)!
self.fileNameIconLocalPath = CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)!
}

override func start() {

guard !isCancelled else { return self.finish() }

var etagResource: String?
if FileManager.default.fileExists(atPath: fileNameIconLocalPath) && FileManager.default.fileExists(atPath: fileNamePreviewLocalPath) {
etagResource = metadata.etagResource
}

NextcloudKit.shared.downloadPreview(fileNamePathOrFileId: fileNamePath,
fileNamePreviewLocalPath: fileNamePreviewLocalPath,
widthPreview: NCGlobal.shared.sizePreview,
heightPreview: NCGlobal.shared.sizePreview,
fileNameIconLocalPath: fileNameIconLocalPath,
sizeIcon: NCGlobal.shared.sizeIcon,
etag: etagResource,
options: NKRequestOptions(queue: NextcloudKit.shared.nkCommonInstance.backgroundQueue)) { _, imagePreview, _, _, etag, error in

if error == .success, let image = imagePreview {
NCManageDatabase.shared.setMetadataEtagResource(ocId: self.metadata.ocId, etagResource: etag)
DispatchQueue.main.async {
if self.metadata.ocId == self.cell?.fileObjectId, let filePreviewImageView = self.cell?.filePreviewImageView {
UIView.transition(with: filePreviewImageView,
duration: 0.75,
options: .transitionCrossDissolve,
animations: { filePreviewImageView.image = image },
completion: nil)
}
}
NCMediaCache.shared.setImage(ocId: self.metadata.ocId, image: image)
}
self.finish()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// NCMediaManager.swift
// NCMediaCache.swift
// Nextcloud
//
// Created by Milen on 10.10.23.
Expand All @@ -10,10 +10,10 @@ import UIKit
import LRUCache
import NextcloudKit

@objc class NCMediaManager: NSObject {
@objc class NCMediaCache: NSObject {

@objc public static let shared: NCMediaManager = {
let instance = NCMediaManager()
@objc public static let shared: NCMediaCache = {
let instance = NCMediaCache()
return instance
}()

Expand Down
2 changes: 0 additions & 2 deletions iOSClient/NCGlobal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -379,8 +379,6 @@ class NCGlobal: NSObject {
let notificationCenterMenuSearchTextPDF = "menuSearchTextPDF"
let notificationCenterMenuGotToPageInPDF = "menuGotToPageInPDF"

let notificationCenterDownloadedThumbnail = "DownloadedThumbnail" // userInfo: ocId

let notificationCenterOpenMediaDetail = "openMediaDetail" // userInfo: ocId

let notificationCenterDismissScanDocument = "dismissScanDocument"
Expand Down
4 changes: 3 additions & 1 deletion iOSClient/Networking/NCNetworking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,9 @@ class NCNetworking: NSObject, NKCommonDelegate {
func cancel(inBackground: Bool) async {

#if !EXTENSION
NCOperationQueue.shared.cancelAllQueue()
if let appDelegate = await UIApplication.shared.delegate as? AppDelegate {
await appDelegate.cancelAllQueue()
}
#endif

NextcloudKit.shared.sessionManager.cancelAllRequests()
Expand Down
Loading

0 comments on commit 4ca1fbe

Please sign in to comment.