mirror of https://github.com/logseq/logseq
fix: prompt to create a Logseq sync graph or normal graph on iOS
Previously, users can create a graph everywhere including the iCloud folder, which is both confusing and can cause unexpected data conflicts. Another enhancement: After the user confirms the "Use Logseq Sync for this new graph?" prompt, a remote graph will be created and start to sync automatically. https://www.loom.com/share/69059969747c4b798a4c712c45e442d7pull/7184/head
parent
2dfac3d774
commit
7ddfa66004
|
@ -18,13 +18,33 @@ public class FolderPicker: CAPPlugin, UIDocumentPickerDelegate {
|
|||
self._call = call
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
|
||||
let documentPicker = UIDocumentPickerViewController(
|
||||
documentTypes: [String(kUTTypeFolder)],
|
||||
in: UIDocumentPickerMode.open
|
||||
documentTypes: [String(kUTTypeFolder)],
|
||||
in: UIDocumentPickerMode.open
|
||||
)
|
||||
|
||||
// Set the initial directory.
|
||||
|
||||
if let path = call.getString("path") {
|
||||
// guard let url = URL(string: path) else {
|
||||
// call.reject("can not parse url")
|
||||
// return
|
||||
// }
|
||||
|
||||
guard let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
|
||||
|
||||
let url = documentDirectory.appendingPathComponent(path)
|
||||
|
||||
print("picked folder url = " + url.path)
|
||||
|
||||
documentPicker.directoryURL = url
|
||||
|
||||
}
|
||||
|
||||
documentPicker.allowsMultipleSelection = false
|
||||
documentPicker.delegate = self
|
||||
|
||||
documentPicker.modalPresentationStyle = UIModalPresentationStyle.fullScreen
|
||||
|
||||
self?.bridge?.viewController?.present(
|
||||
|
|
|
@ -534,7 +534,8 @@
|
|||
(file-sync-handler/init-remote-graph url graph)
|
||||
(js/setTimeout (fn [] (repo-handler/refresh-repos!)) 200))
|
||||
|
||||
{:empty-dir?-or-pred
|
||||
{:sync-from-remote? true
|
||||
:empty-dir?-or-pred
|
||||
(fn [ret]
|
||||
(let [empty-dir? (nil? (second ret))]
|
||||
(if-let [root (first ret)]
|
||||
|
|
|
@ -154,9 +154,9 @@
|
|||
nfs-record))
|
||||
|
||||
(defn open-dir
|
||||
[ok-handler]
|
||||
[dir ok-handler]
|
||||
(let [record (get-record)]
|
||||
(p/let [result (protocol/open-dir record ok-handler)]
|
||||
(p/let [result (protocol/open-dir record dir ok-handler)]
|
||||
(if (or (util/electron?)
|
||||
(mobile-util/native-platform?))
|
||||
(let [[dir & paths] (bean/->clj result)]
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
(js/window.pfs.rename old-path new-path))
|
||||
(stat [_this dir path]
|
||||
(js/window.pfs.stat (str dir path)))
|
||||
(open-dir [_this _ok-handler]
|
||||
(open-dir [_this _dir _ok-handler]
|
||||
nil)
|
||||
(get-files [_this _path-or-handle _ok-handler]
|
||||
nil)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
(ns frontend.fs.capacitor-fs
|
||||
"Implementation of fs protocol for mobile"
|
||||
(:require ["@capacitor/filesystem" :refer [Encoding Filesystem]]
|
||||
(:require ["@capacitor/filesystem" :refer [Encoding Filesystem Directory]]
|
||||
[cljs-bean.core :as bean]
|
||||
[clojure.string :as string]
|
||||
[goog.string :as gstring]
|
||||
|
@ -260,6 +260,25 @@
|
|||
:webkit-allow-full-screen "webkitallowfullscreen"
|
||||
:height "100%"}]])
|
||||
|
||||
(defn- open-dir
|
||||
[dir]
|
||||
(p/let [_ (when (mobile-util/native-android?) (android-check-permission))
|
||||
{:keys [path localDocumentsPath]} (-> (.pickFolder mobile-util/folder-picker
|
||||
(clj->js (when (and dir (mobile-util/native-ios?))
|
||||
{:path dir})))
|
||||
(p/then #(js->clj % :keywordize-keys true))
|
||||
(p/catch (fn [e]
|
||||
(js/alert (str e))
|
||||
nil))) ;; NOTE: If pick folder fails, let it crash
|
||||
_ (when (and (mobile-util/native-ios?)
|
||||
(not (or (local-container-path? path localDocumentsPath)
|
||||
(mobile-util/iCloud-container-path? path))))
|
||||
(state/pub-event! [:modal/show-instruction]))
|
||||
_ (js/console.log "Opening or Creating graph at directory: " path)
|
||||
files (readdir path)
|
||||
files (js->clj files :keywordize-keys true)]
|
||||
(into [] (concat [{:path path}] files))))
|
||||
|
||||
(defrecord ^:large-vars/cleanup-todo Capacitorfs []
|
||||
protocol/Fs
|
||||
(mkdir! [_this dir]
|
||||
|
@ -336,21 +355,8 @@
|
|||
(let [path (get-file-path dir path)]
|
||||
(p/chain (.stat Filesystem (clj->js {:path path}))
|
||||
#(js->clj % :keywordize-keys true))))
|
||||
(open-dir [_this _ok-handler]
|
||||
(p/let [_ (when (mobile-util/native-android?) (android-check-permission))
|
||||
{:keys [path localDocumentsPath]} (-> (.pickFolder mobile-util/folder-picker)
|
||||
(p/then #(js->clj % :keywordize-keys true))
|
||||
(p/catch (fn [e]
|
||||
(js/alert (str e))
|
||||
nil))) ;; NOTE: If pick folder fails, let it crash
|
||||
_ (when (and (mobile-util/native-ios?)
|
||||
(not (or (local-container-path? path localDocumentsPath)
|
||||
(mobile-util/iCloud-container-path? path))))
|
||||
(state/pub-event! [:modal/show-instruction]))
|
||||
_ (js/console.log "Opening or Creating graph at directory: " path)
|
||||
files (readdir path)
|
||||
files (js->clj files :keywordize-keys true)]
|
||||
(into [] (concat [{:path path}] files))))
|
||||
(open-dir [_this dir _ok-handler]
|
||||
(open-dir dir))
|
||||
(get-files [_this path-or-handle _ok-handler]
|
||||
(readdir path-or-handle))
|
||||
(watch-dir! [_this dir _options]
|
||||
|
|
|
@ -224,7 +224,7 @@
|
|||
:file/size (get-attr "size")
|
||||
:file/type (get-attr "type")}))
|
||||
(p/rejected "File not exists")))
|
||||
(open-dir [_this ok-handler]
|
||||
(open-dir [_this _dir ok-handler]
|
||||
(utils/openDirectory #js {:recursive true}
|
||||
ok-handler))
|
||||
(get-files [_this path-or-handle ok-handler]
|
||||
|
|
|
@ -75,8 +75,8 @@
|
|||
(error-handler error)
|
||||
(log/error :write-file-failed error)))))))))
|
||||
|
||||
(defn- open-dir []
|
||||
(p/let [dir-path (util/mocked-open-dir-path)
|
||||
(defn- open-dir [dir]
|
||||
(p/let [dir-path (or dir (util/mocked-open-dir-path))
|
||||
result (if dir-path
|
||||
(ipc/ipc "getFiles" dir-path)
|
||||
(ipc/ipc "openDir" {}))]
|
||||
|
@ -113,8 +113,8 @@
|
|||
(stat [_this dir path]
|
||||
(let [path (concat-path dir path)]
|
||||
(ipc/ipc "stat" path)))
|
||||
(open-dir [_this _ok-handler]
|
||||
(open-dir))
|
||||
(open-dir [_this dir _ok-handler]
|
||||
(open-dir dir))
|
||||
(get-files [_this path-or-handle _ok-handler]
|
||||
(ipc/ipc "getFiles" path-or-handle))
|
||||
(watch-dir! [_this dir options]
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
(rename! [this repo old-path new-path])
|
||||
(copy! [this repo old-path new-path])
|
||||
(stat [this dir path])
|
||||
(open-dir [this ok-handler])
|
||||
(open-dir [this dir ok-handler])
|
||||
(get-files [this path-or-handle ok-handler])
|
||||
(watch-dir! [this dir options])
|
||||
(unwatch-dir! [this dir])
|
||||
|
|
|
@ -572,6 +572,24 @@
|
|||
(state/close-modal!)
|
||||
(nfs-handler/refresh! (state/get-current-repo) refresh-cb)))]]))
|
||||
|
||||
(defmethod handle :sync/create-remote-graph [[_ current-repo]]
|
||||
(let [graph-name (js/decodeURI (util/node-path.basename current-repo))]
|
||||
(async/go
|
||||
(async/<! (sync/<sync-stop))
|
||||
(state/set-state! [:ui/loading? :graph/create-remote?] true)
|
||||
(when-let [GraphUUID (get (async/<! (file-sync-handler/create-graph graph-name)) 2)]
|
||||
(async/<! (sync/sync-start))
|
||||
(state/set-state! [:ui/loading? :graph/create-remote?] false)
|
||||
;; update existing repo
|
||||
(state/set-repos! (map (fn [r]
|
||||
(if (= (:url r) current-repo)
|
||||
(assoc r
|
||||
:GraphUUID GraphUUID
|
||||
:GraphName graph-name
|
||||
:remote? true)
|
||||
r))
|
||||
(state/get-repos)))))))
|
||||
|
||||
(defmethod handle :graph/re-index [[_]]
|
||||
;; Ensure the graph only has ONE window instance
|
||||
(repo-handler/re-index!
|
||||
|
|
|
@ -691,11 +691,18 @@
|
|||
(defn ls-dir-files!
|
||||
([ok-handler] (ls-dir-files! ok-handler nil))
|
||||
([ok-handler opts]
|
||||
(web-nfs/ls-dir-files-with-handler!
|
||||
(fn [e]
|
||||
(init-commands!)
|
||||
(when ok-handler (ok-handler e)))
|
||||
opts)))
|
||||
(let [ios-logseq-sync? (when (and (mobile-util/native-ios?)
|
||||
(state/enable-sync?)
|
||||
(not (:sync-from-remote? opts)))
|
||||
(js/confirm "Use Logseq Sync for this new graph?"))]
|
||||
(web-nfs/ls-dir-files-with-handler!
|
||||
(fn [e]
|
||||
(init-commands!)
|
||||
(when ok-handler
|
||||
(ok-handler e)
|
||||
(when ios-logseq-sync?
|
||||
(state/pub-event! [:sync/create-remote-graph (state/get-current-repo)]))))
|
||||
(assoc opts :ios-logseq-sync? ios-logseq-sync?)))))
|
||||
|
||||
(defn get-all-pages
|
||||
[repo]
|
||||
|
|
|
@ -121,18 +121,22 @@
|
|||
(defn ^:large-vars/cleanup-todo ls-dir-files-with-handler!
|
||||
"Read files from directory and setup repo (for the first time setup a repo)"
|
||||
([ok-handler] (ls-dir-files-with-handler! ok-handler nil))
|
||||
([ok-handler {:keys [empty-dir?-or-pred dir-result-fn]}]
|
||||
([ok-handler {:keys [empty-dir?-or-pred dir-result-fn ios-logseq-sync?]}]
|
||||
(let [path-handles (atom {})
|
||||
electron? (util/electron?)
|
||||
mobile-native? (mobile-util/native-platform?)
|
||||
nfs? (and (not electron?)
|
||||
(not mobile-native?))
|
||||
*repo (atom nil)]
|
||||
*repo (atom nil)
|
||||
dir (when ios-logseq-sync?
|
||||
;; open Logseq's Documents folder
|
||||
"")]
|
||||
;; TODO: add ext filter to avoid loading .git or other ignored file handlers
|
||||
(->
|
||||
(p/let [result (if (fn? dir-result-fn)
|
||||
(dir-result-fn {:path-handles path-handles :nfs? nfs?})
|
||||
(fs/open-dir (fn [path handle]
|
||||
(fs/open-dir dir
|
||||
(fn [path handle]
|
||||
(when nfs?
|
||||
(swap! path-handles assoc path handle)))))
|
||||
_ (when-not (nil? empty-dir?-or-pred)
|
||||
|
|
Loading…
Reference in New Issue