diff --git a/kDriveCore/Data/Cache/DriveFileManager/DriveFileManager.swift b/kDriveCore/Data/Cache/DriveFileManager/DriveFileManager.swift index 861742310..5b7386284 100644 --- a/kDriveCore/Data/Cache/DriveFileManager/DriveFileManager.swift +++ b/kDriveCore/Data/Cache/DriveFileManager/DriveFileManager.swift @@ -540,163 +540,14 @@ public final class DriveFileManager { } } - public struct ActivitiesResult { - public var inserted: [File] - public var updated: [File] - public var deleted: [File] - - public init(inserted: [File] = [], updated: [File] = [], deleted: [File] = []) { - self.inserted = inserted - self.updated = updated - self.deleted = deleted - } - } - - public func fileActivities(file: ProxyFile, - from timestamp: Int? = nil) async throws -> (result: ActivitiesResult, responseAt: Int) { - // Get all pages and assemble - let fetchedFile = try file.resolve(within: self).freeze() - let timestamp = TimeInterval(timestamp ?? fetchedFile.responseAt) - var cursor: String? - var moreComing = true - var pagedActions = [String: FileActivityType]() - var pagedActivities = ActivitiesResult() - var responseAt = 0 - - while moreComing { - // Get activities page - let response = try await apiFetcher.fileActivities( - file: file, - from: Date(timeIntervalSince1970: timestamp), - cursor: cursor - ) - - let activities = response.validApiResponse.data - moreComing = response.validApiResponse.hasMore - cursor = response.validApiResponse.cursor - responseAt = response.validApiResponse.responseAt ?? Int(Date().timeIntervalSince1970) - - try database.writeTransaction { writableRealm in - let cachedFile = try file.resolve(using: writableRealm) - - // Apply activities to file - let results = apply( - activities: activities, - to: cachedFile, - pagedActions: &pagedActions, - timestamp: responseAt, - writableRealm: writableRealm - ) + /// Fetch changes for a given directory and add it to DB + /// - With API V3 there is no notion of activities. We only do a listing for an existing cursor + public func fileActivities(file: ProxyFile) async throws { + var (_, nextCursor) = try await fileListing(in: file) - pagedActivities.inserted.insert(contentsOf: results.inserted, at: 0) - pagedActivities.updated.insert(contentsOf: results.updated, at: 0) - pagedActivities.deleted.insert(contentsOf: results.deleted, at: 0) - } + while nextCursor != nil { + (_, nextCursor) = try await fileListing(in: file) } - return (pagedActivities, responseAt) - } - - // swiftlint:disable:next cyclomatic_complexity - // TODO: Refactor - private func apply(activities: [FileActivity], - to file: File, - pagedActions: inout [String: FileActivityType], - timestamp: Int, - writableRealm: Realm) -> ActivitiesResult { - var insertedFiles = [File]() - var updatedFiles = [File]() - var deletedFiles = [File]() - - for activity in activities { - let fileId = File.uid(driveId: file.driveId, fileId: activity.fileId) - if pagedActions[fileId] == nil { - switch activity.action { - case .fileDelete, .fileTrash: - if let file = writableRealm.object(ofType: File.self, forPrimaryKey: fileId), !file.isInvalidated { - deletedFiles.append(file.freeze()) - } - removeFileInDatabase(fileUid: fileId, cascade: true, writableRealm: writableRealm) - if let file = activity.file { - deletedFiles.append(file) - } - pagedActions[fileId] = .fileDelete - case .fileMoveOut: - if let file = writableRealm.object(ofType: File.self, forPrimaryKey: fileId), - !file.isInvalidated, - let oldParent = file.parent { - oldParent.children.remove(file) - } - if let file = activity.file { - deletedFiles.append(file) - } - pagedActions[fileId] = .fileDelete - case .fileRename: - if let oldFile = writableRealm.object(ofType: File.self, forPrimaryKey: fileId), - !file.isInvalidated, - let renamedFile = activity.file { - try? renameCachedFile(updatedFile: renamedFile, oldFile: oldFile) - // If the file is a folder we have to copy the old attributes which are not returned by the API - keepCacheAttributesForFile( - newFile: renamedFile, - keepProperties: [.standard, .extras], - writableRealm: writableRealm - ) - writableRealm.add(renamedFile, update: .modified) - file.children.insert(renamedFile) - renamedFile.applyLastModifiedDateToLocalFile() - updatedFiles.append(renamedFile) - pagedActions[fileId] = .fileUpdate - } - case .fileMoveIn, .fileRestore, .fileCreate: - if let newFile = activity.file { - keepCacheAttributesForFile( - newFile: newFile, - keepProperties: [.standard, .extras], - writableRealm: writableRealm - ) - writableRealm.add(newFile, update: .modified) - // If was already had a local parent, remove it - if let file = writableRealm.object(ofType: File.self, forPrimaryKey: fileId), - !file.isInvalidated, - let oldParent = file.parent { - oldParent.children.remove(file) - } - file.children.insert(newFile) - insertedFiles.append(newFile) - pagedActions[fileId] = .fileCreate - } - case .fileFavoriteCreate, .fileFavoriteRemove, .fileUpdate, .fileShareCreate, .fileShareUpdate, .fileShareDelete, - .collaborativeFolderCreate, .collaborativeFolderUpdate, .collaborativeFolderDelete, .fileColorUpdate, - .fileColorDelete: - if let newFile = activity.file { - if newFile.isTrashed { - removeFileInDatabase(fileUid: fileId, cascade: true, writableRealm: writableRealm) - deletedFiles.append(newFile) - pagedActions[fileId] = .fileDelete - } else { - keepCacheAttributesForFile( - newFile: newFile, - keepProperties: [.standard, .extras], - writableRealm: writableRealm - ) - writableRealm.add(newFile, update: .modified) - file.children.insert(newFile) - updatedFiles.append(newFile) - pagedActions[fileId] = .fileUpdate - } - } - default: - break - } - } - } - file.responseAt = timestamp - - return ActivitiesResult( - inserted: insertedFiles.map { $0.freeze() }, - updated: updatedFiles.map { $0.freeze() }, - deleted: deletedFiles - ) } func handleError(message: String, offlineFile file: File) { diff --git a/kDriveCore/UI/UIConstants.swift b/kDriveCore/UI/UIConstants.swift index 734d94416..637934d06 100644 --- a/kDriveCore/UI/UIConstants.swift +++ b/kDriveCore/UI/UIConstants.swift @@ -78,10 +78,9 @@ public enum UIConstants { action: .init(title: KDriveResourcesStrings.Localizable.buttonCancel) { Task { do { - let now = Date() try await driveFileManager.undoAction(cancelId: cancelableResponse.id) if let parentFile { - _ = try? await driveFileManager.fileActivities(file: parentFile, from: Int(now.timeIntervalSince1970)) + _ = try? await driveFileManager.fileActivities(file: parentFile) } UIConstants.showSnackBar(message: cancelSuccessMessage)