浏览代码

Organize frontend.state into config, subs and everything else

Everything else is purposefully last to expose some state that config
and subs were implicitly relying on. Also noted some TODOs that
would help with state usage
Gabriel Horner 3 年之前
父节点
当前提交
cbcc19309d
共有 1 个文件被更改,包括 265 次插入231 次删除
  1. 265 231
      src/main/frontend/state.cljs

+ 265 - 231
src/main/frontend/state.cljs

@@ -16,6 +16,7 @@
             [logseq.graph-parser.config :as gp-config]
             [logseq.graph-parser.config :as gp-config]
             [frontend.mobile.util :as mobile-util]))
             [frontend.mobile.util :as mobile-util]))
 
 
+;; Stores main application state
 (defonce ^:large-vars/data-var state
 (defonce ^:large-vars/data-var state
   (let [document-mode? (or (storage/get :document/mode?) false)
   (let [document-mode? (or (storage/get :document/mode?) false)
         current-graph  (let [graph (storage/get :git/current-repo)]
         current-graph  (let [graph (storage/get :git/current-repo)]
@@ -252,6 +253,9 @@
      :graph/importing-state                 {}
      :graph/importing-state                 {}
      })))
      })))
 
 
+;; Block ast state
+;; ===============
+
 ;; block uuid -> {content(String) -> ast}
 ;; block uuid -> {content(String) -> ast}
 (def blocks-ast-cache (atom {}))
 (def blocks-ast-cache (atom {}))
 (defn add-block-ast-cache!
 (defn add-block-ast-cache!
@@ -268,65 +272,22 @@
   (when (and block-uuid content)
   (when (and block-uuid content)
     (get-in @blocks-ast-cache [block-uuid content])))
     (get-in @blocks-ast-cache [block-uuid content])))
 
 
-(defn sub
-  [ks]
-  (if (coll? ks)
-    (util/react (rum/cursor-in state ks))
-    (util/react (rum/cursor state ks))))
-
-(defn get-route-match
-  []
-  (:route-match @state))
-
-(defn get-current-route
-  []
-  (get-in (get-route-match) [:data :name]))
-
-(defn home?
-  []
-  (= :home (get-current-route)))
-
-(defn setups-picker?
-  []
-  (= :repo-add (get-current-route)))
-
-(defn get-current-page
-  []
-  (when (= :page (get-current-route))
-    (get-in (get-route-match)
-            [:path-params :name])))
-
-(defn route-has-p?
-  []
-  (get-in (get-route-match) [:query-params :p]))
-
-(defn set-state!
-  [path value]
-  (if (vector? path)
-    (swap! state assoc-in path value)
-    (swap! state assoc path value)))
-
-(defn update-state!
-  [path f]
-  (if (vector? path)
-    (swap! state update-in path f)
-    (swap! state update path f)))
-
-(defn get-current-repo
-  []
-  (or (:git/current-repo @state)
-      (when-not (mobile-util/native-platform?)
-        "local")))
-
-(defn get-root-dir
-  []
-  (:config/root-dir @state))
+;; User configuration getters under :config (and sometimes :me)
+;; ========================================
+;; TODO: Refactor default config values to be data driven. Currently they are all
+;;  buried in getters
+;; TODO: Refactor our access to be more data driven. Currently each getter
+;;  (re-)fetches get-current-repo needlessly
+;; TODO: Add consistent validation. Only a few config options validate at get time
 
 
 (def default-config
 (def default-config
   "Default config for a repo-specific, user config"
   "Default config for a repo-specific, user config"
   {:feature/enable-search-remove-accents? true
   {:feature/enable-search-remove-accents? true
    :default-arweave-gateway "https://arweave.net"})
    :default-arweave-gateway "https://arweave.net"})
 
 
+;; State that most user config is dependent on
+(declare get-current-repo)
+
 (defn get-config
 (defn get-config
   "User config for the given repo or current repo if none given"
   "User config for the given repo or current repo if none given"
   ([]
   ([]
@@ -337,6 +298,16 @@
           (get-in @state [:config ::global-config])
           (get-in @state [:config ::global-config])
           (get-in @state [:config repo-url]))))
           (get-in @state [:config repo-url]))))
 
 
+(defonce publishing? (atom nil))
+
+(defn publishing-enable-editing?
+  []
+  (and @publishing? (:publishing/enable-editing? (get-config))))
+
+(defn enable-editing?
+  []
+  (or (not @publishing?) (:publishing/enable-editing? (get-config))))
+
 (defn get-arweave-gateway
 (defn get-arweave-gateway
   []
   []
   (:arweave/gateway (get-config)))
   (:arweave/gateway (get-config)))
