Browse Source

remove posh

Tienson Qin 5 years ago
parent
commit
6c7fc9c64c

+ 1 - 3
web/deps.edn

@@ -4,9 +4,7 @@
   cider/cider-nrepl           {:mvn/version "0.23.0-SNAPSHOT"}
   binaryage/devtools          {:mvn/version "0.9.10"}
 
-  sablono                     {:mvn/version "0.8.1"}
-  rum                         {:local/root "/home/tienson/codes/source/clj/rum"}
-  posh                        {:local/root "/home/tienson/codes/projects/posh"}
+  rum                         {:mvn/version "0.11.4"}
   datascript-transit          {:mvn/version "0.3.0"}
   funcool/promesa             {:mvn/version "4.0.2"}
   medley                      {:mvn/version "1.2.0"}

File diff suppressed because it is too large
+ 0 - 0
web/public/static/js/manifest.edn


+ 58 - 58
web/src/frontend/components/agenda.cljs

@@ -50,68 +50,68 @@
       [:span
        name]])])
 
-(rum/defq agenda <
-  {:q (fn [state] (db/sub-agenda))}
-  [state tasks]
-  (sidebar/sidebar
-   [:div#agenda
-    [:h2.mb-3 "Agenda"]
-    (if (seq tasks)
-      [:div.ml-1
-       (let [parent-tasks (block/group-by-parent (block/sort-tasks tasks))]
-         (for [[parent tasks] parent-tasks]
-           (let [parent (cond
-                          (string? parent)
-                          parent
+(rum/defc agenda
+  []
+  (let [tasks (db/get-agenda)]
+    (sidebar/sidebar
+     [:div#agenda
+      [:h2.mb-3 "Agenda"]
+      (if (seq tasks)
+        [:div.ml-1
+         (let [parent-tasks (block/group-by-parent (block/sort-tasks tasks))]
+           (for [[parent tasks] parent-tasks]
+             (let [parent (cond
+                            (string? parent)
+                            parent
 
-                          (and (map? parent)
-                               (:label parent))
-                          (title-cp (:label parent))
+                            (and (map? parent)
+                                 (:label parent))
+                            (title-cp (:label parent))
 
-                          :else
-                          "uncategorized")]
-             [:div.mt-10
-              [:h4.mb-3.text-gray-500 parent]
-              (for [{:heading/keys [uuid marker title priority level tags children timestamps meta repo file] :as task} tasks]
-                [:div.mb-2
-                 {:key (str "task-" uuid)
-                  :style {:padding-left 8
-                          :padding-right 8}}
-                 [:div.column
-                  [:div.row {:style {:align-items "center"}}
-                   (case marker
-                     (list "DOING" "IN-PROGRESS" "TODO")
-                     (ui/checkbox {:on-change (fn [_]
-                                                ;; FIXME: Log timestamp
-                                                (handler/check repo file marker (:pos meta)))})
+                            :else
+                            "uncategorized")]
+               [:div.mt-10
+                [:h4.mb-3.text-gray-500 parent]
+                (for [{:heading/keys [uuid marker title priority level tags children timestamps meta repo file] :as task} tasks]
+                  [:div.mb-2
+                   {:key (str "task-" uuid)
+                    :style {:padding-left 8
+                            :padding-right 8}}
+                   [:div.column
+                    [:div.row {:style {:align-items "center"}}
+                     (case marker
+                       (list "DOING" "IN-PROGRESS" "TODO")
+                       (ui/checkbox {:on-change (fn [_]
+                                                  ;; FIXME: Log timestamp
+                                                  (handler/check task))})
 
-                     "WAIT"
-                     [:span {:style {:font-weight "bold"}}
-                      "WAIT"]
+                       "WAIT"
+                       [:span {:style {:font-weight "bold"}}
+                        "WAIT"]
 
-                     "DONE"
-                     (ui/checkbox {:checked true
-                                   :on-change (fn [_]
-                                                ;; FIXME: Log timestamp
-                                                (handler/uncheck repo file (:pos meta))
-                                                )})
+                       "DONE"
+                       (ui/checkbox {:checked true
+                                     :on-change (fn [_]
+                                                  ;; FIXME: Log timestamp
+                                                  (handler/uncheck task)
+                                                  )})
 
-                     nil)
-                   [:div.row.ml-2
-                    (if priority
-                      [:span.priority.mr-1
-                       (str "#[" priority "]")])
-                    (title-cp title)
-                    (marker-cp marker)
-                    (when (seq tags)
-                      (tags-cp tags))]]
-                  (when (seq timestamps)
-                    (timestamps-cp timestamps))
+                       nil)
+                     [:div.row.ml-2
+                      (if priority
+                        [:span.priority.mr-1
+                         (str "#[" priority "]")])
+                      (title-cp title)
+                      (marker-cp marker)
+                      (when (seq tags)
+                        (tags-cp tags))]]
+                    (when (seq timestamps)
+                      (timestamps-cp timestamps))
 
-                  ;; FIXME: parse error
-                  ;; (when (seq children)
-                  ;;   (children-cp children))
+                    ;; FIXME: parse error
+                    ;; (when (seq children)
+                    ;;   (children-cp children))
 
-                  ]]
-                )])))]
-      "Empty")]))
+                    ]]
+                  )])))]
+        "Empty")])))

