Просмотр исходного кода

refactor: unify heading UX for both markdown and org mode

Tienson Qin 3 лет назад
Родитель
Сommit
8b144269f7

+ 0 - 4
deps/db/src/logseq/db/schema.cljs

@@ -62,9 +62,6 @@
    ;; first block that's not a heading or unordered list
    :block/pre-block? {}
 
-   ;; heading's level (the block must be a heading)
-   :block/heading-level {}
-
    ;; scheduled day
    :block/scheduled {}
 
@@ -116,7 +113,6 @@
     :block/deadline
     :block/repeated?
     :block/pre-block?
-    :block/heading-level
     :block/type
     :block/properties
     :block/properties-order

+ 19 - 10
deps/graph-parser/src/logseq/graph_parser/block.cljs

@@ -541,6 +541,16 @@
                  blocks)]
     (with-path-refs blocks)))
 
+(defn- with-heading-property
+  [properties markdown-heading? size]
+  (let [properties (if markdown-heading?
+                     (assoc properties :heading size)
+                     properties)]
+    (if (true? (:heading properties))
+      ;; default-level 2
+      (assoc properties :heading 2)
+      properties)))
+
 (defn- construct-block
   [block properties timestamps body encoded-content format pos-meta with-id? {:keys [block-pattern supported-formats db date-formatter]}]
   (let [id (get-custom-id-or-new-id properties)
@@ -551,18 +561,17 @@
         markdown-heading? (and (:size block) (= :markdown format))
         block (if markdown-heading?
                 (assoc block
-                       :type :heading
-                       :level (if unordered? (:level block) 1)
-                       :heading-level (or (:size block) 6))
+                       :level (if unordered? (:level block) 1))
                 block)
         block (cond->
-                (assoc block
-                       :uuid id
-                       :refs ref-pages-in-properties
-                       :format format
-                       :meta pos-meta)
-                (seq (:properties properties))
-                (assoc :properties (:properties properties)
+                (-> (assoc block
+                           :uuid id
+                           :refs ref-pages-in-properties
+                           :format format
+                           :meta pos-meta)
+                    (dissoc :size))
+                (or (seq (:properties properties)) markdown-heading?)
+                (assoc :properties (with-heading-property (:properties properties) markdown-heading? (:size block))
                        :properties-text-values (:properties-text-values properties)
                        :properties-order (vec (:properties-order properties)))
 

+ 1 - 2
deps/graph-parser/src/logseq/graph_parser/test/docs_graph_helper.cljs

@@ -115,10 +115,9 @@
             :block/priority 4
             :block/deadline 1
             :block/collapsed? 22
-            :block/heading-level 60
             :block/repeated? 1}
            (->> [:block/scheduled :block/priority :block/deadline :block/collapsed?
-                 :block/heading-level :block/repeated?]
+                 :block/repeated?]
                 (map (fn [attr]
                        [attr
                         (ffirst (d/q [:find (list 'count '?b) :where ['?b attr]]

+ 29 - 17
src/main/frontend/commands.cljs

@@ -132,13 +132,11 @@
    [:editor/set-heading heading]
    [:editor/move-cursor-to-end]])
 
-(defn- markdown-headings
+(defn- headings
   []
-  (let [format (state/get-preferred-format)]
-    (when (= (name format) "markdown")
-      (mapv (fn [level]
-              (let [heading (str "h" level)]
-                [heading (->heading (apply str (repeat level "#")))])) (range 1 7)))))
+  (mapv (fn [level]
+          (let [heading (str "h" level)]
+            [heading (->heading level)])) (range 1 7)))
 
 (defonce *matched-commands (atom nil))
 (defonce *initial-commands (atom nil))
@@ -241,7 +239,7 @@
        ;; ["Upload an image" [[:editor/click-hidden-file-input :id]]]
        )]
 
-    (markdown-headings)
+    (headings)
 
     ;; time & date
 
@@ -593,19 +591,33 @@
         (property/goto-properties-end format current-input)
         (cursor/move-cursor-backward current-input 3)))))
 
+(defonce markdown-heading-pattern #"^#+\s+")
+(defn set-markdown-heading
+  [content heading]
+  (let [heading-str (apply str (repeat heading "#"))]
+    (if (util/safe-re-find markdown-heading-pattern content)
+      (string/replace-first content
+                            markdown-heading-pattern
+                            (str heading-str " "))
+      (str heading-str " " (string/triml content)))))
+
+(defn clear-markdown-heading
+  [content]
+  [:pre (string? content)]
+  (string/replace-first content
+                        markdown-heading-pattern
+                        ""))
+
 (defmethod handle-step :editor/set-heading [[_ heading]]
   (when-let [input-id (state/get-edit-input-id)]
     (when-let [current-input (gdom/getElement input-id)]
-      (let [edit-content (gobj/get current-input "value")
-            heading-pattern #"^#+\s+"
-            new-value (cond
-                        (util/safe-re-find heading-pattern edit-content)
-                        (string/replace-first edit-content
-                                              heading-pattern
-                                              (str heading " "))
-                        :else
-                        (str heading " " (string/triml edit-content)))]
-        (state/set-edit-content! input-id new-value)))))
+      (let [current-block (state/get-edit-block)
+            format (:block/format current-block)]
+        (if (= format :markdown)
+          (let [edit-content (gobj/get current-input "value")
+                new-content (set-markdown-heading edit-content heading)]
+            (state/set-edit-content! input-id new-content))
+          (state/pub-event! [:editor/set-org-mode-heading current-block heading]))))))
 
 (defmethod handle-step :editor/search-page [[_]]
   (state/set-editor-action! :page-search))

