Browse Source

feat(ios): sync current graph only when switching from other apps

leizhe 4 years ago
parent
commit
fb0bf97d52

+ 2 - 1
ios/App/App/DownloadiCloudFiles.m

@@ -9,5 +9,6 @@
 #import <Capacitor/Capacitor.h>
 
 CAP_PLUGIN(DownloadiCloudFiles, "DownloadiCloudFiles",
-           CAP_PLUGIN_METHOD(downloadFilesFromiCloud, CAPPluginReturnPromise);
+           CAP_PLUGIN_METHOD(iCloudSync, CAPPluginReturnPromise);
+           CAP_PLUGIN_METHOD(syncGraph, CAPPluginReturnPromise);
            )

+ 32 - 19
ios/App/App/DownloadiCloudFiles.swift

@@ -19,49 +19,62 @@ public class DownloadiCloudFiles: CAPPlugin,  UIDocumentPickerDelegate  {
         return fileManager.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents")
     }
     
-    @objc func downloadFilesFromiCloud(_ call: CAPPluginCall) {
-        
-        self._call = call
+    var isDirectory: ObjCBool = false
+    var downloaded = false
+    
+    @objc func syncGraph(_ call: CAPPluginCall) {
         
-        var downloaded = false
+        guard let graph = call.options["graph"] as? String else {
+            call.reject("Missing graph name")
+            return
+        }
+ 
+        let ignores = [".git", ".trash", "bak", ".recycle"]
         
+        if let url = self.containerUrl?.appendingPathComponent(graph) {
+            do {
+                downloaded = try self.downloadAllFilesFromCloud(at: url, ignorePattern: ignores)
+            } catch {
+                print(error.localizedDescription)
+            }
+        }
+        call.resolve(["success": downloaded])
+    }
+    
+    @objc func iCloudSync(_ call: CAPPluginCall) {
+
         if let url = self.containerUrl, fileManager.fileExists(atPath: url.path) {
-            
             do {
-                print("Download started!")
-                downloaded = try self.downloadAllFilesFromCloud(at: url)
-                print("All files has been downloaded!", downloaded)
+                downloaded = try self.downloadAllFilesFromCloud(at: url, ignorePattern: [".git", ".Trash", "bak", ".recycle"])
             } catch {
-                print("Can't download logseq's files from iCloud to local device.")
                 print(error.localizedDescription)
             }
         }
         
-        self._call?.resolve(["success": downloaded])
+        call.resolve(["success": downloaded])
     }
     
-    func downloadAllFilesFromCloud(at url: URL) throws -> Bool {
+    func downloadAllFilesFromCloud(at url: URL, ignorePattern ignores: [String] = []) throws -> Bool {
 
-        guard url.hasDirectoryPath else { return true }
         let files = try fileManager.contentsOfDirectory(at: url, includingPropertiesForKeys: nil, options: [])
 
-        var completed = false
-        
         for file in files {
             if file.pathExtension.lowercased() == "icloud" {
-                
                 do {
                     try fileManager.startDownloadingUbiquitousItem(at: file)
                 } catch {
                     print("Unexpected error: \(error).")
                 }
-
             } else {
-                if try downloadAllFilesFromCloud(at: file) {
-                    completed = true
+                if fileManager.fileExists(atPath: file.path, isDirectory:&isDirectory) {
+                    if isDirectory.boolValue && !ignores.contains(file.lastPathComponent) {
+                        if try downloadAllFilesFromCloud(at: file, ignorePattern: ignores) {
+                            downloaded = true
+                        }
+                    }
                 }
             }
         }
-        return completed
+        return downloaded
     }
 }

+ 1 - 1
src/main/frontend/fs/capacitor_fs.cljs

@@ -251,7 +251,7 @@
                   (.pickFolder mobile-util/folder-picker)
                   #(js->clj % :keywordize-keys true)
                   :path)
-            _ (when (mobile-util/native-ios?) (.downloadFilesFromiCloud mobile-util/download-icloud-files))
+            _ (when (mobile-util/native-ios?) (mobile-util/sync-icloud-repo path))
             files (readdir path)
             files (js->clj files :keywordize-keys true)]
       (into [] (concat [{:path path}] files))))