+ 13 - 13
web/src/frontend/components/file.cljs

@@ -16,17 +16,15 @@
         decoded-path (b64/decodeString encoded-path)]
     [encoded-path decoded-path]))
 
-(rum/defq file <
-  {:q (fn [state]
-        (db/sub-file (last (get-path state))))
-   :did-mount (fn [state]
+(rum/defcs file <
+  {:did-mount (fn [state]
                 (doseq [block (-> (js/document.querySelectorAll "pre code")
                                   (array-seq))]
                   (js/hljs.highlightBlock block))
                 state)}
   [state content]
-  (let [[encoded-path path] (get-path state)
-        content (ffirst content)
+  (let [content (db/get-file (last (get-path state)))
+        [encoded-path path] (get-path state)
         suffix (last (string/split path #"\."))]
     (sidebar/sidebar
      (if (and suffix (contains? #{"md" "markdown" "org"} suffix))
@@ -42,21 +40,23 @@
   [s]
   (count (re-seq #"\n" (or s ""))))
 
-(rum/defq edit <
+(rum/defcs edit <
   (rum/local nil ::content)
   (rum/local "" ::commit-message)
-  {:q (fn [state]
-        (db/sub-file (last (get-path state))))}
-  [state initial-content]
-  (let [content (get state ::content)
+  {:will-mount (fn [state]
+                 (assoc state ::initial-content (db/get-file (last (get-path state)))))}
+  [state]
+  (let [initial-content (get state ::initial-content)
+        initial-rows (+ 3 (count-newlines initial-content))
+        content (get state ::content)
         commit-message (get state ::commit-message)
+        rows (if (nil? @content) initial-rows (+ 3 (count-newlines @content)))
         [_encoded-path path] (get-path state)]
     (sidebar/sidebar
      [:div#content
       [:h3.mb-2 (str "Update " path)]
       [:textarea
-       {:rows (+ 3 (count-newlines @content))
-        :style {:min-height 300}
+       {:rows rows
         :default-value initial-content
         :on-change #(reset! content (.. % -target -value))
         :auto-focus true}]

+ 4 - 5
web/src/frontend/components/home.cljs

@@ -70,13 +70,12 @@
         [:p.text-sm.text-gray-500.leading-tight
          "Author of Refactoring UI"]]]]]]])
 
-(rum/defq home < (rum/local false ::loading?)
+(rum/defc home <
   {:will-mount (fn [state]
                  (when-not (db/get-github-token)
                    (handler/get-github-access-token))
-                 state)
-   :q (fn [_state] (db/sub-github-token))}
-  [state {:keys [:github/token]}]
-  (if token
+                 state)}
+  [state]
+  (if (db/get-github-token)
     (sidebar/sidebar (sidebar/main-content))
     (front-page)))

+ 8 - 9
web/src/frontend/components/repo.cljs

@@ -8,15 +8,14 @@
 (defn repos
   [repos]
   (when (seq repos)
-    (let [repos (->> repos (map first) distinct)]
-      [:div#repos
-       [:ul
-        (for [url repos]
-          [:li {:key url}
-           [:button {:on-click (fn []
-                                 ;; (handler/set-current-repo url)
-                                 )}
-            (string/replace url "https://github.com/" "")]])]])))
+    [:div#repos
+     [:ul
+      (for [url repos]
+        [:li {:key url}
+         [:button {:on-click (fn []
+                               ;; (handler/set-current-repo url)
+                               )}
+          (string/replace url "https://github.com/" "")]])]]))
 
 (rum/defcs add-repo < (rum/local "https://github.com/" ::repo-url)
   [state]

+ 14 - 15
web/src/frontend/components/sidebar.cljs

@@ -26,19 +26,18 @@
          :stroke-linecap "round"}]]
       title])))
 
-(rum/defq files-list <
-  {:q (fn [] (db/sub-files))}
-  [state files file-active?]
-  [:div.cursor-pointer.my-1.flex.flex-col.ml-2
-   (if (seq files)
-     (let [files (->> files (map first))]
+(rum/defc files-list
+  [file-active?]
+  (let [files (db/get-files)]
+    [:div.cursor-pointer.my-1.flex.flex-col.ml-2
+     (if (seq files)
        (for [file files]
          (let [encoded-path (b64/encodeString file)]
            [:a {:key file
                 :class (util/hiccup->class "mt-1.group.flex.items-center.px-2.py-1.text-base.leading-6.font-medium.rounded-md.text-gray-500.hover:text-white.hover:bg-gray-700.focus:outline-none.focus:text-white.focus:bg-gray-700.transition.ease-in-out.duration-150")
                 :style {:color (if (file-active? encoded-path) "#FFF")}
                 :href (str "/file/" encoded-path)}
-            file]))))])
+            file])))]))
 
 (rum/defc sidebar-nav < rum/reactive
   []
@@ -55,14 +54,14 @@
                (active? :agenda))
      (files-list file-active?)]))
 
-(rum/defq main-content <
-  {:q (fn [_state] (db/sub-repos))}
-  [state repos]
-  [:div.max-w-7xl.mx-auto.px-4.sm:px-6.md:px-8
-   (if (seq repos)
-     [:div
-      (repo/repos repos)]
-     (repo/add-repo))])
+(rum/defc main-content
+  []
+  (let [repos (db/get-repos)]
+    [:div.max-w-7xl.mx-auto.px-4.sm:px-6.md:px-8
+    (if (seq repos)
+      [:div
+       (repo/repos repos)]
+      (repo/add-repo))]))
 
 (rum/defcs sidebar < (mixins/modal)
   [state main-content]

+ 95 - 102
web/src/frontend/db.cljs

@@ -2,8 +2,9 @@
   (:require [datascript.core :as d]
             [frontend.util :as util]
             [medley.core :as medley]
-            [posh.rum :as posh]
-            [datascript.transit :as dt]))
+            [datascript.transit :as dt]
+            [frontend.format.org-mode :as org]
+            [frontend.format.org.block :as block]))
 
 ;; TODO: don't persistent :github/token
 
@@ -46,9 +47,7 @@
    })
 
 (defonce conn
-  (let [conn (d/create-conn schema)]
-    (posh/posh! conn)
-    conn))
+  (d/create-conn schema))
 
 ;; transit serialization
 