@@ -350,13 +321,6 @@
     built-in-macros
     built-in-macros
     (:macros (get-config))))
     (:macros (get-config))))
 
 
-(defn sub-config
-  "Sub equivalent to get-config"
-  ([] (sub-config (get-current-repo)))
-  ([repo]
-   (let [config (sub :config)]
-     (merge (get config ::global-config) (get config repo)))))
-
 (defn get-custom-css-link
 (defn get-custom-css-link
   []
   []
   (:custom-css-url (get-config)))
   (:custom-css-url (get-config)))
@@ -377,67 +341,10 @@
         value (if (some? value) value (:all-pages-public? (get-config)))]
         value (if (some? value) value (:all-pages-public? (get-config)))]
     (true? value)))
     (true? value)))
 
 
-(defn enable-grammarly?
-  []
-  (true? (:feature/enable-grammarly? (sub-config))))
-
-(defn scheduled-deadlines-disabled?
-  []
-  (true? (:feature/disable-scheduled-and-deadline-query? (sub-config))))
-
-(defn enable-timetracking?
-  []
-  (not (false? (:feature/enable-timetracking? (sub-config)))))
-
-(defn enable-journals?
-  ([]
-   (enable-journals? (get-current-repo)))
-  ([repo]
-   (not (false? (:feature/enable-journals? (sub-config repo))))))
-
-(defn enable-flashcards?
-  ([]
-   (enable-flashcards? (get-current-repo)))
-  ([repo]
-   (not (false? (:feature/enable-flashcards? (sub-config repo))))))
-
-(defn user-groups
-  []
-  (set (sub [:user/info :UserGroups])))
-
-(defn enable-sync?
-  []
-  (sub :feature/enable-sync?))
-
-(defn export-heading-to-list?
-  []
-  (not (false? (:export/heading-to-list? (sub-config)))))
-
-(defn enable-git-auto-push?
-  [repo]
-  (not (false? (:git-auto-push (sub-config repo)))))
-
-(defn enable-block-timestamps?
-  []
-  (true? (:feature/enable-block-timestamps? (sub-config))))
-
-(defn graph-settings
-  []
-  (:graph/settings (sub-config)))
-
-;; Enable by default
-(defn show-brackets?
-  []
-  (not (false? (:ui/show-brackets? (sub-config)))))
-
 (defn get-default-home
 (defn get-default-home
   []
   []
   (:default-home (get-config)))
   (:default-home (get-config)))
 
 
-(defn sub-default-home-page
-  []
-  (get-in (sub-config) [:default-home :page] ""))
-
 (defn custom-home-page?
 (defn custom-home-page?
   []
   []
   (some? (:page (get-default-home))))
   (some? (:page (get-default-home))))
@@ -513,6 +420,244 @@
   []
   []
   (:page-name-order (get-config)))
   (:page-name-order (get-config)))
 
 
