(ns outliner.model.state (:require [reagent.core :as r] [outliner.control.system :as system])) (defn welcome-doc [] (let [id1 (str (random-uuid)) id2 (str (random-uuid))] (system/inject-system-nodes {:root [id1] :nodes {id1 {:id id1 :text "Welcome to Palatium" :annotations [] :children [id2] :parent nil} id2 {:id id2 :text "Try adding a sub-node" :annotations [] :children [] :parent id1}}} nil))) (defn empty-doc [] {:root [] :nodes {}}) (defn get-zoom-id-from-url [] (let [params (js/URLSearchParams. js/window.location.search)] (.get params "zoom"))) (defn html-format? [] (let [params (js/URLSearchParams. js/window.location.search)] (= (.get params "format") "text/html"))) (defn init-view [doc] (let [zoom-id (get-zoom-id-from-url)] {:focused-id (or zoom-id (first (:root doc))) :zoom-id zoom-id :active-context-menu-id nil :toast nil})) (defn init-sys [] {:undo-stack [] :redo-stack [] :location-history [] :dark-mode? false :viewport nil}) (def initial-doc (empty-doc)) (def initial-view (init-view initial-doc)) (def initial-sys (init-sys)) (defonce doc-state (r/atom initial-doc)) (defn- update-tree-size! [new-doc] (let [count (count (remove (fn [[_ node]] (:read-only? node)) (:nodes new-doc)))] (reset! system/tree-size count))) (add-watch doc-state :tree-size-watcher (fn [_ _ _ new-doc] (update-tree-size! new-doc))) ;; Initial count (update-tree-size! @doc-state) (defonce view-state (r/atom initial-view)) (defonce sys-state (r/atom (merge initial-sys {:user nil :sync-status :disconnected :last-sync-timestamp nil :unsaved-changes? false}))) (defn node-exists? [id] (boolean (get-in @doc-state [:nodes id]))) (defn reset-to-initial-state! [] (let [doc (welcome-doc)] (reset! doc-state doc) (reset! view-state (init-view doc)))) (defn clear-preserved-caret-position! [] (swap! view-state dissoc :preserved-caret-position)) (defn clear-preserved-selection! [] (swap! view-state dissoc :preserved-selection)) (defn update-node! [id updates] (swap! doc-state update-in [:nodes id] merge updates)) (defn show-toast! [message] (swap! view-state assoc :toast message)) (defn hide-toast! [] (swap! view-state assoc :toast nil))