فهرست منبع

Use counter to keep track of most recently loaded activity

Can't rely on it to be all sequential, also since we sometimes only load fractions (filtered for files) there can be gaps.
Adding a simple variable to the database to keep track (for each account separately) fixes that.

Signed-off-by: Henrik Storch <henrik.storch@nextcloud.com>
Henrik Storch 3 سال پیش
والد
کامیت
a5d4b3bbd7
3فایلهای تغییر یافته به همراه77 افزوده شده و 31 حذف شده
  1. 42 8
      iOSClient/Activity/NCActivity.swift
  2. 9 0
      iOSClient/Data/NCDatabase.swift
  3. 26 23
      iOSClient/Data/NCManageDatabase.swift

+ 42 - 8
iOSClient/Activity/NCActivity.swift

@@ -375,7 +375,7 @@ extension NCActivity {
         if !isInitial, let activity = allItems.compactMap({ $0 as? tableActivity }).last {
             loadActivity(idActivity: activity.idActivity, disptachGroup: dispatchGroup)
         } else {
-            loadActivity(idActivity: 0, disptachGroup: dispatchGroup)
+            checkRecentActivity(disptachGroup: dispatchGroup)
         }
 
         dispatchGroup.notify(queue: .main) {
@@ -428,21 +428,55 @@ extension NCActivity {
             }
         }
     }
-    
-    func loadActivity(idActivity: Int, disptachGroup: DispatchGroup) {
+
+    /// Check if most recent activivities are loaded, if not trigger reload
+    func checkRecentActivity(disptachGroup: DispatchGroup) {
+        let recentActivityId = NCManageDatabase.shared.getLatestActivityId(account: appDelegate.account)
+
+        guard recentActivityId > 0 else {
+            return self.loadActivity(idActivity: 0, disptachGroup: disptachGroup)
+        }
+
+        disptachGroup.enter()
+
+        NCCommunication.shared.getActivity(
+            since: 0,
+            limit: 1,
+            objectId: metadata?.fileId,
+            objectType: objectType,
+            previews: true) { (account, activities, errorCode, errorDescription) in
+                defer { disptachGroup.leave() }
+
+                guard errorCode == 0,
+                      account == self.appDelegate.account,
+                      let activity = activities.first,
+                      activity.idActivity > recentActivityId
+                else { return }
+
+                self.loadActivity(idActivity: 0, limit: activity.idActivity - recentActivityId, disptachGroup: disptachGroup)
+            }
+    }
+
+    func loadActivity(idActivity: Int, limit: Int = 200, disptachGroup: DispatchGroup) {
         disptachGroup.enter()
 
         NCCommunication.shared.getActivity(
             since: idActivity,
-            limit: 200,
+            limit: min(limit, 200),
             objectId: metadata?.fileId,
             objectType: objectType,
             previews: true) { (account, activities, errorCode, errorDescription) in
-                
-                if errorCode == 0 && account == self.appDelegate.account {
-                    NCManageDatabase.shared.addActivity(activities, account: account)
+                defer { disptachGroup.leave() }
+                guard errorCode == 0,
+                      account == self.appDelegate.account,
+                      !activities.isEmpty
+                else { return }
+                NCManageDatabase.shared.addActivity(activities, account: account)
+
+                // update most recently loaded activity only when all activities are loaded (not filtered)
+                if self.metadata == nil {
+                    NCManageDatabase.shared.updateLatestActivityId(activities, account: account)
                 }
-                disptachGroup.leave()
             }
     }
 }

+ 9 - 0
iOSClient/Data/NCDatabase.swift

@@ -6,6 +6,7 @@
 //  Copyright © 2017 Marino Faggiana. All rights reserved.
 //
 //  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//  Author Henrik Storch <henrik.storch@nextcloud.com>
 //
 //  This program is free software: you can redistribute it and/or modify
 //  it under the terms of the GNU General Public License as published by
@@ -107,6 +108,14 @@ class tableAccount: Object {
     }
 }
 
+class tableActivityLatestId: Object {
+    @objc dynamic var account = ""
+    @objc dynamic var mostRecentlyLoadedActivityId: Int = 0
+    override static func primaryKey() -> String {
+        return "account"
+    }
+}
+
 class tableActivity: Object, DateCompareable {
     var dateKey: Date { date as Date }
 

+ 26 - 23
iOSClient/Data/NCManageDatabase.swift

@@ -6,6 +6,7 @@
 //  Copyright © 2017 Marino Faggiana. All rights reserved.
 //
 //  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//  Author Henrik Storch <henrik.storch@nextcloud.com>
 //
 //  This program is free software: you can redistribute it and/or modify
 //  it under the terms of the GNU General Public License as published by
@@ -756,7 +757,7 @@ class NCManageDatabase: NSObject {
     //MARK: Table Activity
 
     @objc func addActivity(_ activities: [NCCommunicationActivity], account: String) {
-    
+
         let realm = try! Realm()
 
         do {
@@ -854,22 +855,10 @@ class NCManageDatabase: NSObject {
         guard let filterFileId = filterFileId else {
             return (all: allActivity, filter: allActivity)
         }
-        // comments are loaded seperately
+
+        // comments are loaded seperately, see NCManageDatabase.getComments
         let filtered = allActivity.filter({ String($0.objectId) == filterFileId && $0.type != "comments" })
         return (all: allActivity, filter: filtered)
-        
-        //HELP: What is this? What is it used for? Why not just use `.filter()` on the array
-        var resultsFilter: [tableActivity] = []
-        for result in results {
-            let resultsActivitySubjectRich = realm.objects(tableActivitySubjectRich.self).filter("account == %@ && idActivity == %d", result.account, result.idActivity)
-            for resultActivitySubjectRich in resultsActivitySubjectRich {
-                if filterFileId.contains(resultActivitySubjectRich.id) && resultActivitySubjectRich.key == "file" {
-                    resultsFilter.append(result)
-                    break
-                }
-            }
-        }
-        return(all: allActivity, filter: Array(resultsFilter.map(tableActivity.init)))
     }
     
     @objc func getActivitySubjectRich(account: String, idActivity: Int, key: String) -> tableActivitySubjectRich? {
@@ -904,16 +893,30 @@ class NCManageDatabase: NSObject {
         
         return results
     }
-    
-    @objc func getActivityLastIdActivity(account: String) -> Int {
-        
+
+    @objc func updateLatestActivityId(_ activities: [NCCommunicationActivity], account: String) {
         let realm = try! Realm()
-        
-        if let entities = realm.objects(tableActivity.self).filter("account == %@", account).max(by: { $0.idActivity < $1.idActivity }) {
-            return entities.idActivity
+
+        do {
+            try realm.write {
+                guard let mostRecentActivityId = activities.map({ $0.idActivity }).max() else { return }
+                let newRecentActivity = tableActivityLatestId()
+                newRecentActivity.mostRecentlyLoadedActivityId = mostRecentActivityId
+                newRecentActivity.account = account
+                realm.add(newRecentActivity, update: .all)
+            }
+        } catch {
+            NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
         }
-        
-        return 0
+    }
+
+    @objc func getLatestActivityId(account: String) -> Int {
+
+        let realm = try! Realm()
+        guard let maxId = realm.objects(tableActivityLatestId.self).filter("account == %@", account).map({ $0.mostRecentlyLoadedActivityId }).max()
+        else { return 0 }
+
+        return maxId
     }
     
     //MARK: -