Bläddra i källkod

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 år sedan
förälder
incheckning
cbcc19309d
1 ändrade filer med 265 tillägg och 231 borttagningar
  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]
             [frontend.mobile.util :as mobile-util]))
 
+;; Stores main application state
 (defonce ^:large-vars/data-var state
   (let [document-mode? (or (storage/get :document/mode?) false)
         current-graph  (let [graph (storage/get :git/current-repo)]
@@ -252,6 +253,9 @@
      :graph/importing-state                 {}
      })))
 
+;; Block ast state
+;; ===============
+
 ;; block uuid -> {content(String) -> ast}
 (def blocks-ast-cache (atom {}))
 (defn add-block-ast-cache!
@@ -268,65 +272,22 @@
   (when (and 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
   "Default config for a repo-specific, user config"
   {:feature/enable-search-remove-accents? true
    :default-arweave-gateway "https://arweave.net"})
 
+;; State that most user config is dependent on
+(declare get-current-repo)
+
 (defn get-config
   "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 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
   []
   (:arweave/gateway (get-config)))
@@ -350,13 +321,6 @@
     built-in-macros
     (: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
   []
   (:custom-css-url (get-config)))
@@ -377,67 +341,10 @@
         value (if (some? value) value (:all-pages-public? (get-config)))]
     (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
   []
   (:default-home (get-config)))
 
-(defn sub-default-home-page
-  []
-  (get-in (sub-config) [:default-home :page] ""))
-
 (defn custom-home-page?
   []
   (some? (:page (get-default-home))))
@@ -513,6 +420,244 @@
   []
   (: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
   []
   (get-in @state [:file-sync/remote-graphs :graphs]))
@@ -604,10 +749,6 @@
   []
   (get (:editor/content @state) (get-edit-input-id)))
 
-(defn sub-edit-content
-  []
-  (sub [:editor/content (get-edit-input-id)]))
-
 (defn get-cursor-range
   []
   (:cursor-range @state))
@@ -661,13 +802,16 @@
     (do
       (set-editor-action! nil)
       (set-editor-action-data! nil))))
+
 (defn get-editor-show-input
   []
   (when (= (get-editor-action) :input)
     (get @state :editor/action-data)))
+
 (defn set-editor-show-commands!
   []
   (when-not (get-editor-action) (set-editor-action! :commands)))
+
 (defn set-editor-show-block-commands!
   []
   (when-not (get-editor-action) (set-editor-action! :block-commands)))
@@ -722,25 +866,10 @@
   []
   (: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
   []
   (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
   []
   (or (get-selection-start-block)
@@ -871,20 +1000,6 @@
        :container       (gobj/get container "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!
   []
   (swap! state merge {:editor/editing? nil
@@ -1037,13 +1152,6 @@
   [value]
   (set-state! :today value))
 
-(defn get-date-formatter
-  []
-  (gp-config/get-date-formatter (get-config)))
-
-(defn shortcuts []
-  (:shortcuts (get-config)))
-
 (defn get-me
   []
   (:me @state))
@@ -1177,11 +1285,6 @@
   []
   (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!
   []
   (let [mode (document-mode?)]
@@ -1198,20 +1301,6 @@
     (set-state! :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!
   [repo-url value]
   (set-state! [:config repo-url] value))
@@ -1233,10 +1322,6 @@
   [value]
   (set-state! :network/online? value))
 
-(defn get-commands
-  []
-  (:commands (get-config)))
-
 (defn get-plugins-commands
   []
   (mapcat seq (flatten (vals (:plugin/installed-slash-commands @state)))))
@@ -1288,11 +1373,6 @@
     true))
 
 
-(defn get-scheduled-future-days
-  []
-  (let [days (:scheduled/future-days (get-config))]
-    (or (when (int? days) days) 0)))
-
 (defn set-graph-syncing?
   [value]
   (set-state! :graph/syncing? value))
@@ -1415,28 +1495,6 @@
   []
   @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
   []
   (:system/events @state))
@@ -1487,26 +1545,10 @@
   [value]
   (set-state! :block/component-editing-mode? value))
 
-(defn logical-outdenting?
-  []
-  (:editor/logical-outdenting? (sub-config)))
-
 (defn get-editor-args
   []
   (: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!
   [value]
   (set-state! [:view/components :page-blocks] value))
@@ -1732,10 +1774,6 @@
     (when (every? not-empty (vals 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
   [is-active?]
   (set-state! :mobile/app-state-change
@@ -1751,10 +1789,6 @@
   [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
   []
   (:file/rename-event-chan @state))