+(defn get-date-formatter
+  []
+  (gp-config/get-date-formatter (get-config)))
+
+(defn shortcuts []
+  (:shortcuts (get-config)))
+
+(defn get-commands
+  []
+  (:commands (get-config)))
+
+(defn get-scheduled-future-days
+  []
+  (let [days (:scheduled/future-days (get-config))]
+    (or (when (int? days) days) 0)))
+
+(defn get-start-of-week
+  []
+  (or (:start-of-week (get-config))
+      (get-in @state [:me :settings :start-of-week])
+      6))
+
+(defn get-ref-open-blocks-level
+  []
+  (or
+    (when-let [value (:ref/default-open-blocks-level (get-config))]
+      (when (integer? value)
+        value))
+    2))
+
+(defn get-linked-references-collapsed-threshold
+  []
+  (or
+    (when-let [value (:ref/linked-references-collapsed-threshold (get-config))]
+      (when (integer? value)
+        value))
+    100))
+
+(defn get-export-bullet-indentation
+  []
+  (case (get (get-config) :export/bullet-indentation :tab)
+    :eight-spaces
+    "        "
+    :four-spaces
+    "    "
+    :two-spaces
+    "  "
+    :tab
+    "\t"))
+
+(defn enable-search-remove-accents?
+  []
+  (:feature/enable-search-remove-accents? (get-config)))
+
+;; State cursor fns for use with rum components
+;; ============================================
+
+;; State that some subs are dependent on. Should they use sub too?
+(declare get-edit-input-id document-mode?)
+
+(defn sub
+  "Creates a rum cursor, https://github.com/tonsky/rum#cursors, for use in rum components.
+Similar to re-frame subscriptions"
+  [ks]
+  (if (coll? ks)
+    (util/react (rum/cursor-in state ks))
+    (util/react (rum/cursor state ks))))
+
+(defn sub-config
+  "Sub equivalent to get-config"
+  ([] (sub-config (get-current-repo)))
+  ([repo]
+   (let [config (sub :config)]
+     (merge (get config ::global-config) (get config repo)))))
+
+(defn enable-grammarly?
+  []
+  (true? (:feature/enable-grammarly? (sub-config))))
+
+(defn scheduled-deadlines-disabled?
+  []
+  (true? (:feature/disable-scheduled-and-deadline-query? (sub-config))))
+
+(defn enable-timetracking?
+  []
+  (not (false? (:feature/enable-timetracking? (sub-config)))))
+
+(defn enable-journals?
+  ([]
+   (enable-journals? (get-current-repo)))
+  ([repo]
+   (not (false? (:feature/enable-journals? (sub-config repo))))))
+
+(defn enable-flashcards?
+  ([]
+   (enable-flashcards? (get-current-repo)))
+  ([repo]
+   (not (false? (:feature/enable-flashcards? (sub-config repo))))))
+
+(defn enable-sync?
+  []
+  (sub :feature/enable-sync?))
+
+(defn export-heading-to-list?
+  []
+  (not (false? (:export/heading-to-list? (sub-config)))))
+
+(defn enable-git-auto-push?
+  [repo]
+  (not (false? (:git-auto-push (sub-config repo)))))
+
+(defn enable-block-timestamps?
+  []
+  (true? (:feature/enable-block-timestamps? (sub-config))))
+
+(defn graph-settings
+  []
+  (:graph/settings (sub-config)))
+
+;; Enable by default
+(defn show-brackets?
+  []
+  (not (false? (:ui/show-brackets? (sub-config)))))
+
+(defn sub-default-home-page
+  []
+  (get-in (sub-config) [:default-home :page] ""))
+
+(defn sub-edit-content
+  []
+  (sub [:editor/content (get-edit-input-id)]))
+
+(defn- get-selected-block-ids
+  [blocks]
+  (->> blocks
+       (keep #(when-let [id (dom/attr % "blockid")]
+                (uuid id)))
+       (distinct)))
+
+(defn sub-block-selected?
+  [block-uuid]
+  (rum/react
+   (rum/derived-atom [state] [::select-block block-uuid]
+     (fn [state]
+       (contains? (set (get-selected-block-ids (:selection/blocks state)))
+                  block-uuid)))))
+
+(defn block-content-max-length
+  [repo]
+  (or (:block/content-max-length (sub-config repo)) 5000))
+
+(defn mobile?
+  []
+  (or (util/mobile?) (mobile-util/native-platform?)))
+
+(defn enable-tooltip?
+  []
+  (if (mobile?)
+    false
+    (get (sub-config) :ui/enable-tooltip? true)))
+
+(defn show-command-doc?
+  []
+  (get (sub-config) :ui/show-command-doc? true))
+
+(defn logical-outdenting?
+  []
+  (:editor/logical-outdenting? (sub-config)))
+
+(defn enable-encryption?
+  [repo]
+  (:feature/enable-encryption? (sub-config repo)))
+
+(defn doc-mode-enter-for-new-line?
+  []
+  (and (document-mode?)
+       (not (:shortcut/doc-mode-enter-for-new-block? (sub-config)))))
+
+(defn user-groups
+  []
+  (set (sub [:user/info :UserGroups])))
+
+;; State mutation helpers
+;; ======================
+
+(defn set-state!
+  [path value]
+  (if (vector? path)
+    (swap! state assoc-in path value)
+    (swap! state assoc path value)))
+
+(defn update-state!
+  [path f]
+  (if (vector? path)
+    (swap! state update-in path f)
+    (swap! state update path f)))
+
+;; State getters and setters
+;; =========================
+;; These fns handle any key except :config.
+;; Some state is also stored in local storage and/or sent to electron's main process
+
+(defn get-route-match
+  []
+  (:route-match @state))
+
+(defn get-current-route
+  []
+  (get-in (get-route-match) [:data :name]))
+
+(defn home?
+  []
+  (= :home (get-current-route)))
+
+(defn setups-picker?
+  []
+  (= :repo-add (get-current-route)))
+
+(defn get-current-page
+  []
+  (when (= :page (get-current-route))
+    (get-in (get-route-match)
+            [:path-params :name])))
+
+(defn route-has-p?
+  []
+  (get-in (get-route-match) [:query-params :p]))
+
+(defn get-current-repo
+  []
+  (or (:git/current-repo @state)
+      (when-not (mobile-util/native-platform?)
+        "local")))
+
+(defn get-root-dir
+  []
+  (:config/root-dir @state))
+
 (defn get-remote-repos
 (defn get-remote-repos
   []
   []
   (get-in @state [:file-sync/remote-graphs :graphs]))
   (get-in @state [:file-sync/remote-graphs :graphs]))