@@ -65,15 +64,6 @@
 (defn reset-conn! [db]
   (reset! conn db))
 
-(d/listen! conn :persistence
-           (fn [tx-report] ;; FIXME do not notify with nil as db-report
-             ;; FIXME do not notify if tx-data is empty
-             (when-let [db (:db-after tx-report)]
-               (prn "DB changed")
-               (js/setTimeout (fn []
-                                (posh/posh! conn)
-                                (persist db)) 0))))
-
 ;; (new TextEncoder().encode('foo')).length
 (defn db-size
   []
@@ -175,6 +165,23 @@
         headings (mapv (fn [eid] [:db.fn/retractEntity eid]) headings)]
     (d/transact! conn headings)))
 
+(defn get-file-headings
+  [repo-url path]
+  (-> (d/q '[:find ?heading
+             :in $ ?repo-url ?path
+             :where
+             [?repo :repo/url ?repo-url]
+             [?file :file/path ?path]
+             [?heading :heading/file ?file]
+             [?heading :heading/repo ?repo]]
+        @conn repo-url path)
+      seq-flatten))
+
+(defn delete-file-headings!
+  [repo-url path]
+  (let [headings (get-file-headings repo-url path)]
+    (mapv (fn [eid] [:db.fn/retractEntity eid]) headings)))
+
 ;; transactions
 (defn reset-headings!
   [repo-url headings]
@@ -204,27 +211,9 @@
            [(?pred $ ?tags)]]
       @conn pred)))
 
