refactor(fs): android support

pull/8914/head
Andelf 2023-03-10 23:38:09 +08:00
parent 3f467d72ec
commit 269718d92c
7 changed files with 92 additions and 88 deletions

View File

@ -193,10 +193,10 @@
(rum/defc sync-now
[]
(ui/button "Sync now"
:class "block cursor-pointer"
:small? true
:on-click #(async/offer! fs-sync/immediately-local->remote-chan true)
:style {:color "#ffffff"}))
:class "block cursor-pointer"
:small? true
:on-click #(async/offer! fs-sync/immediately-local->remote-chan true)
:style {:color "#ffffff"}))
(def *last-calculated-time (atom nil))
@ -285,8 +285,7 @@
(not online?) "Currently having connection issues..."
idle-&-no-active? "Everything is synced!"
syncing? "Currently syncing your graph..."
:else "Waiting..."
)]]
:else "Waiting...")]]
[:div.ar
(when queuing? (sync-now))]]
@ -395,7 +394,7 @@
(if (= (:url r) current-repo)
(dissoc r :GraphUUID :GraphName :remote?)
r))
(state/get-repos)))
(state/get-repos)))
(create-remote-graph-fn))
(second @graphs-txid) ; sync not started yet
@ -448,7 +447,7 @@
(concat
(map (fn [f] {:title [:div.file-item
{:key (str "downloading-" f)}
(gp-util/safe-decode-uri-component f)]
f]
:key (str "downloading-" f)
:icon (if enabled-progress-panel?
(let [progress (get sync-progress f)
@ -457,8 +456,7 @@
(< percent 100))
(indicator-progress-pie percent)
(ui/icon "circle-check")))
(ui/icon "arrow-narrow-down"))
}) downloading-files)
(ui/icon "arrow-narrow-down"))}) downloading-files)
(map (fn [e] (let [icon (case (.-type e)
"add" "plus"
@ -467,17 +465,13 @@
path (fs-sync/relative-path e)]
{:title [:div.file-item
{:key (str "queue-" path)}
(try
(gp-util/safe-decode-uri-component path)
(catch :default _
(prn "Wrong path: " path)
path))]
path]
:key (str "queue-" path)
:icon (ui/icon icon)})) (take 10 queuing-files))
(map (fn [f] {:title [:div.file-item
{:key (str "uploading-" f)}
(gp-util/safe-decode-uri-component f)]
f]
:key (str "uploading-" f)
:icon (if enabled-progress-panel?
(let [progress (get sync-progress f)
@ -486,8 +480,7 @@
(< percent 100))
(indicator-progress-pie percent)
(ui/icon "circle-check")))
(ui/icon "arrow-up"))
}) uploading-files)
(ui/icon "arrow-up"))}) uploading-files)
(when (seq history-files)
(map-indexed (fn [i f] (:time f)
@ -500,7 +493,7 @@
(if page-name
(rfe/push-state :page {:name page-name})
(rfe/push-state :file {:path full-path})))}
[:span.file-sync-item (gp-util/safe-decode-uri-component (:path f))]
[:span.file-sync-item (:path f)]
[:div.opacity-50 (ui/humanity-time-ago (:time f) nil)]]})))
(take 10 history-files)))))
@ -531,41 +524,41 @@
(:GraphName graph))]
(ui/button
"Open a local directory"
:class "block w-full py-4 mt-4"
:on-click #(do
(state/close-modal!)
(fs-sync/<sync-stop)
(->
(page-handler/ls-dir-files!
(fn [{:keys [url]}]
(file-sync-handler/init-remote-graph url graph)
(js/setTimeout (fn [] (repo-handler/refresh-repos!)) 200))
"Open a local directory"
:class "block w-full py-4 mt-4"
:on-click #(do
(state/close-modal!)
(fs-sync/<sync-stop)
(->
(page-handler/ls-dir-files!
(fn [{:keys [url]}]
(file-sync-handler/init-remote-graph url graph)
(js/setTimeout (fn [] (repo-handler/refresh-repos!)) 200))
{:empty-dir?-or-pred
(fn [ret]
(let [empty-dir? (nil? (second ret))]
(if-let [root (first ret)]
{:on-open-dir
(fn [result]
(prn ::on-open-dir result)
(let [empty-dir? (not (seq (:files result)))
root (:path result)]
(cond
(string/blank? root)
(p/rejected (js/Error. nil)) ;; cancel pick a directory
;; verify directory
(-> (if empty-dir?
(p/resolved nil)
(if (util/electron?)
(ipc/ipc :readGraphTxIdInfo root)
(fs-util/read-graphs-txid-info root)))
empty-dir?
(p/resolved nil)
(p/then (fn [^js info]
(when (and (not empty-dir?)
(or (nil? info)
(nil? (second info))
(not= (second info) (:GraphUUID graph))))
(if (js/confirm "This directory is not empty, are you sure to sync the remote graph to it? Make sure to back up the directory first.")
(p/resolved nil)
(throw (js/Error. nil)))))))
;; cancel pick a directory
(throw (js/Error. nil)))))})
(p/catch (fn [])))))
:else ; dir is not empty
(-> (if (util/electron?)
(ipc/ipc :readGraphTxIdInfo root)
(fs-util/read-graphs-txid-info root))
(p/then (fn [^js info]
(when (or (nil? info)
(nil? (second info))
(not= (second info) (:GraphUUID graph)))
(if (js/confirm "This directory is not empty, are you sure to sync the remote graph to it? Make sure to back up the directory first.")
(p/resolved nil)
(p/rejected (js/Error. nil))))))))))}) ;; cancel pick a non-empty directory
(p/catch (fn [])))))
[:div.text-xs.opacity-50.px-1.flex-row.flex.items-center.p-2
(ui/icon "alert-circle")
@ -754,8 +747,7 @@
;; Logseq sync available
(maybe-onboarding-show :sync-initiate))
(close-fn)
(set-loading? false))
))]]))
(set-loading? false))))]]))
(rum/defc onboarding-unavailable-file-sync
[close-fn]

View File

@ -40,7 +40,8 @@
[logseq.graph-parser.util :as gp-util]
[react-draggable]
[reitit.frontend.easy :as rfe]
[rum.core :as rum]))
[rum.core :as rum]
[frontend.fs2.path :as fs2-path]))
(rum/defc nav-content-item < rum/reactive
[name {:keys [class]} child]
@ -561,11 +562,9 @@
(let [finished (or (:finished state) 0)
total (:total state)
width (js/Math.round (* (.toFixed (/ finished total) 2) 100))
file-basename (util/node-path.basename
(:current-parsing-file state))
display-filename (if (mobile-util/native-platform?)
(gp-util/safe-decode-uri-component file-basename)
file-basename)
display-filename (some-> (:current-parsing-file state)
not-empty
fs2-path/filename)
left-label [:div.flex.flex-row.font-bold
(t :parsing-files)
[:div.hidden.md:flex.flex-row

View File

@ -31,6 +31,20 @@
(p/do!
(.requestPermissions Filesystem))))))
;; FIXME: should distinguish between no-exist and error
(defn- <file-exists?
[fpath]
(p/catch (p/let [fpath (fs2-path/path-normalize fpath)
stat (.stat Filesystem (clj->js {:path fpath}))]
(-> stat
bean/->clj
:type
(= "file")))
(fn [_error]
false)))
(defn- <write-file-with-utf8
[path content]
(when-not (string/blank? path)
@ -184,14 +198,14 @@
(log/error :write-file-failed error))))
;; Compare with disk content and backup if not equal
(p/let [disk-content (<read-file-with-utf8 fpath)
(p/let [disk-content (if (not= stat :not-found)
(<read-file-with-utf8 fpath)
"")
disk-content (or disk-content "")
repo-dir (config/get-local-dir repo)
ext (util/get-file-ext rpath)
db-content (or old-content (db/get-file repo rpath) "")
contents-matched? (contents-matched? disk-content db-content)]
(prn ::before-write contents-matched? )
(prn disk-content db-content)
(cond
(and
(not= stat :not-found) ; file on the disk was deleted
@ -208,9 +222,9 @@
:mtime)]
(when-not contents-matched?
(backup-file repo-dir :backup-dir fpath disk-content))
(db/set-file-last-modified-at! repo fpath mtime)
(db/set-file-last-modified-at! repo rpath mtime)
(p/let [content content]
(db/set-file-content! repo fpath content))
(db/set-file-content! repo rpath content))
(when ok-handler
(ok-handler repo fpath result))
result)
@ -219,7 +233,7 @@
(error-handler error)
(log/error :write-file-failed error))))))))))
(defn ios-force-include-private
(defn- ios-force-include-private
"iOS sometimes return paths without the private part."
[path]
(if (mobile-util/native-ios?)
@ -321,7 +335,7 @@
(defrecord ^:large-vars/cleanup-todo Capacitorfs []
protocol/Fs
(mkdir! [_this dir]
(let [dir' (normalize-file-protocol-path "" dir)]
(let [dir' (fs2-path/path-normalize dir)]
(-> (.mkdir Filesystem
(clj->js
{:path dir'}))

View File

@ -70,7 +70,8 @@
[logseq.db.schema :as db-schema]
[logseq.graph-parser.config :as gp-config]
[promesa.core :as p]
[rum.core :as rum]))
[rum.core :as rum]
[frontend.fs2.path :as fs2-path]))
;; TODO: should we move all events here?
@ -617,10 +618,13 @@
(defmethod handle :mobile-file-watcher/changed [[_ ^js event]]
(let [type (.-event event)
payload (-> event
(js->clj :keywordize-keys true)
(update :path (fn [path]
(when (string? path) (capacitor-fs/normalize-file-protocol-path nil path)))))]
payload (js->clj event :keywordize-keys true)
dir (:dir payload)
payload (-> payload
(update :path
(fn [path]
(when (string? path)
(fs2-path/relative-path dir path)))))]
(fs-watcher/handle-changed! type payload)
(when (file-sync-handler/enable-sync?)
(sync/file-watch-handler type payload))))

View File

@ -123,7 +123,7 @@
(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 picked-root-fn dir]}]
([ok-handler {:keys [on-open-dir dir-result-fn picked-root-fn dir]}]
(let [path-handles (atom {})
electron? (util/electron?)
mobile-native? (mobile-util/native-platform?)
@ -139,14 +139,8 @@
(fn [path handle]
(when nfs?
(swap! path-handles assoc path handle)))))
_ (when-not (nil? empty-dir?-or-pred)
(cond
(boolean? empty-dir?-or-pred)
(and (not-empty (:files result))
(throw (js/Error. "EmptyDirOnly")))
(fn? empty-dir?-or-pred)
(empty-dir?-or-pred result)))
_ (when (fn? on-open-dir)
(on-open-dir result))
root-handle (:path result)
_ (when (fn? picked-root-fn) (picked-root-fn root-handle))
dir-name (if nfs?
@ -206,11 +200,11 @@
(prn ::prepare-load-new-repo files)
(repo-handler/start-repo-db-if-not-exists! repo)
(prn ::dd (nil? (seq markup-files)))
(let [_finished? (repo-handler/load-new-repo-to-db! repo
{:new-graph? true
:empty-graph? (nil? (seq markup-files))
:file-objs files})
_ (prn ::fuck _finished?)]
(p/do!
(repo-handler/load-new-repo-to-db! repo
{:new-graph? true
:empty-graph? (nil? (seq markup-files))
:file-objs files})
(prn ::debug-2.5)
(state/add-repo! {:url repo :nfs? true})
(prn ::debug-33333)

View File

@ -139,6 +139,7 @@
[b-cut m-cut nil]))
[value nil nil])))
;; FIXME: distinguish from get-repo-name
(defn get-graph-name-from-path
[path]
(when (string? path)
@ -147,4 +148,4 @@
(-> (if (not= (first parts) "0")
(util/string-join-path parts)
(last parts))
js/decodeURI))))
js/decodeURIComponent))))

View File

@ -11,8 +11,8 @@
(defn get-local-repo-identifier
[repo]
(let [repo-path (db-conn/get-repo-name repo)]
(db-conn/get-short-repo-name repo-path)))
(let [repo-name (db-conn/get-repo-name repo)]
(db-conn/get-short-repo-name repo-name)))
(defn get-repo-id-url
"Get Logseq protocol URL, w/o param (v0.1).