@@ -604,10 +749,6 @@
   []
   []
   (get (:editor/content @state) (get-edit-input-id)))
   (get (:editor/content @state) (get-edit-input-id)))
 
 
-(defn sub-edit-content
-  []
-  (sub [:editor/content (get-edit-input-id)]))
-
 (defn get-cursor-range
 (defn get-cursor-range
   []
   []
   (:cursor-range @state))
   (:cursor-range @state))
@@ -661,13 +802,16 @@
     (do
     (do
       (set-editor-action! nil)
       (set-editor-action! nil)
       (set-editor-action-data! nil))))
       (set-editor-action-data! nil))))
+
 (defn get-editor-show-input
 (defn get-editor-show-input
   []
   []
   (when (= (get-editor-action) :input)
   (when (= (get-editor-action) :input)
     (get @state :editor/action-data)))
     (get @state :editor/action-data)))
+
 (defn set-editor-show-commands!
 (defn set-editor-show-commands!
   []
   []
   (when-not (get-editor-action) (set-editor-action! :commands)))
   (when-not (get-editor-action) (set-editor-action! :commands)))
+
 (defn set-editor-show-block-commands!
 (defn set-editor-show-block-commands!
   []
   []
   (when-not (get-editor-action) (set-editor-action! :block-commands)))
   (when-not (get-editor-action) (set-editor-action! :block-commands)))
@@ -722,25 +866,10 @@
   []
   []
   (:selection/blocks @state))
   (:selection/blocks @state))
 
 
-(defn- get-selected-block-ids
-  [blocks]
-  (->> blocks
-       (keep #(when-let [id (dom/attr % "blockid")]
-                (uuid id)))
-       (distinct)))
-
 (defn get-selection-block-ids
 (defn get-selection-block-ids
   []
   []
   (get-selected-block-ids (get-selection-blocks)))
   (get-selected-block-ids (get-selection-blocks)))
 
 
-(defn sub-block-selected?
-  [block-uuid]
-  (rum/react
-   (rum/derived-atom [state] [::select-block block-uuid]
-     (fn [state]
-       (contains? (set (get-selected-block-ids (:selection/blocks state)))
-                  block-uuid)))))
-
 (defn get-selection-start-block-or-first
 (defn get-selection-start-block-or-first
   []
   []
   (or (get-selection-start-block)
   (or (get-selection-start-block)
@@ -871,20 +1000,6 @@
        :container       (gobj/get container "id")
        :container       (gobj/get container "id")
        :pos             (cursor/pos (gdom/getElement edit-input-id))})))
        :pos             (cursor/pos (gdom/getElement edit-input-id))})))
 
 
-(defonce publishing? (atom nil))
-
-(defn publishing-enable-editing?
-  []
-  (and @publishing? (:publishing/enable-editing? (get-config))))
-
-(defn enable-editing?
-  []
-  (or (not @publishing?) (:publishing/enable-editing? (get-config))))
-
-(defn block-content-max-length
-  [repo]
-  (or (:block/content-max-length (sub-config repo)) 5000))
-
 (defn clear-edit!
 (defn clear-edit!
   []
   []
   (swap! state merge {:editor/editing? nil
   (swap! state merge {:editor/editing? nil
@@ -1037,13 +1152,6 @@
   [value]
   [value]
   (set-state! :today value))
   (set-state! :today value))
 
 
-(defn get-date-formatter
-  []
-  (gp-config/get-date-formatter (get-config)))
-
-(defn shortcuts []
-  (:shortcuts (get-config)))
-
 (defn get-me
 (defn get-me
   []
   []
   (:me @state))
   (:me @state))
@@ -1177,11 +1285,6 @@
   []
   []
   (get @state :document/mode?))
   (get @state :document/mode?))
 
 
-(defn doc-mode-enter-for-new-line?
-  []
-  (and (document-mode?)
-       (not (:shortcut/doc-mode-enter-for-new-block? (sub-config)))))
-
 (defn toggle-document-mode!
 (defn toggle-document-mode!
   []
   []
   (let [mode (document-mode?)]
   (let [mode (document-mode?)]
@@ -1198,20 +1301,6 @@
     (set-state! :ui/shortcut-tooltip? (not mode))
     (set-state! :ui/shortcut-tooltip? (not mode))
     (storage/set :ui/shortcut-tooltip? (not mode))))
     (storage/set :ui/shortcut-tooltip? (not mode))))
 
 
-(defn mobile?
-  []
-  (or (util/mobile?) (mobile-util/native-platform?)))
-
-(defn enable-tooltip?
-  []
-  (if (mobile?)
-    false
-    (get (sub-config) :ui/enable-tooltip? true)))
-
-(defn show-command-doc?
-  []
-  (get (sub-config) :ui/show-command-doc? true))
-
 (defn set-config!
 (defn set-config!
   [repo-url value]
   [repo-url value]
   (set-state! [:config repo-url] value))
   (set-state! [:config repo-url] value))
@@ -1233,10 +1322,6 @@
   [value]
   [value]
   (set-state! :network/online? value))
   (set-state! :network/online? value))
 
 