-(comment
-  (frontend.handler/initial-db!)
-  )
-
-(defn pull
-  [selector eid]
-  (posh/pull conn selector eid))
-
-(defn pull-many
-  ([eids]
-   (pull-many '[*] eids))
-  ([selector eids]
-   (posh/pull-many conn selector eids)))
-
-(defn q
-  [query & inputs]
-  (apply posh/q query inputs))
-
 (defn transact!
   [tx-data]
-  (posh/transact! conn tx-data))
+  (d/transact! conn tx-data))
 
 (defn set-key-value
   [key value]
@@ -241,10 +230,6 @@
   (some-> (d/entity (d/db conn) key)
           key))
 
-(defn sub-github-token
-  []
-  (pull '[*] [:db/ident :github/token]))
-
 (defn get-github-token
   []
   (get-key-value :github/token))
@@ -253,20 +238,10 @@
   [repo]
   (set-key-value :repo/current [:repo/url repo]))
 
-(defn sub-current-repo
-  []
-  (pull '[*] [:db/ident :repo/current]))
-
 (defn get-current-repo
   []
   (:repo/url (get-key-value :repo/current)))
 
-(defn sub-repos
-  []
-  (q '[:find ?url
-       :where [_ :repo/url ?url]]
-    conn))
-
 (defn get-repos
   []
   (->> (d/q '[:find ?url
@@ -275,14 +250,16 @@
        (map first)
        distinct))
 
-(defn sub-files
+(defn get-files
   []
-  (q '[:find ?path
-       :where
-       [_     :repo/current ?repo]
-       [?file :file/repo ?repo]
-       [?file :file/path ?path]]
-    conn))
+  (->> (d/q '[:find ?path
+              :where
+              [_     :repo/current ?repo]
+              [?file :file/repo ?repo]
+              [?file :file/path ?path]]
+         @conn)
+       (map first)
+       distinct))
 
 (defn set-repo-cloning
   [repo-url value]
@@ -323,6 +300,48 @@
       :file/path file
       :file/content content}]))
 
+(defn extract-headings
+  [repo-url file content]
+  (let [headings (-> content
+                     (org/parse-json)
+                     (util/json->clj))
+        headings (block/extract-headings headings)]
+    (map (fn [heading]
+           (assoc heading
+                  :heading/repo [:repo/url repo-url]
+                  :heading/file [:file/path file]))
+      headings)))
+
+(defn get-all-files-content
+  [repo-url]
+  (d/q '[:find ?path ?content
+         :in $ ?repo-url
+         :where
+         [?repo :repo/url ?repo-url]
+         [?file :file/repo ?repo]
+         [?file :file/content ?content]
+         [?file :file/path ?path]]
+    @conn repo-url))
+
+(defn extract-all-headings
+  [repo-url]
+  (let [contents (get-all-files-content repo-url)]
+    (vec
+     (mapcat
+      (fn [[file content] contents]
+        (extract-headings repo-url file content))
+      contents))))
+
+(defn reset-file!
+  [repo-url file content]
+  (let [file-content [{:file/repo [:repo/url repo-url]
+                       :file/path file
+                       :file/content content}]
+        delete-headings (delete-file-headings! repo-url file)
+        headings (extract-headings repo-url file content)
+        headings (safe-headings headings)]
+    (d/transact! conn (concat file-content delete-headings headings))))
+
 (defn get-file-content
   [repo-url path]
   (->> (d/q '[:find ?content
@@ -331,55 +350,27 @@
               [?repo :repo/url ?repo-url]
               [?file :file/repo ?repo]
               [?file :file/path ?path]
-              [?file :file/content ?content]
-              ]
+              [?file :file/content ?content]]
          @conn repo-url path)
        (map first)
        first))
 