+ 5 - 4
src/main/frontend/handler/repo.cljs

@@ -29,7 +29,7 @@
             [promesa.core :as p]
             [shadow.resource :as rc]
             [clojure.set :as set]
-            [frontend.mobile.util :as mobile]
+            [frontend.mobile.util :as mobile-util]
             [frontend.db.persist :as db-persist]
             [electron.ipc :as ipc]))
 
@@ -632,10 +632,11 @@
   [nfs-rebuild-index! ok-handler]
   (route-handler/redirect-to-home!)
   (when-let [repo (state/get-current-repo)]
-    (let [local? (config/local-db? repo)]
+    (let [local? (config/local-db? repo)
+          repo-dir (config/get-repo-dir repo)]
       (if local?
-        (p/let [_ (when (mobile/native-ios?)
-                    (.downloadFilesFromiCloud mobile/download-icloud-files))
+        (p/let [_ (when (mobile-util/native-ios?)
+                    (mobile-util/sync-icloud-repo repo-dir))
                 _ (metadata-handler/set-pages-metadata! repo)]
           (nfs-rebuild-index! repo ok-handler))
         (rebuild-index! repo))

+ 10 - 5
src/main/frontend/mobile/core.cljs

@@ -12,7 +12,8 @@
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.notification :as notification]
             [promesa.core :as p]
-            [frontend.util :as util]))
+            [frontend.util :as util]
+            [frontend.config :as config]))
 
 (defn init!
   []
@@ -50,12 +51,16 @@
   (when (mobile-util/is-native-platform?)
     (.addEventListener js/window "statusTap"
                        #(util/scroll-to-top true))
-    
+
     (.addListener App "appStateChange"
                   (fn [^js state]
                     (when-let [repo (state/get-current-repo)]
-                      (let [is-active? (.-isActive state)]
+                      (let [is-active? (.-isActive state)
+                            repo-dir (config/get-repo-dir repo)]
                         (if is-active?
-                          (p/do! (nfs-handler/refresh! repo repo/refresh-cb)
-                                 (notification/show! "Notes updated!" :success true))
+                          (p/do!
+                           (when (mobile-util/native-ios?)
+                               (mobile-util/sync-icloud-repo repo-dir))
+                           (nfs-handler/refresh! repo repo/refresh-cb)
+                           (notification/show! "Notes updated!" :success true))
                           (editor-handler/save-current-block!))))))))

+ 13 - 5
src/main/frontend/mobile/util.cljs

@@ -1,7 +1,7 @@
 (ns frontend.mobile.util
   (:require ["@capacitor/core" :refer [Capacitor registerPlugin]]
             ["@capacitor/splash-screen" :refer [SplashScreen]]
-            [clojure.string :as str]))
+            [clojure.string :as string]))
 
 (defn platform []
   (.getPlatform Capacitor))
@@ -29,6 +29,14 @@
 (when (native-ios?)
   (defonce ios-file-container (registerPlugin "FileContainer")))
 
+(defn sync-icloud-repo [repo-dir]
+  (let [repo-name (-> (string/split repo-dir "Documents/")
+                      last
+                      string/trim
+                      js/decodeURI)]
+    (.syncGraph download-icloud-files
+                       (clj->js {:graph repo-name}))))
+
 (defn hide-splash []
   (.hide SplashScreen))
 
@@ -101,18 +109,18 @@
 (defn native-iphone-without-notch?
   []
   (when-let [model (get-idevice-model)]
-    (str/starts-with? (first model) "iPhone8")))
+    (string/starts-with? (first model) "iPhone8")))
 
 (defn native-iphone?
   []
   (when-let [model (get-idevice-model)]
-    (and (str/starts-with? (first model) "iPhone")
-         (not (str/starts-with? (first model) "iPhone8")))))
+    (and (string/starts-with? (first model) "iPhone")
+         (not (string/starts-with? (first model) "iPhone8")))))
 
 (defn native-ipad?
   []
   (when-let [model (get-idevice-model)]
-    (str/starts-with? (first model) "iPad")))
+    (string/starts-with? (first model) "iPad")))
 
 (defn get-idevice-statusbar-height
   []