feat: add util persist-var

This commit is contained in:
rcmerci
2021-07-15 15:27:17 +08:00
committed by Tienson Qin
parent 1571b9fce1
commit 6dafc0af0c
4 changed files with 125 additions and 38 deletions

View File

@@ -4,6 +4,7 @@
[frontend.db.query-react :as react]
[frontend.util :as util]
[frontend.util.property :as property]
[frontend.util.persist-var :as persist-var]
[frontend.db :as db]
[frontend.state :as state]
[frontend.handler.editor :as editor-handler]
@@ -23,7 +24,7 @@
;;; ================================================================
;;; Some Commentary
;;; - One block with property `card-type-property' is treated as a card.
;;; - When the card's type is ':sided', this block's content is the front side,
;;; - When the card's type is ':sided', root block's content is the front side,
;;; and its children are the back side
;;; - When the card's type is ':cloze', '{{cloze: <content>}}' shows as '[...]'
@@ -57,8 +58,7 @@
"any number between 0 and 1 (the greater it is the faster the changes of the OF matrix)"
0.5)
;;; TODO: persist var 'of-matrix'
(def of-matrix (atom nil))
(def of-matrix (persist-var/persist-var nil "srs-of-matrix"))
;;; ================================================================
;;; utils
@@ -479,7 +479,8 @@
(fn [review-records]
(operation-card-info-summary!
review-records review-cards card-query-block)
(swap! (::need-requery state) (fn [o] (not o))))}))))))}
(swap! (::need-requery state) (fn [o] (not o)))
(persist-var/persist-save of-matrix))}))))))}
svg/edit]
[:a.open-block-ref-link.bg-base-2.text-sm.ml-2
{:title "click to refresh count"
@@ -495,3 +496,6 @@
card-next-schedule-property
card-last-easiness-factor-property
card-last-score-property})
;; (def f []
;; (persist-def 1 2 3 " "))

View File

@@ -141,48 +141,51 @@
(p/let [file-handle (idb/get-item basename-handle-path)]
;; check file-handle available, remove it when got 'NotFoundError'
(p/let [test-get-file (when file-handle
(p/catch (p/let [_ (.getFile file-handle)] true)
(fn [e]
(when (= "NotFoundError" (.-name e))
(idb/remove-item! basename-handle-path)
(remove-nfs-file-handle! basename-handle-path))
false)))
(p/catch (p/let [_ (.getFile file-handle)] true)
(fn [e]
(js/console.dir e)
(when (= "NotFoundError" (.-name e))
(idb/remove-item! basename-handle-path)
(remove-nfs-file-handle! basename-handle-path))
false)))
file-handle (if test-get-file file-handle nil)]
(when file-handle
(add-nfs-file-handle! basename-handle-path file-handle))
(if file-handle
(p/let [local-file (.getFile file-handle)
local-content (.text local-file)
local-last-modified-at (gobj/get local-file "lastModified")
current-time (util/time-ms)
new? (> current-time local-last-modified-at)
new-created? (nil? last-modified-at)
not-changed? (= last-modified-at local-last-modified-at)
format (-> (util/get-file-ext path)
(config/get-file-format))
pending-writes (state/get-write-chan-length)
draw? (and path (string/ends-with? path ".excalidraw"))
config? (and path (string/ends-with? path "/config.edn"))]
(p/let [_ (verify-permission repo file-handle true)
_ (utils/writeFile file-handle content)
file (.getFile file-handle)]
(if (and local-content new?
(or
draw?
config?
;; Writing not finished
(> pending-writes 0)
;; not changed by other editors
not-changed?
new-created?))
(-> (p/let [local-file (.getFile file-handle)
local-content (.text local-file)
local-last-modified-at (gobj/get local-file "lastModified")
current-time (util/time-ms)
new? (> current-time local-last-modified-at)
new-created? (nil? last-modified-at)
not-changed? (= last-modified-at local-last-modified-at)
format (-> (util/get-file-ext path)
(config/get-file-format))
pending-writes (state/get-write-chan-length)
draw? (and path (string/ends-with? path ".excalidraw"))
config? (and path (string/ends-with? path "/config.edn"))]
(p/let [_ (verify-permission repo file-handle true)
_ (utils/writeFile file-handle content)
file (.getFile file-handle)]
(when file
(nfs-saved-handler repo path file)))
(js/alert (str "The file has been modified on your local disk! File path: " path
", please save your changes and click the refresh button to reload it.")))))
(if (and local-content new?
(or
draw?
config?
;; Writing not finished
(> pending-writes 0)
;; not changed by other editors
not-changed?
new-created?))
(p/let [_ (verify-permission repo file-handle true)
_ (utils/writeFile file-handle content)
file (.getFile file-handle)]
(when file
(nfs-saved-handler repo path file)))
(js/alert (str "The file has been modified on your local disk! File path: " path
", please save your changes and click the refresh button to reload it.")))))
(p/catch (fn [e]
(js/console.error e))))
;; create file handle
(->
(p/let [handle (idb/get-item handle-path)]

View File

@@ -1396,3 +1396,9 @@
(defn get-favorites-name
[]
(or (:name/favorites (get-config)) "Favorites"))
(defn add-watch-state [key f]
(add-watch state key f))
(defn remove-watch-state [key]
(remove-watch state key))

View File

@@ -0,0 +1,74 @@
(ns frontend.util.persist-var
(:require [frontend.config :as config]
[frontend.state :as state]
[frontend.fs :as fs]
[frontend.util :as util]
[promesa.core :as p]))
(defn- load-path [location]
(config/get-file-path (state/get-current-repo) (str config/app-name "/" location ".edn")))
(defprotocol ILoad
(-load [this]))
(defprotocol ISave
(-save [this]))
(deftype PersistVar [*value location]
ILoad
(-load [_]
(state/add-watch-state (keyword (str "persist-var/" location))
(fn [k r o n]
(let [repo (state/get-current-repo)]
(when (and
(not (get-in @*value [repo :loaded?]))
(get-in n [:nfs/user-granted? repo]))
(p/let [content (fs/read-file
(config/get-repo-dir (state/get-current-repo))
(load-path location))]
(when-let [content (and (some? content)
(try (cljs.reader/read-string content)
(catch js/Error e
(println (util/format "load persist-var failed: %s" (load-path location)))
(js/console.dir e))))]
(swap! *value (fn [o]
(-> o
(assoc-in [repo :loaded?] true)
(assoc-in [repo :value] content)))))))))))
ISave
(-save [_]
(let [path (load-path location)
repo (state/get-current-repo)
content (str (get-in @*value [repo :value]))
dir (config/get-repo-dir repo)]
(fs/write-file! repo dir path content nil)))
IDeref
(-deref [this]
(get-in @*value [(state/get-current-repo) :value]))
IReset
(-reset! [o new-value]
(swap! *value (fn [o] (assoc-in @*value [(state/get-current-repo) :value] new-value)))))
(defn persist-var [init-value location]
"This var is stored at logseq/LOCATION.edn"
(let [var (->PersistVar (atom {(state/get-current-repo)
{:value init-value
:loaded? false}})
location)]
(-load var)
var))
(defn persist-save [v]
{:pre [(satisfies? ISave v)]}
(-save v))
(comment
(do
(def bbb (persist-var 1 "aaa"))
(-save bbb)
))