-(defn sub-file
+(defn get-file
   [path]
-  (q '[:find ?content
-       :in $ ?path
-       :where
-       [_     :repo/current ?repo]
-       [?file :file/repo ?repo]
-       [?file :file/path ?path]
-       [?file :file/content ?content]]
-    conn
-    path))
-
-(defn get-all-files-content
-  [repo-url]
-  (d/q '[:find ?path ?content
-         :in $ ?repo-url
-         :where
-         [?repo :repo/url ?repo-url]
-         [?file :file/repo ?repo]
-         [?file :file/content ?content]
-         [?file :file/path ?path]]
-    @conn repo-url))
+  (->
+   (d/q '[:find ?content
+          :in $ ?path
+          :where
+          [_     :repo/current ?repo]
+          [?file :file/repo ?repo]
+          [?file :file/path ?path]
+          [?file :file/content ?content]]
+     @conn
+     path)
+   ffirst))
 
 ;; marker should be one of: TODO, DOING, IN-PROGRESS
 ;; time duration
-(defn sub-agenda
-  ([]
-   (sub-agenda :week))
-  ([time]
-   (let [duration (case time
-                    :today []
-                    :week  []
-                    :month [])
-         tasks-ids (-> @(q '[:find ?h
-                             :where
-                             (or [?h :heading/marker "TODO"]
-                                 [?h :heading/marker "DOING"]
-                                 [?h :heading/marker "IN-PROGRESS"]
-                                 [?h :heading/marker "DONE"])]
-                          conn)
-                       seq-flatten)]
-     (pull-many tasks-ids))))
-
 (defn get-agenda
   ([]
    (get-agenda :week))
@@ -388,13 +379,15 @@
                     :today []
                     :week  []
                     :month [])]
-     (d/q '[:find (pull ?h [*])
-            :where
-            (or [?h :heading/marker "TODO"]
-                [?h :heading/marker "DOING"]
-                [?h :heading/marker "IN-PROGRESS"]
-                [?h :heading/marker "DONE"])]
-       @conn))))
+     (->
+      (d/q '[:find (pull ?h [*])
+             :where
+             (or [?h :heading/marker "TODO"]
+                 [?h :heading/marker "DOING"]
+                 [?h :heading/marker "IN-PROGRESS"]
+                 [?h :heading/marker "DONE"])]
+        @conn)
+      seq-flatten))))
 
 (defn entity
   [id-or-lookup-ref]

+ 10 - 2
web/src/frontend/format/org/block.cljs

@@ -95,11 +95,19 @@
                   m2 (get markers (:heading/marker t2) 0)
                   p1 (get priorities (:heading/priority t1) 0)
                   p2 (get priorities (:heading/priority t2) 0)]
-              (if (= m1 m2)
+              (cond
+                (and (= m1 m2)
+                     (= p1 p2))
+                (compare (:heading/title t1) (:heading/title t2))
+
+                (= m1 m2)
                 (> p1 p2)
+                :else
                 (> m1 m2))))
           headings)))
 
 (defn group-by-parent
   [headings]
-  (group-by :heading/parent-title headings))
+  (->> (group-by :heading/parent-title headings)
+       (into (sorted-map-by (fn [x y]
+                              (compare (str x) (str y)))))))

+ 1 - 0
web/src/frontend/git.cljs

@@ -62,6 +62,7 @@
                {:dir (get-repo-dir repo-url)
                 :filepath file})))
 
+;; TODO: cache email and name
 (defn commit
   [repo-url message]
   (js/git.commit (clj->js

+ 70 - 66
web/src/frontend/handler.cljs

@@ -6,8 +6,6 @@
             [frontend.db :as db]
             [frontend.storage :as storage]
             [frontend.util :as util]
-            [frontend.format.org-mode :as org]
-            [frontend.format.org.block :as block]
             [frontend.config :as config]
             [clojure.walk :as walk]
             [clojure.string :as string]
@@ -15,7 +13,9 @@
             [cljs-bean.core :as bean]
             [reitit.frontend.easy :as rfe]
             [goog.crypt.base64 :as b64]
-            [goog.object :as gobj])
+            [goog.object :as gobj]
+            [rum.core :as rum]
+            [datascript.core :as d])
   (:import [goog.events EventHandler]))
 
 ;; We only support Github token now