-(defn get-commands
-  []
-  (:commands (get-config)))
-
 (defn get-plugins-commands
 (defn get-plugins-commands
   []
   []
   (mapcat seq (flatten (vals (:plugin/installed-slash-commands @state)))))
   (mapcat seq (flatten (vals (:plugin/installed-slash-commands @state)))))
@@ -1288,11 +1373,6 @@
     true))
     true))
 
 
 
 
-(defn get-scheduled-future-days
-  []
-  (let [days (:scheduled/future-days (get-config))]
-    (or (when (int? days) days) 0)))
-
 (defn set-graph-syncing?
 (defn set-graph-syncing?
   [value]
   [value]
   (set-state! :graph/syncing? value))
   (set-state! :graph/syncing? value))
@@ -1415,28 +1495,6 @@
   []
   []
   @editor-op)
   @editor-op)
 
 
-(defn get-start-of-week
-  []
-  (or (:start-of-week (get-config))
-      (get-in @state [:me :settings :start-of-week])
-      6))
-
-(defn get-ref-open-blocks-level
-  []
-  (or
-    (when-let [value (:ref/default-open-blocks-level (get-config))]
-      (when (integer? value)
-        value))
-    2))
-
-(defn get-linked-references-collapsed-threshold
-  []
-  (or
-    (when-let [value (:ref/linked-references-collapsed-threshold (get-config))]
-      (when (integer? value)
-        value))
-    100))
-
 (defn get-events-chan
 (defn get-events-chan
   []
   []
   (:system/events @state))
   (:system/events @state))
@@ -1487,26 +1545,10 @@
   [value]
   [value]
   (set-state! :block/component-editing-mode? value))
   (set-state! :block/component-editing-mode? value))
 
 
-(defn logical-outdenting?
-  []
-  (:editor/logical-outdenting? (sub-config)))
-
 (defn get-editor-args
 (defn get-editor-args
   []
   []
   (:editor/args @state))
   (:editor/args @state))
 
 
-(defn get-export-bullet-indentation
-  []
-  (case (get (get-config) :export/bullet-indentation :tab)
-    :eight-spaces
-    "        "
-    :four-spaces
-    "    "
-    :two-spaces
-    "  "
-    :tab
-    "\t"))
-
 (defn set-page-blocks-cp!
 (defn set-page-blocks-cp!
   [value]
   [value]
   (set-state! [:view/components :page-blocks] value))
   (set-state! [:view/components :page-blocks] value))
@@ -1732,10 +1774,6 @@
     (when (every? not-empty (vals agent-opts))
     (when (every? not-empty (vals agent-opts))
       (str (:protocol agent-opts) "://" (:host agent-opts) ":" (:port agent-opts)))))
       (str (:protocol agent-opts) "://" (:host agent-opts) ":" (:port agent-opts)))))
 
 
-(defn enable-encryption?
-  [repo]
-  (:feature/enable-encryption? (sub-config repo)))
-
 (defn set-mobile-app-state-change
 (defn set-mobile-app-state-change
   [is-active?]
   [is-active?]
   (set-state! :mobile/app-state-change
   (set-state! :mobile/app-state-change
@@ -1751,10 +1789,6 @@
   [dir]
   [dir]
   (contains? (:file/unlinked-dirs @state) dir))
   (contains? (:file/unlinked-dirs @state) dir))
 
 
-(defn enable-search-remove-accents?
-  []
-  (:feature/enable-search-remove-accents? (get-config)))
-
 (defn get-file-rename-event-chan
 (defn get-file-rename-event-chan
   []
   []
   (:file/rename-event-chan @state))
   (:file/rename-event-chan @state))