123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- import UIKit
- import NextcloudKit
- import RealmSwift
- extension NCMedia {
- func loadDataSource() {
- let session = self.session
- DispatchQueue.global().async {
- if let metadatas = self.database.getResultsMetadatas(predicate: self.imageCache.getMediaPredicate(filterLivePhotoFile: true, session: session, showOnlyImages: self.showOnlyImages, showOnlyVideos: self.showOnlyVideos), sortedByKeyPath: "date") {
- self.dataSource = NCMediaDataSource(metadatas: metadatas)
- }
- self.collectionViewReloadData()
- }
- }
- func collectionViewReloadData() {
- DispatchQueue.main.async {
- self.collectionView.reloadData()
- self.refreshControl.endRefreshing()
- self.setTitleDate()
- }
- }
-
- @objc func searchMediaUI(_ distant: Bool = false) {
- let session = self.session
- self.lockQueue.sync {
- guard self.isViewActived,
- !self.hasRunSearchMedia,
- !self.isPinchGestureActive,
- !self.showOnlyImages,
- !self.showOnlyVideos,
- !isEditMode,
- NCNetworking.shared.downloadThumbnailQueue.operationCount == 0,
- let tableAccount = database.getTableAccount(predicate: NSPredicate(format: "account == %@", session.account))
- else { return }
- self.hasRunSearchMedia = true
- let limit = max(collectionView.visibleCells.count * 3, 300)
- var lessDate = Date.distantFuture
- var greaterDate = Date.distantPast
- let countMetadatas = self.dataSource.metadatas.count
- let options = NKRequestOptions(timeout: 120, taskDescription: global.taskDescriptionRetrievesProperties, queue: NextcloudKit.shared.nkCommonInstance.backgroundQueue)
- var firstCellDate: Date?
- var lastCellDate: Date?
- if countMetadatas == 0 {
- self.collectionViewReloadData()
- }
- if let visibleCells = self.collectionView?.indexPathsForVisibleItems.sorted(by: { $0.row < $1.row }).compactMap({ self.collectionView?.cellForItem(at: $0) }), !distant {
- firstCellDate = (visibleCells.first as? NCMediaCell)?.date
- if firstCellDate == self.dataSource.metadatas.first?.date {
- lessDate = Date.distantFuture
- } else {
- if let date = firstCellDate {
- lessDate = Calendar.current.date(byAdding: .second, value: 1, to: date)!
- } else {
- lessDate = Date.distantFuture
- }
- }
- lastCellDate = (visibleCells.last as? NCMediaCell)?.date
- if lastCellDate == self.dataSource.metadatas.last?.date {
- greaterDate = Date.distantPast
- } else {
- if let date = lastCellDate {
- greaterDate = Calendar.current.date(byAdding: .second, value: -1, to: date)!
- } else {
- greaterDate = Date.distantPast
- }
- }
- }
- NextcloudKit.shared.nkCommonInstance.writeLog("[DEBUG] Start searchMedia with lessDate \(lessDate), greaterDate \(greaterDate), limit \(limit)")
- activityIndicator.startAnimating()
- NextcloudKit.shared.searchMedia(path: tableAccount.mediaPath,
- lessDate: lessDate,
- greaterDate: greaterDate,
- elementDate: "d:getlastmodified/",
- limit: limit,
- showHiddenFiles: NCKeychain().showHiddenFiles,
- account: self.session.account,
- options: options) { account, files, _, error in
- if error == .success, let files, session.account == account, !self.showOnlyImages, !self.showOnlyVideos {
-
- if lessDate == Date.distantFuture, greaterDate == Date.distantPast, files.isEmpty {
- self.dataSource.metadatas.removeAll()
- self.collectionViewReloadData()
- }
- DispatchQueue.global().async {
- self.database.convertFilesToMetadatas(files, useFirstAsMetadataFolder: false) { _, metadatas in
- let metadatas = metadatas.filter { metadata in
- if let tableMetadata = self.database.getMetadataFromOcId(metadata.ocId) {
- return tableMetadata.status == self.global.metadataStatusNormal
- } else {
- return true
- }
- }
- self.database.addMetadatas(metadatas)
- if self.dataSource.addMetadatas(metadatas) {
- self.collectionViewReloadData()
- }
- DispatchQueue.main.async {
- if let firstCellDate, let lastCellDate, self.isViewActived {
- DispatchQueue.global().async {
- let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [ NSPredicate(format: "date >= %@ AND date =< %@", lastCellDate as NSDate, firstCellDate as NSDate), self.imageCache.getMediaPredicate(filterLivePhotoFile: false, session: session, showOnlyImages: self.showOnlyImages, showOnlyVideos: self.showOnlyVideos)])
- if let resultsMetadatas = NCManageDatabase.shared.getResultsMetadatas(predicate: predicate) {
- for metadata in resultsMetadatas where !self.filesExists.contains(metadata.ocId) {
- if NCNetworking.shared.fileExistsQueue.operations.filter({ ($0 as? NCOperationFileExists)?.ocId == metadata.ocId }).isEmpty {
- NCNetworking.shared.fileExistsQueue.addOperation(NCOperationFileExists(metadata: metadata))
- }
- }
- }
- }
- }
- }
- }
- }
- } else {
- NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Media search new media error code \(error.errorCode) " + error.errorDescription)
- self.collectionViewReloadData()
- }
- DispatchQueue.main.async {
- self.activityIndicator.stopAnimating()
- }
- self.hasRunSearchMedia = false
- }
- }
- }
- }
- public class NCMediaDataSource: NSObject {
- public class Metadata: NSObject {
- let date: Date
- let etag: String
- let imageSize: CGSize
- let isImage: Bool
- let isLivePhoto: Bool
- let isVideo: Bool
- let ocId: String
- init(date: Date,
- etag: String,
- imageSize: CGSize,
- isImage: Bool,
- isLivePhoto: Bool,
- isVideo: Bool,
- ocId: String) {
- self.date = date
- self.etag = etag
- self.imageSize = imageSize
- self.isImage = isImage
- self.isLivePhoto = isLivePhoto
- self.isVideo = isVideo
- self.ocId = ocId
- }
- }
- private let utilityFileSystem = NCUtilityFileSystem()
- private let global = NCGlobal.shared
- var metadatas: [Metadata] = []
- override init() { super.init() }
- init(metadatas: Results<tableMetadata>) {
- super.init()
- self.metadatas.removeAll()
- metadatas.forEach { metadata in
- let metadata = getMetadataFromTableMetadata(metadata)
- self.metadatas.append(metadata)
- }
- }
- private func insertInMetadatas(metadata: Metadata) {
- for i in 0..<self.metadatas.count {
- if (metadata.date as Date) > self.metadatas[i].date {
- self.metadatas.insert(metadata, at: i)
- return
- }
- }
- self.metadatas.append(metadata)
- }
- private func getMetadataFromTableMetadata(_ metadata: tableMetadata) -> Metadata {
- return Metadata(date: metadata.date as Date,
- etag: metadata.etag,
- imageSize: CGSize(width: metadata.width, height: metadata.height),
- isImage: metadata.classFile == NKCommon.TypeClassFile.image.rawValue,
- isLivePhoto: !metadata.livePhotoFile.isEmpty,
- isVideo: metadata.classFile == NKCommon.TypeClassFile.video.rawValue,
- ocId: metadata.ocId)
- }
-
- func getMetadata(indexPath: IndexPath) -> Metadata? {
- if indexPath.row < self.metadatas.count {
- return self.metadatas[indexPath.row]
- }
- return nil
- }
- func getMetadatas(indexPaths: [IndexPath]) -> [Metadata] {
- var metadatas: [Metadata] = []
- for indexPath in indexPaths {
- if indexPath.row < self.metadatas.count {
- metadatas.append(self.metadatas[indexPath.row])
- }
- }
- return metadatas
- }
- func removeMetadata(_ ocId: [String]) {
- self.metadatas.removeAll { item in
- ocId.contains(item.ocId)
- }
- }
- func addMetadatas(_ metadatas: [tableMetadata]) -> Bool {
- var metadatasToInsert: [Metadata] = []
- for tableMetadata in metadatas {
- let metadata = getMetadataFromTableMetadata(tableMetadata)
- if metadata.isLivePhoto, metadata.isVideo { continue }
- if let index = self.metadatas.firstIndex(where: { $0.ocId == tableMetadata.ocId }) {
- self.metadatas[index] = metadata
- } else {
- metadatasToInsert.append(metadata)
- }
- }
-
-
- if !metadatasToInsert.isEmpty {
- if metadatasToInsert.count < 100 {
- for metadata in metadatasToInsert {
- self.insertInMetadatas(metadata: metadata)
- }
- } else {
- for metadata in metadatasToInsert {
- self.metadatas.append(metadata)
- }
- self.metadatas = self.metadatas.sorted { $0.date > $1.date }
- }
- return true
- }
- return false
- }
- }
|