@@ -69,21 +69,24 @@
 ;; TODO: callback hell
 (defn pull
   [repo-url token]
-  (util/p-handle (git/pull repo-url token)
-                 (fn [result]
-                   (get-latest-commit
-                    (fn [commit]
-                      (when (or (nil? @latest-commit)
-                                (and @latest-commit
-                                     commit
-                                     (not= (gobj/get commit "oid")
-                                           (gobj/get @latest-commit "oid"))))
-                        (prn "New commit oid: " (gobj/get commit "oid"))
-                        (-> (load-files repo-url)
-                            (p/then
-                             (fn []
-                               (load-repo-to-db! repo-url)))))
-                      (reset! latest-commit commit))))))
+  (prn "pushing? " (:pushing? @state/state))
+  (when-not (:pushing? @state/state)
+    (util/p-handle
+     (git/pull repo-url token)
+     (fn [result]
+       (get-latest-commit
+        (fn [commit]
+          (when (or (nil? @latest-commit)
+                    (and @latest-commit
+                         commit
+                         (not= (gobj/get commit "oid")
+                               (gobj/get @latest-commit "oid"))))
+            (prn "New commit oid: " (gobj/get commit "oid"))
+            (-> (load-files repo-url)
+                (p/then
+                 (fn []
+                   (load-repo-to-db! repo-url)))))
+          (reset! latest-commit commit)))))))
 
 (defn periodically-pull
   [repo-url]
@@ -92,23 +95,10 @@
     (js/setInterval #(pull repo-url token)
                     (* 10 1000))))
 
-(defn add-transaction
-  [tx]
-  (swap! state/state update :tasks-transactions conj tx))
-
-(defn clear-transactions!
-  []
-  (swap! state/state assoc :tasks-transactions nil))
-
-(defn- transactions->commit-msg
-  [transactions]
-  (let [transactions (reverse transactions)]
-    (str
-     "Gitnotes auto save tasks.\n\n"
-     (string/join "\n" transactions))))
-
+;; TODO: update latest commit
 (defn push
   [repo-url file message]
+  (swap! state/state assoc :pushing? true)
   (let [token (db/get-github-token)]
     (git/add-commit-push
      repo-url
@@ -116,9 +106,11 @@
      message
      token
      (fn []
-       (prn "Push successfully!"))
+       (prn "Push successfully!")
+       (swap! state/state assoc :pushing? false))
      (fn []
-       (prn "Failed to push.")))))
+       (prn "Failed to push.")
+       (swap! state/state assoc :pushing? false)))))
 
 (defn clone
   [repo]
@@ -196,14 +188,16 @@
     (util/p-handle
      (fs/write-file (git/get-repo-dir repo-url) path content)
      (fn [_]
+       (rfe/push-state :file {:path (b64/encodeString path)})
+       (db/reset-file! repo-url path content)
+
        (git/add-commit-push repo-url
                             path
                             commit-message
                             token
                             (fn []
-                              (db/set-file-content! repo-url path content)
-                              (rfe/push-state :file {:path (b64/encodeString path)})
-                              (show-notification! "File updated!"))
+                              ;; (show-notification! "File updated!")
+                              )
                             (fn [error]
                               (prn "Failed to update file, error: " error)))))))
 
