diff --git a/web/src/main/frontend/components/content.cljs b/web/src/main/frontend/components/content.cljs index 5944c0f7b..7fbdb9003 100644 --- a/web/src/main/frontend/components/content.cljs +++ b/web/src/main/frontend/components/content.cljs @@ -49,7 +49,7 @@ (ui/textarea {:id "edit-box" :on-change (fn [e] - (reset! state/edit-content (util/evalue e))) + (handler/set-edit-content! (util/evalue e))) :initial-value content :value-atom state/edit-content :auto-focus true @@ -110,25 +110,27 @@ content on-click on-hide]}] - (let [{:keys [edit? format/loading]} (rum/react state/state)] - (if edit? + (let [{:keys [edit? edit-id format/loading edit-journal edit-file]} (rum/react state/state) + edit-id (rum/react state/edit-id)] + (if (and edit? (= id edit-id)) (editor-box content {:on-hide on-hide}) (let [format (format/normalize format) loading? (get loading format) - html (if-not (string/blank? html) html (format/to-html content format config)) markup? (contains? handler/html-render-formats format) on-click (fn [e] (when-not (node-link? (gobj/get e "target")) - (handler/reset-cursor-range! (gdom/getElement id)) - (if on-click + (reset! state/edit-id id) + (handler/reset-cursor-range! (gdom/getElement (str id))) + (when on-click (on-click)) - (reset! state/edit-content content)))] + (handler/set-edit-content! content)))] (cond (and markup? loading?) [:div "loading ..."] markup? - (let [html (if html html "")] + (let [html (if-not (string/blank? html) html (format/to-html content format config)) + html (if html html "")] [:div {:id id :on-click on-click @@ -137,6 +139,5 @@ :else ; other text formats [:div.pre-white-space {:id id - :content-editable true :on-click on-click} content]))))) diff --git a/web/src/main/frontend/components/journal.cljs b/web/src/main/frontend/components/journal.cljs index b49c57802..1c3044ccc 100644 --- a/web/src/main/frontend/components/journal.cljs +++ b/web/src/main/frontend/components/journal.cljs @@ -4,61 +4,9 @@ [frontend.handler :as handler] [clojure.string :as string] [frontend.ui :as ui] - [frontend.mixins :as mixins] - [frontend.db :as db] [frontend.state :as state :refer [edit-content]] - [frontend.format.org-mode :as org] - [frontend.format :as format] - [goog.object :as gobj] - [goog.dom :as gdom] - [frontend.image :as image] [frontend.components.content :as content])) -(rum/defc editor-box < - (mixins/event-mixin - (fn [state] - (let [heading (first (:rum/args state))] - (mixins/hide-when-esc-or-outside - state - nil - :show-fn (fn [] - (:edit? @state/state)) - :on-hide (fn [] - (handler/save-current-edit-journal! (str heading "\n" (string/trimr @edit-content) "\n\n"))))))) - {:did-mount (fn [state] - (when-let [content (second (:rum/args state))] - (handler/restore-cursor-pos! content)) - state)} - [heading content] - [:div.flex-1 - (ui/textarea - {:id "edit-box" - :on-change (fn [e] - (reset! edit-content (util/evalue e))) - :initial-value content - :value-atom edit-content - :auto-focus true - :style {:border "none" - :border-radius 0 - :background "transparent" - :margin-top 12.5} - :on-key-down handler/reset-cursor-pos! - :on-click handler/reset-cursor-pos!}) - [:input - {:id "files" - :type "file" - :on-change (fn [e] - (let [files (.-files (.-target e))] - (image/upload - files - (fn [file file-name file-type] - (handler/request-presigned-url - file file-name file-type - (fn [signed-url] - ;; insert into the text - (handler/insert-image! signed-url))))))) - :hidden true}]]) - (defn split-first [re s] (clojure.string/split s re 2)) @@ -73,23 +21,20 @@ (rum/defc journal-cp < rum/reactive [{:keys [uuid title content] :as journal}] (let [{:keys [edit? edit-journal]} (rum/react state/state) - [heading content] (split-heading-body content)] + [heading content] (split-heading-body content) + id uuid] [:div.flex-1 [:h1.text-gray-600 {:style {:font-weight "450"}} title] - (if (and edit? (= uuid (:uuid edit-journal))) - (editor-box heading content) - (let [id (str "journal-" uuid) - html (-> (format/to-html content "org" org/config-with-line-break) - (util/minimize-html))] - [:div - {:id id - :content-editable true - :on-click (fn [_e] - (handler/reset-cursor-range! (gdom/getElement id)) - (handler/edit-journal! journal) - (reset! edit-content content)) - :dangerouslySetInnerHTML {:__html html}}]))])) + (content/content id + nil + :org + {:content content + :on-click (fn [] + (handler/edit-journal! journal)) + :on-hide (fn [] + (prn content (str heading "\n" (string/trimr @edit-content) "\n\n")) + (handler/save-current-edit-journal! (str heading "\n" (string/trimr @edit-content) "\n\n")))})])) (rum/defc journals < rum/reactive [latest-journals] diff --git a/web/src/main/frontend/core.cljs b/web/src/main/frontend/core.cljs index 99d303c47..f45a9c23e 100644 --- a/web/src/main/frontend/core.cljs +++ b/web/src/main/frontend/core.cljs @@ -3,11 +3,15 @@ [frontend.handler :as handler] [frontend.page :as page] [frontend.routes :as routes] + [frontend.util :as util] [reitit.frontend :as rf] [reitit.frontend.easy :as rfe])) (defn set-router! [] + (when-let [fragment (util/get-fragment)] + (util/scroll-to-element fragment)) + (rfe/start! (rf/router routes/routes {}) handler/set-route-match! diff --git a/web/src/main/frontend/db.cljs b/web/src/main/frontend/db.cljs index b82ba8131..98a9a8ba0 100644 --- a/web/src/main/frontend/db.cljs +++ b/web/src/main/frontend/db.cljs @@ -531,9 +531,10 @@ (defn me-tx [db {:keys [name email avatar repos]}] - (let [me-tx [{:me/name name - :me/email email - :me/avatar avatar}] + (let [me (util/remove-nils {:me/name name + :me/email email + :me/avatar avatar}) + me-tx [me] repos-tx (mapv (fn [repo] {:repo/url (:url repo)}) repos) diff --git a/web/src/main/frontend/expand.cljs b/web/src/main/frontend/expand.cljs index 479de0442..4e8312262 100644 --- a/web/src/main/frontend/expand.cljs +++ b/web/src/main/frontend/expand.cljs @@ -61,6 +61,28 @@ (drop-last nodes) nodes))) +(defn get-heading-non-heading-children + [all-nodes heading] + (let [heading-id (gobj/get heading "id") + heading-tag-name (gobj/get heading "tagName") + control? (fn [node] + (d/has-class? node "control")) + level (get-level heading-tag-name) + nodes (->> all-nodes + ;; drop preceding nodes + (drop-while (fn [node] + (not= heading-id (gobj/get node "id")))) + ;; drop self + (next) + ;; take the children + (take-while (fn [node] + (let [tag-name (gobj/get node "tagName")] + (not (heading? node))))))] + (if (and (last nodes) + (control? (last nodes))) + (drop-last nodes) + nodes))) + (defn collapse! [all-nodes id] (when-let [node (gdom/getElement id)] @@ -131,45 +153,64 @@ (let [all-nodes (get-content-children) headings (get-all-headings)] (doseq [heading headings] - (when-let [heading-children (seq (get-heading-children all-nodes heading))] - (indent-non-headings! heading heading-children) - (let [id (gobj/get heading "id") - control-id (str "control-" id) - element (d/create-element "a") - mouseover (fn [e] - (when (and - (not (d/has-class? element "caret-down")) - (not (d/has-class? element "caret-right"))) - (d/add-class! element "caret-down"))) - mouseout (fn [e] - (d/remove-class! element "caret-down"))] - (when-let [old-node (gdom/getElement control-id)] - (d/remove! old-node)) - (d/set-style! heading - :position "relative") - (d/set-attr! element - :id control-id - :class "control block no-underline text-gray-700 hover:bg-gray-100 transition ease-in-out duration-150") - (d/set-style! element - :position "absolute" - :top 0 - :left "-20px") - (d/listen! heading :mouseover mouseover) - (d/listen! heading :mouseout mouseout) - (d/listen! element :mouseover mouseover) - (d/listen! element :mouseout mouseout) - (d/listen! element - :click (fn [e] - (if (d/has-class? element "caret-down") - (do - (d/remove-class! element "caret-down") - (d/add-class! element "caret-right") - (collapse! all-nodes id)) - (do - (d/remove-class! element "caret-right") - (d/add-class! element "caret-down") - (expand! all-nodes id))))) - (d/prepend! heading element)))))) + (let [heading-parent (d/parent heading)] + (when-let [heading-children (seq (get-heading-children all-nodes heading))] + (indent-non-headings! heading heading-children) + (let [id (gobj/get heading "id") + control-id (str "control-" id) + element (d/create-element "a") + mouseover (fn [e] + (when (and + (not (d/has-class? element "caret-down")) + (not (d/has-class? element "caret-right"))) + (d/add-class! element "caret-down"))) + mouseout (fn [e] + (d/remove-class! element "caret-down"))] + (when-let [old-node (gdom/getElement control-id)] + (d/remove! old-node)) + (d/set-style! heading + :position "relative") + (d/set-attr! element + :id control-id + :class "control block no-underline text-gray-700 hover:bg-gray-100 transition ease-in-out duration-150") + (d/set-style! element + :position "absolute" + :top 0 + :left "-20px") + (d/listen! heading :mouseover mouseover) + (d/listen! heading :mouseout mouseout) + (d/listen! element :mouseover mouseover) + (d/listen! element :mouseout mouseout) + (d/listen! element + :click (fn [e] + (if (d/has-class? element "caret-down") + (do + (d/remove-class! element "caret-down") + (d/add-class! element "caret-right") + (collapse! all-nodes id)) + (do + (d/remove-class! element "caret-right") + (d/add-class! element "caret-down") + (expand! all-nodes id))))) + ;; create a div wrapper + ;; (let [wrapper (d/create-element "div") + ;; non-heading-children (get-heading-non-heading-children all-nodes heading)] + ;; ;; (d/replace! heading wrapper) + ;; ;; (prn "remove " ) + ;; ;; (js/console.dir heading) + ;; (d/set-class! wrapper "heading-group") + ;; (d/remove! heading) + ;; (doseq [child non-heading-children] + ;; (d/remove! child)) + ;; (apply d/append! wrapper + ;; element + ;; heading + ;; non-heading-children) + ;; (d/append! heading-parent wrapper) + ;; ) + + (d/prepend! heading element) + )))))) (comment (def all-nodes (get-content-children)) diff --git a/web/src/main/frontend/handler.cljs b/web/src/main/frontend/handler.cljs index cf231cfd1..d2d7b0fc5 100644 --- a/web/src/main/frontend/handler.cljs +++ b/web/src/main/frontend/handler.cljs @@ -236,7 +236,6 @@ (when (and (not (:edit? @state/state)) (nil? (:git/error @state/state)) - (not= status ) (or (nil? status) (= status :pulling))) (set-git-status! :pulling) @@ -695,13 +694,18 @@ (when-let [node (gdom/getElement "edit-box")] (when-let [range (string/trim @state/cursor-range)] (let [pos (inc (diff/find-position markup range))] - (println "Edit position: " pos) (util/set-caret-pos! node pos))))) (defn set-edit-node! [ref] (reset! state/edit-node ref)) +(defn set-edit-content! + [content] + (prn "set edit content: " + content) + (reset! state/edit-content content)) + (defn move-cursor-to-end [input] (let [n (count (.-value input))] (set! (.-selectionStart input) n) diff --git a/web/src/main/frontend/state.cljs b/web/src/main/frontend/state.cljs index 593d1c6c1..d8822fd2a 100644 --- a/web/src/main/frontend/state.cljs +++ b/web/src/main/frontend/state.cljs @@ -19,11 +19,12 @@ ;; format => boolean :format/loading {} :search/result nil - :edit/journal nil - :edit/file nil})) + :edit-journal nil + :edit-file nil})) ;; TODO: add to global state (def edit-node (atom nil)) +(def edit-id (atom nil)) (def edit-content (atom "")) (def cursor-range (atom nil)) (def cursor-pos (atom nil)) diff --git a/web/src/main/frontend/util.cljs b/web/src/main/frontend/util.cljs index bc5fbdd85..9a7ee8899 100644 --- a/web/src/main/frontend/util.cljs +++ b/web/src/main/frontend/util.cljs @@ -231,10 +231,15 @@ (defn scroll-into-view [element] (let [scroll-top (gobj/get element "offsetTop") - scroll-top (- scroll-top 80)] + scroll-top (if (zero? scroll-top) + (-> (gobj/get element "parentElement") + (gobj/get "offsetTop")) + scroll-top)] + (when-let [main (first (array-seq (gdom/getElementsByTagName "main")))] (.scroll main #js {:top scroll-top - :behavior "smooth"})))) + ;; :behavior "smooth" + })))) (defn scroll-to-element [fragment]