+ 8 - 14
src/main/frontend/components/block.cljs

@@ -1839,7 +1839,7 @@
 (declare block-content)
 
 (defn build-block-title
-  [config {:block/keys [title marker pre-block? properties level heading-level]
+  [config {:block/keys [title marker pre-block? properties]
            :as t}]
   (let [config (assoc config :block t)
         slide? (boolean (:slide? config))
@@ -1856,14 +1856,9 @@
         priority (priority-cp t)
         tags (block-tags-cp t)
         bg-color (:background-color properties)
-        heading-level (or (and heading-level
-                               (<= heading-level 6)
-                               heading-level)
-                          (and (get properties :heading)
-                               (<= level 6)
-                               level))
-        elem (if heading-level
-               (keyword (str "h" heading-level
+        heading (:heading properties)
+        elem (if heading
+               (keyword (str "h" heading
                              (when block-ref? ".inline")))
                :span.inline)]
     (->elem
@@ -2289,7 +2284,7 @@
 
 (rum/defcs block-content-or-editor < rum/reactive
   (rum/local true ::hide-block-refs?)
-  [state config {:block/keys [uuid format] :as block} edit-input-id block-id heading-level edit?]
+  [state config {:block/keys [uuid format] :as block} edit-input-id block-id edit?]
   (let [*hide-block-refs? (get state ::hide-block-refs?)
         hide-block-refs? @*hide-block-refs?
         editor-box (get config :editor-box)
@@ -2307,7 +2302,6 @@
                      :block-id uuid
                      :block-parent-id block-id
                      :format format
-                     :heading-level heading-level
                      :on-hide (fn [value event]
                                 (when (= event :esc)
                                   (editor-handler/save-block! (editor-handler/get-state) value)
@@ -2574,7 +2568,7 @@
         block (if ref?
                 (merge block (db/pull-block (:db/id block)))
                 block)
-        {:block/keys [uuid children pre-block? top? refs heading-level level format content properties]} block
+        {:block/keys [uuid children pre-block? top? refs level format content properties]} block
         config (if navigated? (assoc config :id (str navigating-block)) config)
         block (merge block (block/parse-title-and-body uuid format pre-block? content))
         blocks-container-id (:blocks-container-id config)
@@ -2583,7 +2577,7 @@
         config (if (nil? (:query-result config))
                  (assoc config :query-result (atom nil))
                  config)
-        heading? (or (:heading properties) (and heading-level (<= heading-level 6)))
+        heading? (:heading properties)
         *control-show? (get state ::control-show?)
         db-collapsed? (util/collapsed? block)
         collapsed? (cond
@@ -2665,7 +2659,7 @@
       (when @*show-left-menu?
         (block-left-menu config block))
 
-      (block-content-or-editor config block edit-input-id block-id heading-level edit?)
+      (block-content-or-editor config block edit-input-id block-id edit?)
 
       (when @*show-right-menu?
         (block-right-menu config block edit?))]

+ 27 - 25
src/main/frontend/components/content.cljs

@@ -84,7 +84,7 @@
      :on-click editor-handler/copy-block-embeds}
     "Copy block embeds"
     nil)
-   
+
    [:hr.menu-separator]
 
    (ui/menu-link
@@ -100,8 +100,7 @@
    "#787f97"
    "#978626"
    "#49767b"
-   "#264c9b"
-   "#793e3e"])
+   "#264c9b"])
 
 (defonce *template-including-parent? (atom nil))
 
@@ -163,22 +162,36 @@
 (rum/defc ^:large-vars/cleanup-todo block-context-menu-content
   [_target block-id]
     (when-let [block (db/entity [:block/uuid block-id])]
-      (let [properties (:block/properties block)
-            heading? (true? (:heading properties))]
+      (let [format (:block/format block)]
         [:.menu-links-wrapper
-         [:div.flex-row.flex.justify-between.pb-2.pt-1.px-2
-          [:div.flex-row.flex.justify-between
+         [:div.flex.flex-row.justify-between.pb-2.pt-1.px-2.items-center
+          [:div.flex.flex-row.justify-between.flex-1
            (for [color block-background-colors]
              [:a.m-2.shadow-sm
               {:on-click (fn [_e]
                            (editor-handler/set-block-property! block-id "background-color" color))}
-              [:div.heading-bg {:style {:background-color color}}]])
-           [:a.m-2.shadow-sm
-            {:title    (t :remove-background)
-             :on-click (fn [_e]
-                         (editor-handler/remove-block-property! block-id "background-color"))}
-            [:div.heading-bg.remove "-"]]]]
-         
+              [:div.heading-bg {:style {:background-color color}}]])]
+          [:a.m-2.shadow-sm
+           {:title    (t :remove-background)
+            :on-click (fn [_e]
+                        (editor-handler/remove-block-property! block-id "background-color"))}
+           [:div.heading-bg.remove "-"]]]
+
+         [:div.flex.flex-row.justify-between.pb-2.pt-1.px-2.items-center
+          [:div.flex.flex-row.justify-between.flex-1
+           (for [i (range 1 7)]
+             (ui/button
+               (str "H" i)
+               :on-click (fn [_e]
+                           (editor-handler/set-heading! block-id format i))
+               :intent "link"
+               :small? true))]
+          [:a.m-2
+           {:title    (t :remove-heading)
+            :on-click (fn [_e]
+                        (editor-handler/remove-heading! block-id format))}
+           [:div.heading-bg.remove "-"]]]
+
          [:hr.menu-separator]
 
          (ui/menu-link
@@ -232,17 +245,6 @@
 
          [:hr.menu-separator]
 
-         (ui/menu-link
-          {:key      "Convert heading"
-           :on-click (fn [_e]
-                       (if heading?
-                         (editor-handler/remove-block-property! block-id :heading)
-                         (editor-handler/set-block-property! block-id :heading true)))}
-          (if heading?
-            "Convert back to a block"
-            "Convert to a heading")
-          nil)
-
          (block-template block-id)
 
          (if (srs/card-block? block)

+ 1 - 1
src/main/frontend/components/editor.cljs

@@ -568,7 +568,7 @@
 
 (rum/defcs box < rum/reactive
   {:init (fn [state]
-           (assoc state ::heading-level (:heading-level (first (:rum/args state)))
+           (assoc state
                   ::id (str (random-uuid))))
    :did-mount (fn [state]
                 (state/set-editor-args! (:rum/args state))

+ 0 - 1
src/main/frontend/db/model.cljs

@@ -54,7 +54,6 @@
     :block/created-at
     :block/updated-at
     :block/file
-    :block/heading-level
     {:block/page [:db/id :block/name :block/original-name :block/journal-day]}
     {:block/_parent ...}])
 

+ 23 - 3
src/main/frontend/handler/editor.cljs

@@ -316,9 +316,10 @@
                      (block/parse-title-and-body uuid format pre-block? (:block/content block)))
         properties (:block/properties block)
         real-content (:block/content block)
-        content (if (and (seq properties) real-content (not= real-content content))
-                  (property/with-built-in-properties properties content format)
-                  content)
+        content (let [properties (if (= format :markdown) (dissoc properties :heading) properties)]
+                  (if (and (seq properties) real-content (not= real-content content))
+                   (property/with-built-in-properties properties content format)
+                   content))
         content (drawer/with-logbook block content)
         content (with-timetracking block content)
         first-block? (= left page)
@@ -1939,6 +1940,7 @@
                                   (property/insert-properties format content props))
                     ast (mldoc/->edn content* (gp-mldoc/default-config format))
                     blocks (block/extract-blocks ast content* format {})
+                    _ (prn {:block (first blocks)})
                     fst-block (first blocks)
                     fst-block (if (and keep-uuid? (uuid? (:uuid block)))
                                 (assoc fst-block :block/uuid (:uuid block))
@@ -3465,3 +3467,21 @@
     ;; has children
     (first (:block/_parent (db/entity (:db/id block)))))
    (util/collapsed? block)))
+
+(defn set-heading!
+  [block-id format heading]
+  (if (= format :markdown)
+    (let [repo (state/get-current-repo)
+          block (db/entity [:block/uuid block-id])
+          content' (commands/set-markdown-heading (:block/content block) heading)]
+      (save-block! repo block-id content'))
+    (set-block-property! block-id "heading" heading)))
+
+(defn remove-heading!
+  [block-id format]
+  (remove-block-property! block-id "heading")
+  (when (= format :markdown)
+    (let [repo (state/get-current-repo)
+          block (db/entity [:block/uuid block-id])
+          content' (commands/clear-markdown-heading (:block/content block))]
+      (save-block! repo block-id content'))))

+ 4 - 0
src/main/frontend/handler/events.cljs

@@ -611,6 +611,10 @@
            template
            {:target page}))))))
 
+(defmethod handle :editor/set-org-mode-heading [[_ block heading]]
+  (when-let [id (:block/uuid block)]
+    (editor-handler/set-heading! id :org heading)))
+
 (defmethod handle :file-sync-graph/restore-file [[_ graph page-entity content]]
   (when (db/get-db graph)
     (let [file (:block/file page-entity)]

+ 0 - 1
src/main/frontend/handler/export.cljs

@@ -482,7 +482,6 @@
          [:block/id
           :block/page-name
           :block/properties
-          :block/heading-level
           :block/format
           :block/children
           :block/content]))})

+ 0 - 7
src/main/frontend/mobile/action_bar.cljs

@@ -52,13 +52,6 @@
           (.scrollBy (util/app-scroll-container-node) #js {:top (- 10 delta)})))
       [:div.action-bar
        [:div.action-bar-commands
-        (when-not (= (:block/format block) :org)
-          (action-command "heading" "Heading"
-                          #(let [properties (:block/properties block)
-                                 heading?   (true? (:heading properties))]
-                             (if heading?
-                               (editor-handler/remove-block-property! uuid :heading)
-                               (editor-handler/set-block-property! uuid :heading true)))))
         (action-command "infinity" "Card" #(srs/make-block-a-card! (:block/uuid block)))
         (action-command "copy" "Copy" #(editor-handler/copy-selection-blocks false))
         (action-command "cut" "Cut" #(editor-handler/cut-selection-blocks true))

+ 10 - 9
src/main/frontend/modules/file/core.cljs

@@ -29,13 +29,14 @@
     content))
 
 (defn transform-content
-  [{:block/keys [collapsed? format pre-block? unordered content heading-level left page parent]} level {:keys [heading-to-list?]}]
-  (let [content (or content "")
+  [{:block/keys [collapsed? format pre-block? unordered content left page parent properties]} level {:keys [heading-to-list?]}]
+  (let [heading (:heading properties)
+        markdown? (= :markdown format)
+        content (or content "")
         pre-block? (or pre-block?
                        (and (= page parent left) ; first block
-                            (= :markdown format)
+                            markdown?
                             (string/includes? (first (string/split-lines content)) ":: ")))
-        markdown? (= format :markdown)
         content (cond
                   pre-block?
                   (let [content (string/trim content)]
@@ -45,7 +46,7 @@
                   (let [markdown-top-heading? (and markdown?
                                                    (= parent page)
                                                    (not unordered)
-                                                   heading-level)
+                                                   heading)
                         [prefix spaces-tabs]
                         (cond
                           (= format :org)
@@ -57,10 +58,10 @@
                           ["" ""]
 
                           :else
-                          (let [level (if (and heading-to-list? heading-level)
-                                        (if (> heading-level 1)
-                                          (dec heading-level)
-                                          heading-level)
+                          (let [level (if (and heading-to-list? heading)
+                                        (if (> heading 1)
+                                          (dec heading)
+                                          heading)
                                         level)
                                 spaces-tabs (->>
                                              (repeat (dec level) (state/get-export-bullet-indentation))

+ 2 - 2
src/main/frontend/ui.css

@@ -245,7 +245,7 @@ html.is-mobile {
 .ui__button {
   @apply flex items-center px-3 py-2 border border-transparent
   text-sm leading-4 font-medium rounded-md text-white
-  focus:outline-none transition ease-in-out duration-150 mt-1;
+  focus:outline-none transition ease-in-out duration-150;
 
   &:disabled {
     opacity: 0.5;
@@ -355,4 +355,4 @@ html.is-mobile {
 
 .ui__icon {
   display: inline-block;
-}
+}