@@ -213,8 +207,10 @@
   (clone repo-url))
 
 (defn check
-  [repo file marker pos]
-  (let [repo (db/entity (:db/id repo))
+  [heading]
+  (let [{:heading/keys [repo file marker meta uuid]} heading
+        pos (:pos meta)
+        repo (db/entity (:db/id repo))
         file (db/entity (:db/id file))
         repo-url (:repo/url repo)
         file (:file/path file)
@@ -223,15 +219,18 @@
       (let [content' (str (subs content 0 pos)
                           (-> (subs content pos)
                               (string/replace-first marker "DONE")))]
-        (db/set-file-content! repo-url file content')
         (util/p-handle
          (fs/write-file (git/get-repo-dir repo-url) file content')
          (fn [_]
+           (prn "check successfully, " file)
+           (db/reset-file! repo-url file content')
            (push repo-url file (util/format "`%s` marked as DONE." marker))))))))
 
 (defn uncheck
-  [repo file pos]
-  (let [repo (db/entity (:db/id repo))
+  [heading]
+  (let [{:heading/keys [repo file marker meta]} heading
+        pos (:pos meta)
+        repo (db/entity (:db/id repo))
         file (db/entity (:db/id file))
         repo-url (:repo/url repo)
         file (:file/path file)
@@ -240,24 +239,13 @@
       (let [content' (str (subs content 0 pos)
                           (-> (subs content pos)
                               (string/replace-first "DONE" "TODO")))]
-        (db/set-file-content! repo-url file content')
         (util/p-handle
          (fs/write-file (git/get-repo-dir repo-url) file content')
          (fn [_]
+           (prn "uncheck successfully, " file)
+           (db/reset-file! repo-url file content')
            (push repo-url file "DONE rollbacks to TODO.")))))))
 
-(defn extract-headings
-  [repo-url file content]
-  (let [headings (-> content
-                     (org/parse-json)
-                     (util/json->clj))
-        headings (block/extract-headings headings)]
-    (map (fn [heading]
-           (assoc heading
-                  :heading/repo [:repo/url repo-url]
-                  :heading/file [:file/path file]))
-      headings)))
-
 (defn load-all-contents!
   [repo-url ok-handler]
   (let [files (db/get-repo-files repo-url)]
@@ -269,22 +257,13 @@
          (fn [_]
            (ok-handler))))))
 
-(defn extract-all-headings
-  [repo-url]
-  (let [contents (db/get-all-files-content repo-url)]
-    (vec
-     (mapcat
-      (fn [[file content] contents]
-        (extract-headings repo-url file content))
-      contents))))
-
 (defonce headings-atom (atom nil))
 
 (defn load-repo-to-db!
   [repo-url]
   (load-all-contents! repo-url
                       (fn []
-                        (let [headings (extract-all-headings repo-url)]
+                        (let [headings (db/extract-all-headings repo-url)]
                           (reset! headings-atom headings)
                           (db/reset-headings! repo-url headings)))))
 
@@ -326,9 +305,34 @@
   [route]
   (swap! state/state assoc :route-match route))
 
+(defn set-ref-component!
+  [k ref]
+  (swap! state/state assoc :ref-components k ref))
+
+(defn set-root-component!
+  [comp]
+  (swap! state/state assoc :root-component comp))
+
+(defn re-render!
+  []
+  (when-let [comp (get @state/state :root-component)]
+    (rum/request-render comp)))
+
+(defn db-listen-to-tx!
+  []
+  (d/listen! db/conn :persistence
+             (fn [tx-report] ;; FIXME do not notify with nil as db-report
+               ;; FIXME do not notify if tx-data is empty
+               (when-let [db (:db-after tx-report)]
+                 (prn "DB changed, re-rendered!")
+                 (re-render!)
+                 (js/setTimeout (fn []
+                                  (db/persist db)) 0)))))
+
 (defn start!
   []
   (db/restore!)
+  (db-listen-to-tx!)
   (when-let [first-repo (first (db/get-repos))]
     (db/set-current-repo! first-repo))
   (let [repos (db/get-repos)]

+ 7 - 2
web/src/frontend/page.cljs

@@ -1,11 +1,16 @@
 (ns frontend.page
   (:require [rum.core :as rum]
-            [frontend.state :as state]))
+            [frontend.state :as state]
+            [frontend.handler :as handler]))
 
 (rum/defc current-page < rum/reactive
+  {:did-mount (fn [state]
+                (handler/set-root-component! (:rum/react-component state))
+                state)}
   []
   (let [state (rum/react state/state)
         route-match (:route-match state)]
     (if route-match
       (when-let [view (:view (:data route-match))]
-        (view route-match)))))
+        (view route-match))
+      [:div "404 Page"])))

+ 0 - 4
web/src/frontend/posh.cljs

@@ -1,4 +0,0 @@
-(ns frontend.posh
-  (:require [posh.core :as posh]))
-
-;; experiment

+ 2 - 1
web/src/frontend/state.cljs

@@ -5,4 +5,5 @@
             {:route-match nil
              :notification/show? false
              :notification/text nil
-             :tasks-transactions nil}))
+             :root-component nil
+             :pushing? false}))

Some files were not shown because too many files changed in this diff