Kaynağa Gözat

Merge branch 'master' into fix-toolbar-showing

llcc 3 yıl önce
ebeveyn
işleme
ade8356bc6

+ 1 - 1
package.json

@@ -104,7 +104,7 @@
         "ignore": "5.1.8",
         "is-svg": "4.3.0",
         "jszip": "3.5.0",
-        "mldoc": "1.3.9",
+        "mldoc": "1.4.0",
         "path": "0.12.7",
         "pixi-graph-fork": "0.2.0",
         "pixi.js": "6.2.0",

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

@@ -2097,12 +2097,14 @@
     [:div.indent (ui/icon "indent-increase" {:style {:fontSize 16}})]]])
 
 (rum/defc block-right-menu < rum/reactive
-  [_config {:block/keys [uuid] :as _block}]
+  [_config {:block/keys [uuid] :as _block} edit?]
   [:div.block-right-menu.flex.bg-base-2.rounded-md.ml-1
    [:div.commands-button.w-0.flex.flew-col.rounded-md
-    {:id (str "block-right-menu-" uuid)}
-    [:div.more (ui/icon "dots-circle-horizontal" {:style {:fontSize 16}})]
-    [:div.outdent (ui/icon "indent-decrease" {:style {:fontSize 16}})]]])
+    {:id (str "block-right-menu-" uuid)
+     :style {:max-width (if edit? 40 80)}}
+    [:div.outdent (ui/icon "indent-decrease" {:style {:fontSize 16}})]
+    (when-not edit?
+      [:div.more (ui/icon "dots-circle-horizontal" {:style {:fontSize 16}})])]])
 
 (rum/defcs block-content-or-editor < rum/reactive
   (rum/local true :hide-block-refs?)
@@ -2434,7 +2436,7 @@
         :data-collapsed (and collapsed? has-child?)
         :class (str uuid
                     (when pre-block? " pre-block")
-                    (when (and card? (not review-cards?)) " shadow-xl")
+                    (when (and card? (not review-cards?)) " shadow-md")
                     (when (:ui/selected? block) " selected noselect"))
         :blockid (str uuid)
         :haschild (str has-child?)}
@@ -2465,9 +2467,9 @@
 
      [:div.flex.flex-row.pr-2
       {:class (if (and heading? (seq (:block/title block))) "items-baseline" "")
-       :on-touch-start block-handler/on-touch-start
+       :on-touch-start (fn [event uuid] (block-handler/on-touch-start event uuid))
        :on-touch-move (fn [event]
-                        (block-handler/on-touch-move event block uuid *show-left-menu? *show-right-menu?))
+                        (block-handler/on-touch-move event block uuid edit? *show-left-menu? *show-right-menu?))
        :on-touch-end (fn [event]
                        (block-handler/on-touch-end event block uuid *show-left-menu? *show-right-menu?))
        :on-touch-cancel block-handler/on-touch-cancel
@@ -2482,7 +2484,7 @@
         (block-left-menu config block))
       (block-content-or-editor config block edit-input-id block-id heading-level edit?)
       (when @*show-right-menu?
-        (block-right-menu config block))]
+        (block-right-menu config block edit?))]
 
      (block-children config children collapsed?)
 

+ 1 - 2
src/main/frontend/components/block.css

@@ -191,7 +191,7 @@
     
     .commands-button {
         overflow: hidden;
-        max-width: 50px;
+        max-width: 40px;
         text-align: center;
         margin: auto 0;
 
@@ -207,7 +207,6 @@
 
     .commands-button {
         overflow: hidden;
-        max-width: 80px;
         text-align: center;
         margin: auto 0;
 

+ 2 - 3
src/main/frontend/components/header.css

@@ -1,5 +1,5 @@
 .cp__header {
-  @apply z-10;  
+  @apply z-10;
   -webkit-app-region: drag;
 
   padding-top: var(--ls-headbar-inner-top-padding);
@@ -105,7 +105,6 @@
 
   .dropdown-wrapper {
     .ti {
-      margin-right: 5px;
       opacity: .9;
     }
   }
@@ -218,7 +217,7 @@ a.button {
 }
 
 html.is-ios.is-safari {
-  
+
   .cp__header {
     background-color: var(--ls-primary-background-color);
   }

+ 152 - 148
src/main/frontend/components/page.cljs

@@ -673,7 +673,7 @@
   [title key by-item desc?]
   [:th
    {:class [(name key)]}
-   [:a {:on-click (fn []
+   [:a.fade-link {:on-click (fn []
                     (reset! by-item key)
                     (swap! desc? not))}
     [:span.flex.items-center
@@ -743,10 +743,6 @@
   (rum/local false ::journals)
   (rum/local nil ::filter-fn)
   (rum/local 1 ::current-page)
-  ;; {:did-mount (fn [state]
-  ;;               (let [current-repo (state/sub :git/current-repo)]
-  ;;                 (js/setTimeout #(db/remove-orphaned-pages! current-repo) 0))
-  ;;               state)}
   [state]
   (let [current-repo (state/sub :git/current-repo)
         per-page-num 40
@@ -794,6 +790,8 @@
     [:div.flex-1.cp__all_pages
      [:h1.title (t :all-pages)]
 
+     [:div.text-sm.ml-1.opacity-70.mb-4 (t :paginates/pages (count @*results-all))]
+
      (when current-repo
 
        ;; all pages
@@ -829,147 +827,153 @@
                                       [idx (boolean (get @*checks idx))])))
            (reset! *results pages)))
 
-       [[:div.actions
-         {:class (util/classnames [{:has-selected (or (nil? @*indeterminate)
-                                                      (not= 0 @*indeterminate))}])}
-         [:div.l.flex.items-center
-          [:div.actions-wrap
-           (ui/button
-             [(ui/icon "trash") (t :delete)]
-             :on-click (fn []
-                         (let [selected (filter (fn [[_ v]] v) @*checks)
-                               selected (and (seq selected)
-                                             (into #{} (for [[k _] selected] k)))]
-                           (when-let [pages (and selected (filter #(contains? selected (:block/idx %)) @*results))]
-                             (state/set-modal! (batch-delete-dialog pages false #(do
-                                                                                   (reset! *checks nil)
-                                                                                   (refresh-pages)))))))
-             :small? true)]
-
-          [:div.search-wrap.flex.items-center.pl-2
-           (let [search-fn (fn []
+       (let [has-prev? (> @*current-page 1)
+             has-next? (not= @*current-page total-pages)]
+         [:div
+         [:div.actions
+          {:class (util/classnames [{:has-selected (or (nil? @*indeterminate)
+                                                       (not= 0 @*indeterminate))}])}
+          [:div.l.flex.items-center
+           [:div.actions-wrap
+            (ui/button
+              [(ui/icon "trash" {:style {:font-size 15}}) (t :delete)]
+              :on-click (fn []
+                          (let [selected (filter (fn [[_ v]] v) @*checks)
+                                selected (and (seq selected)
+                                              (into #{} (for [[k _] selected] k)))]
+                            (when-let [pages (and selected (filter #(contains? selected (:block/idx %)) @*results))]
+                              (state/set-modal! (batch-delete-dialog pages false #(do
+                                                                                    (reset! *checks nil)
+                                                                                    (refresh-pages)))))))
+              :class "fade-link"
+              :small? true)]
+
+           [:div.search-wrap.flex.items-center.pl-2
+            (let [search-fn (fn []
+                              (let [^js input (rum/deref *search-input)]
+                                (search-key (.-value input))
+                                (reset! *current-page 1)))
+                  reset-fn (fn []
                              (let [^js input (rum/deref *search-input)]
-                               (search-key (.-value input))
-                               (reset! *current-page 1)))
-                 reset-fn (fn []
-                            (let [^js input (rum/deref *search-input)]
-                              (set! (.-value input) "")
-                              (reset! *search-key nil)))]
-
-             [(ui/button (ui/icon "search")
-                :on-click search-fn
-                :small? true)
-              [:input.form-input {:placeholder   (t :search/page-names)
-                                  :on-key-up     (fn [^js e]
-                                                   (let [^js target (.-target e)]
-                                                     (if (string/blank? (.-value target))
-                                                       (reset! *search-key nil)
-                                                       (cond
-                                                         (= 13 (.-keyCode e)) (search-fn)
-                                                         (= 27 (.-keyCode e)) (reset-fn)))))
-                                  :ref           *search-input
-                                  :default-value ""}]
-
-              (when (not (string/blank? @*search-key))
-                [:a.cancel {:on-click reset-fn}
-                 (ui/icon "x")])])]]
-
-         [:div.r.flex.items-center.justify-between
-          (let [orphaned-pages (model/get-orphaned-pages {})
-                orphaned-pages? (seq orphaned-pages)]
-            [:a.ml-1.pr-2.opacity-70.hover:opacity-100
-             {:on-click (fn []
-                          (if orphaned-pages?
-                            (state/set-modal!
-                             (batch-delete-dialog
-                              orphaned-pages  true
-                              #(do
-                                 (reset! *checks nil)
-                                 (refresh-pages))))
-                            (notification/show! "Congratulations, no orphaned pages in your graph!" :success)))}
-             [:span
-              (ui/icon "file-x")
-              [:span.ml-1 (t :remove-orphaned-pages)]]])
-
-          [:a.ml-1.pr-2.opacity-70.hover:opacity-100 {:href (rfe/href :all-files)}
-           [:span
-            (ui/icon "files")
-            [:span.ml-1 (t :all-files)]]]
-
-          [:div
-           (ui/tippy
-            {:html  [:small (str (t :page/show-journals) " ?")]
-             :arrow true}
-            [:a.button.journal
-             {:class    (util/classnames [{:active (boolean @*journal?)}])
-              :on-click #(reset! *journal? (not @*journal?))}
-             (ui/icon "calendar")])]
-
-          [:div.paginates
-           [:span.flex.items-center.opacity-60.text-sm
-            [:span.pr-1 (t :paginates/pages (count @*results-all))]]
-           [:span.flex.items-center
-            {:class (util/classnames [{:is-first (= 1 @*current-page)
-                                       :is-last  (= @*current-page total-pages)}])}
-            [:a.py-4.pr-2 {:on-click #(to-page (dec @*current-page))} (ui/icon "caret-left") (str " " (t :paginates/prev))]
-            [:span.opacity-30 (str @*current-page "/" total-pages)]
-            [:a.py-4.pl-2 {:on-click #(to-page (inc @*current-page))} (str (t :paginates/next) " ") (ui/icon "caret-right")]]]]]
-
-        [:table.table-auto.cp__all_pages_table
-         [:thead
-          [:tr
-           [:th.selector
-            (checkbox-opt "all-pages-select-all"
-                          (= 1 @*indeterminate)
-                          {:on-change     (fn []
-                                            (let [indeterminate? (= -1 @*indeterminate)
-                                                  all? (= 1 @*indeterminate)]
-                                              (doseq [{:block/keys [idx]} @*results]
-                                                (swap! *checks assoc idx (or indeterminate? (not all?))))))
-                           :indeterminate (= -1 @*indeterminate)})]
-
-           (sortable-title (t :block/name) :block/name *sort-by-item *desc?)
-           (when-not mobile?
-             [(sortable-title (t :page/backlinks) :block/backlinks *sort-by-item *desc?)
-              (sortable-title (t :page/created-at) :block/created-at *sort-by-item *desc?)
-              (sortable-title (t :page/updated-at) :block/updated-at *sort-by-item *desc?)])]]
-
-         [:tbody
-          (for [{:block/keys [idx name created-at updated-at backlinks] :as page} @*results]
-            (when-not (string/blank? name)
-              [:tr {:key name}
-               [:td.selector
-                (checkbox-opt (str "label-" idx)
-                              (get @*checks idx)
-                              {:on-change (fn []
-                                            (swap! *checks update idx not))})]
-
-               [:td.name [:a {:on-click (fn [e]
-                                          (let [repo (state/get-current-repo)]
-                                            (when (gobj/get e "shiftKey")
-                                              (state/sidebar-add-block!
-                                               repo
-                                               (:db/id page)
-                                               :page))))
-                              :href     (rfe/href :page {:name (:block/name page)})}
-                          (component-block/page-cp {} page)]]
-
-               (when-not mobile?
-                 [:td.backlinks [:span backlinks]])
-
-               (when-not mobile?
-                 [:td.created-at [:span (if created-at
-                                          (date/int->local-time-2 created-at)
-                                          "Unknown")]])
-               (when-not mobile?
-                 [:td.updated-at [:span (if updated-at
-                                          (date/int->local-time-2 updated-at)
-                                          "Unknown")]])]))]]
-
-        [:div.paginates
-         [:span]
-         [:span.flex.items-center
-          {:class (util/classnames [{:is-first (= 1 @*current-page)
-                                     :is-last  (= @*current-page total-pages)}])}
-          [:a.py-4.text-sm {:on-click #(to-page (dec @*current-page))} (ui/icon "caret-left") (str " " (t :paginates/prev))]
-          [:a.py-4.pl-2.text-sm {:on-click #(to-page (inc @*current-page))} (str (t :paginates/next) " ") (ui/icon "caret-right")]]]])]))
+                               (set! (.-value input) "")
+                               (reset! *search-key nil)))]
+
+              [(ui/button (ui/icon "search")
+                 :on-click search-fn
+                 :small? true)
+               [:input.form-input {:placeholder   (t :search/page-names)
+                                   :on-key-up     (fn [^js e]
+                                                    (let [^js target (.-target e)]
+                                                      (if (string/blank? (.-value target))
+                                                        (reset! *search-key nil)
+                                                        (cond
+                                                          (= 13 (.-keyCode e)) (search-fn)
+                                                          (= 27 (.-keyCode e)) (reset-fn)))))
+                                   :ref           *search-input
+                                   :default-value ""}]
+
+               (when (not (string/blank? @*search-key))
+                 [:a.cancel {:on-click reset-fn}
+                  (ui/icon "x")])])]]
+
+          [:div.r.flex.items-center.justify-between
+           [:div
+            (ui/tippy
+             {:html  [:small (str (t :page/show-journals) " ?")]
+              :arrow true}
+             [:a.button.journal
+              {:class    (util/classnames [{:active (boolean @*journal?)}])
+               :on-click #(reset! *journal? (not @*journal?))}
+              (ui/icon "calendar")])]
+
+           [:div.paginates
+            [:span.flex.items-center
+             {:class (util/classnames [{:is-first (= 1 @*current-page)
+                                        :is-last  (= @*current-page total-pages)}])}
+             (when has-prev?
+               [:a.py-4.pr-2.fade-link {:on-click #(to-page (dec @*current-page))} (ui/icon "caret-left") (str " " (t :paginates/prev))])
+             [:span.opacity-60 (str @*current-page "/" total-pages)]
+             (when has-next?
+               [:a.py-4.pl-2.fade-link {:on-click #(to-page (inc @*current-page))} (str (t :paginates/next) " ") (ui/icon "caret-right")])]]
+
+           (ui/dropdown-with-links
+            (fn [{:keys [toggle-fn]}]
+              [:a.button.fade-link
+               {:on-click toggle-fn}
+               (ui/icon "dots" {:style {:fontSize ui/icon-size}})])
+            [{:title (t :remove-orphaned-pages)
+              :options {:on-click (fn []
+                                    (let [orphaned-pages (model/get-orphaned-pages {})
+                                          orphaned-pages? (seq orphaned-pages)]
+                                      (if orphaned-pages?
+                                        (state/set-modal!
+                                         (batch-delete-dialog
+                                          orphaned-pages  true
+                                          #(do
+                                             (reset! *checks nil)
+                                             (refresh-pages))))
+                                        (notification/show! "Congratulations, no orphaned pages in your graph!" :success))))}
+              :icon (ui/icon "file-x")}
+             {:title (t :all-files)
+              :options {:href (rfe/href :all-files)}
+              :icon (ui/icon "files")}]
+            {})]]
+
+         [:table.table-auto.cp__all_pages_table
+          [:thead
+           [:tr
+            [:th.selector
+             (checkbox-opt "all-pages-select-all"
+                           (= 1 @*indeterminate)
+                           {:on-change     (fn []
+                                             (let [indeterminate? (= -1 @*indeterminate)
+                                                   all? (= 1 @*indeterminate)]
+                                               (doseq [{:block/keys [idx]} @*results]
+                                                 (swap! *checks assoc idx (or indeterminate? (not all?))))))
+                            :indeterminate (= -1 @*indeterminate)})]
+
+            (sortable-title (t :block/name) :block/name *sort-by-item *desc?)
+            (when-not mobile?
+              [(sortable-title (t :page/backlinks) :block/backlinks *sort-by-item *desc?)
+               (sortable-title (t :page/created-at) :block/created-at *sort-by-item *desc?)
+               (sortable-title (t :page/updated-at) :block/updated-at *sort-by-item *desc?)])]]
+
+          [:tbody
+           (for [{:block/keys [idx name created-at updated-at backlinks] :as page} @*results]
+             (when-not (string/blank? name)
+               [:tr {:key name}
+                [:td.selector
+                 (checkbox-opt (str "label-" idx)
+                               (get @*checks idx)
+                               {:on-change (fn []
+                                             (swap! *checks update idx not))})]
+
+                [:td.name [:a {:on-click (fn [e]
+                                           (let [repo (state/get-current-repo)]
+                                             (when (gobj/get e "shiftKey")
+                                               (state/sidebar-add-block!
+                                                repo
+                                                (:db/id page)
+                                                :page))))
+                               :href     (rfe/href :page {:name (:block/name page)})}
+                           (component-block/page-cp {} page)]]
+
+                (when-not mobile?
+                  [:td.backlinks [:span backlinks]])
+
+                (when-not mobile?
+                  [:td.created-at [:span (if created-at
+                                           (date/int->local-time-2 created-at)
+                                           "Unknown")]])
+                (when-not mobile?
+                  [:td.updated-at [:span (if updated-at
+                                           (date/int->local-time-2 updated-at)
+                                           "Unknown")]])]))]]
+
+         [:div.paginates
+          [:span]
+          [:span.flex.items-center
+           (when has-prev?
+             [:a.py-4.text-sm.fade-link {:on-click #(to-page (dec @*current-page))} (ui/icon "caret-left") (str " " (t :paginates/prev))])
+           (when has-next?
+             [:a.py-4.pl-2.text-sm.fade-link {:on-click #(to-page (inc @*current-page))} (str (t :paginates/next) " ") (ui/icon "caret-right")])]]]))]))

+ 5 - 12
src/main/frontend/components/page.css

@@ -101,7 +101,7 @@
     position: sticky;
     background-color: var(--ls-primary-background-color);
     white-space: nowrap;
-    top: -1px;
+    top: -18px;
     padding-bottom: 10px;
     z-index: 1;
 
@@ -119,7 +119,6 @@
       font-size: 16px;
       display: inline-block;
       position: relative;
-      bottom: -1px;
     }
 
     .l {
@@ -136,7 +135,7 @@
 
       a.journal {
         color: var(--ls-primary-text-color);
-        opacity: .3;
+        margin-top: 1px;
 
         &.active {
           opacity: 1;
@@ -148,7 +147,7 @@
         display: flex;
         align-items: center;
         justify-content: center;
-        margin-right: 5px;
+        margin-right: 3px;
       }
     }
 
@@ -195,7 +194,7 @@
     display: flex;
     align-items: center;
     justify-content: space-between;
-    padding: 0 5px;
+    padding: 0 5px 0 0;
 
     > span {
       color: var(--ls-primary-text-color);
@@ -209,12 +208,6 @@
           }
         }
       }
-
-      &.is-first > a:first-child,
-      &.is-last > a:last-child {
-        pointer-events: none;
-        opacity: .3;
-      }
     }
   }
 }
@@ -390,4 +383,4 @@ html.is-native-ios {
   display: inline-block;
   line-height: normal;
   background-color: var(--ls-quaternary-background-color);
- }
+ }

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

@@ -122,7 +122,7 @@
   (let [item (build-sidebar-item repo idx db-id block-type)]
     (when item
       (let [collapse? (state/sub [:ui/sidebar-collapsed-blocks db-id])]
-        [:div.sidebar-item.content.color-level.px-4.shadow-lg
+        [:div.sidebar-item.content.color-level.px-4.shadow-md
          (let [[title component] item]
            [:div.flex.flex-col
             [:div.flex.flex-row.justify-between

+ 12 - 8
src/main/frontend/extensions/pdf/assets.cljs

@@ -7,6 +7,7 @@
             [frontend.fs :as fs]
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.page :as page-handler]
+            [frontend.util.page-property :as page-property]
             [frontend.state :as state]
             [frontend.util :as util]
             [logseq.graph-parser.config :as gp-config]
@@ -154,14 +155,14 @@
         page-name (str "hls__" page-name)
         page (db-model/get-page page-name)
         url (:url pdf-current)
-        format (state/get-preferred-format)]
+        format (state/get-preferred-format)
+        repo-dir (config/get-repo-dir (state/get-current-repo))
+        asset-dir (util/node-path.join repo-dir gp-config/local-assets-dir)
+        url (if (string/includes? url asset-dir)
+              (str ".." (last (string/split url repo-dir)))
+              url)]
     (if-not page
-      (let [repo-dir (config/get-repo-dir (state/get-current-repo))
-            asset-dir (util/node-path.join repo-dir gp-config/local-assets-dir)
-            url (if (string/includes? url asset-dir)
-                  (str ".." (last (string/split url repo-dir)))
-                  url)
-            label (:filename pdf-current)]
+      (let [label (:filename pdf-current)]
         (page-handler/create! page-name {:redirect?        false :create-first-block? false
                                          :split-namespace? false
                                          :format           format
@@ -175,7 +176,10 @@
                                                                          url)
                                                             :file-path url}})
         (db-model/get-page page-name))
-      page)))
+
+      ;; try to update file path
+      (page-property/add-property! page-name :file-path url))
+    page))
 
 (defn create-ref-block!
   [{:keys [id content page]}]

+ 92 - 80
src/main/frontend/handler/block.cljs

@@ -1,6 +1,7 @@
 (ns frontend.handler.block
   (:require
    [clojure.set :as set]
+   [clojure.string :as string]
    [clojure.walk :as walk]
    [frontend.db :as db]
    [frontend.db.model :as db-model]
@@ -147,88 +148,99 @@
       (state/exit-editing-and-set-selected-blocks! blocks))))
 
 (def *swipe (atom nil))
+(def *touch-start (atom nil))
 
 (defn on-touch-start
-  [event]
-  (when-let [touches (.-targetTouches event)]
-    (when (= (.-length touches) 1)
-      (let [touch (aget touches 0)
-            x (.-clientX touch)
-            y (.-clientY touch)]
-        (reset! *swipe {:x0 x :y0 y :xi x :yi y :tx x :ty y :direction nil})))))
+  [event uuid]
+  (let [input (state/get-input)
+        input-id (state/get-edit-input-id)
+        selection-type (.-type (.getSelection js/document))]
+    (reset! *touch-start (js/Date.now))
+    (when-not (and input
+                   (string/ends-with? input-id (str uuid)))
+      (state/clear-edit!))
+    (when (not= selection-type "Range")
+      (when-let [touches (.-targetTouches event)]
+        (when (= (.-length touches) 1)
+          (let [touch (aget touches 0)
+                x (.-clientX touch)
+                y (.-clientY touch)]
+            (reset! *swipe {:x0 x :y0 y :xi x :yi y :tx x :ty y :direction nil})))))))
 
 (defn on-touch-move
-  [event block uuid *show-left-menu? *show-right-menu?]
+  [event block uuid edit? *show-left-menu? *show-right-menu?]
   (when-let [touches (.-targetTouches event)]
-    (when (and (= (.-length touches) 1) @*swipe)
-      (let [{:keys [x0 xi direction]} @*swipe
-            touch (aget touches 0)
-            tx (.-clientX touch)
-            ty (.-clientY touch)
-            direction (if (nil? direction)
-                        (if (> tx x0)
-                          :right
-                          :left)
-                        direction)]
-        (swap! *swipe #(-> %
-                           (assoc :tx tx)
-                           (assoc :ty ty)
-                           (assoc :xi tx)
-                           (assoc :yi ty)
-                           (assoc :direction direction)))
-        (when (< (* (- xi x0) (- tx xi)) 0)
-          (swap! *swipe #(-> %
-                             (assoc :x0 tx)
-                             (assoc :y0 ty))))
-        (let [{:keys [x0 y0]} @*swipe
-              dx (- tx x0)
-              dy (- ty y0)]
-          (when (and (< (. js/Math abs dy) 20)
-                     (> (. js/Math abs dx) 10))
-            (let [left (gdom/getElement (str "block-left-menu-" uuid))
-                  right (gdom/getElement (str "block-right-menu-" uuid))]
+    (let [selection-type (.-type (.getSelection js/document))]
+      (when-not (= selection-type "Range")
+        (when (< (- (js/Date.now) @*touch-start) 600)
+          (when (and (= (.-length touches) 1) @*swipe)
+            (let [{:keys [x0 xi direction]} @*swipe
+                  touch (aget touches 0)
+                  tx (.-clientX touch)
+                  ty (.-clientY touch)
+                  direction (if (nil? direction)
+                              (if (> tx x0)
+                                :right
+                                :left)
+                              direction)]
+              (swap! *swipe #(-> %
+                                 (assoc :tx tx)
+                                 (assoc :ty ty)
+                                 (assoc :xi tx)
+                                 (assoc :yi ty)
+                                 (assoc :direction direction)))
+              (when (< (* (- xi x0) (- tx xi)) 0)
+                (swap! *swipe #(-> %
+                                   (assoc :x0 tx)
+                                   (assoc :y0 ty))))
+              (let [{:keys [x0 y0]} @*swipe
+                    dx (- tx x0)
+                    dy (- ty y0)]
+                (when (and (< (. js/Math abs dy) 20)
+                           (> (. js/Math abs dx) 10))
+                  (let [left (gdom/getElement (str "block-left-menu-" uuid))
+                        right (gdom/getElement (str "block-right-menu-" uuid))]
 
-              (cond
-                (= direction :right)
-                (do
-                  (reset! *show-left-menu? true)
-                  (when left
-                    (when (>= dx 0)
-                      (set! (.. left -style -width) (str dx "px")))
-                    (when (< dx 0)
-                      (set! (.. left -style -width) (str (max (+ 50 dx) 0) "px")))
+                    (cond
+                      (= direction :right)
+                      (do
+                        (reset! *show-left-menu? true)
+                        (when left
+                          (when (>= dx 0)
+                            (set! (.. left -style -width) (str dx "px")))
+                          (when (< dx 0)
+                            (set! (.. left -style -width) (str (max (+ 40 dx) 0) "px")))
 
-                    (let [indent (gdom/getFirstElementChild left)]
-                      (when (indentable? block)
-                        (if (>= (.-clientWidth left) 50)
-                          (set! (.. indent -style -opacity) "100%")
-                          (set! (.. indent -style -opacity) "30%"))))))
+                          (let [indent (gdom/getFirstElementChild left)]
+                            (when (indentable? block)
+                              (if (>= (.-clientWidth left) 40)
+                                (set! (.. indent -style -opacity) "100%")
+                                (set! (.. indent -style -opacity) "30%"))))))
 
-                (= direction :left)
-                (do
-                  (reset! *show-right-menu? true)
-                  (when right
-                    (when (<= dx 0)
-                      (set! (.. right -style -width) (str (- dx) "px")))
-                    (when (> dx 0)
-                      (set! (.. right -style -width) (str (max (- 80 dx) 0) "px")))
+                      (= direction :left)
+                      (do
+                        (reset! *show-right-menu? true)
+                        (when right
+                          (when (<= dx 0)
+                            (set! (.. right -style -width) (str (- dx) "px")))
+                          (when (> dx 0)
+                            (set! (.. right -style -width) (str (max (- 80 dx) 0) "px")))
 
-                    (let [outdent (gdom/getFirstElementChild right)
-                          more (gdom/getLastElementChild right)]
-                      (if (and (>= (.-clientWidth right) 40)
-                               (< (.-clientWidth right) 80))
-                        (set! (.. outdent -style -opacity) "100%")
-                        (set! (.. outdent -style -opacity) "30%"))
+                          (let [outdent (gdom/getFirstElementChild right)
+                                more (when-not edit?
+                                       (gdom/getLastElementChild right))]
+                            (when (and outdent (outdentable? block))
+                              (if (and (>= (.-clientWidth right) 40)
+                                       (< (.-clientWidth right) 80))
+                                (set! (.. outdent -style -opacity) "100%")
+                                (set! (.. outdent -style -opacity) "30%")))
 
-                      (when (outdentable? block)
-                        (if (>= (.-clientWidth right) 80)
-                          (set! (.. more -style -opacity) "100%")
-                          (set! (.. more -style -opacity) "30%") 
-                        ;; (set! (.. outdent -style -opacity) "100%")
-                          ;; (set! (.. outdent -style -opacity) "30%")
-                        )))))
-                :else
-                nil))))))))
+                            (when more
+                              (if (>= (.-clientWidth right) 80)
+                                (set! (.. more -style -opacity) "100%")
+                                (set! (.. more -style -opacity) "30%"))))))
+                      :else
+                      nil)))))))))))
 
 (defn on-touch-end
   [_event block uuid *show-left-menu? *show-right-menu?]
@@ -240,25 +252,25 @@
       (try
         (when (> (. js/Math abs dx) 10)
           (cond
-            (and left-menu (>= (.-clientWidth left-menu) 50))
+            (and left-menu (>= (.-clientWidth left-menu) 40))
             (when (indentable? block)
               (haptics/with-haptics-impact
                 (indent-outdent-block! block :right)
                 :light))
 
-            (and right-menu (< 40 (.-clientWidth right-menu) 80))
+            (and right-menu (<= 40 (.-clientWidth right-menu) 79))
+            (when (outdentable? block)
+              (haptics/with-haptics-impact
+                (indent-outdent-block! block :left)
+                :light))
+
+            (and right-menu (>= (.-clientWidth right-menu) 80))
             (haptics/with-haptics-impact
               (do (state/set-state! :mobile/show-action-bar? true)
                   (state/set-state! :mobile/actioned-block block)
                   (select-block! uuid))
               :light)
 
-            (and right-menu (>= (.-clientWidth right-menu) 80))
-            (when (outdentable? block)
-              (haptics/with-haptics-impact
-                (indent-outdent-block! block :left)
-                :light))
-
             :else
             nil))
         (catch js/Error e

+ 19 - 13
src/main/frontend/handler/editor.cljs

@@ -970,11 +970,12 @@
   [repo block-ids]
   (let [blocks (db-utils/pull-many repo '[*] (mapv (fn [id] [:block/uuid id]) block-ids))
         top-level-block-uuids (->> (outliner-core/get-top-level-blocks blocks)
-                                   (map :block/uuid))]
-    (export/export-blocks-as-markdown
-     repo top-level-block-uuids
-     (state/get-export-block-text-indent-style)
-     (into [] (state/get-export-block-text-remove-options)))))
+                                   (map :block/uuid))
+        content (export/export-blocks-as-markdown
+                 repo top-level-block-uuids
+                 (state/get-export-block-text-indent-style)
+                 (into [] (state/get-export-block-text-remove-options)))]
+    [top-level-block-uuids content]))
 
 (defn copy-selection-blocks
   [html?]
@@ -982,10 +983,10 @@
     (let [repo (state/get-current-repo)
           ids (distinct (keep #(when-let [id (dom/attr % "blockid")]
                                  (uuid id)) blocks))
-          content (compose-copied-blocks-contents repo ids)
+          [top-level-block-uuids content] (compose-copied-blocks-contents repo ids)
           block (db/entity [:block/uuid (first ids)])]
       (when block
-        (let [html (export/export-blocks-as-html repo ids)]
+        (let [html (export/export-blocks-as-html repo top-level-block-uuids)]
           (common-handler/copy-to-clipboard-without-id-property! (:block/format block) content (when html? html)))
         (state/set-copied-blocks content ids)
         (notification/show! "Copied!" :success)))))
@@ -1065,9 +1066,13 @@
         (let [repo (state/get-current-repo)
               block-uuids (distinct (map #(uuid (dom/attr % "blockid")) dom-blocks))
               lookup-refs (map (fn [id] [:block/uuid id]) block-uuids)
-              blocks (db/pull-many repo '[*] lookup-refs)]
-          (state/set-copied-full-blocks nil blocks)
-          (delete-blocks! repo block-uuids blocks dom-blocks))))))
+              blocks (db/pull-many repo '[*] lookup-refs)
+              top-level-blocks (outliner-core/get-top-level-blocks blocks)
+              sorted-blocks (mapcat (fn [block]
+                                      (tree/get-sorted-block-and-children repo (:db/id block)))
+                                    top-level-blocks)]
+          (state/set-copied-full-blocks nil sorted-blocks)
+          (delete-blocks! repo (map :block/uuid sorted-blocks) sorted-blocks dom-blocks))))))
 
 (def url-regex
   "Didn't use link/plain-link as it is incorrectly detects words as urls."
@@ -1194,9 +1199,10 @@
   (when-let [block (db/pull [:block/uuid block-id])]
     (let [repo (state/get-current-repo)
           ;; TODO: support org mode
-          md-content (compose-copied-blocks-contents repo [block-id])
-          html (export/export-blocks-as-html repo [block-id])]
-      (state/set-copied-full-blocks md-content [block])
+          [_top-level-block-uuids md-content] (compose-copied-blocks-contents repo [block-id])
+          html (export/export-blocks-as-html repo [block-id])
+          sorted-blocks (tree/get-sorted-block-and-children repo (:db/id block))]
+      (state/set-copied-full-blocks md-content sorted-blocks)
       (common-handler/copy-to-clipboard-without-id-property! (:block/format block) md-content html)
       (delete-block-aux! block true))))
 

+ 0 - 10
src/main/frontend/mobile/mobile_bar.cljs

@@ -45,14 +45,6 @@
                       (state/set-state! :mobile/toolbar-update-observer (rand-int 1000000)))}
     (ui/icon icon {:style {:fontSize ui/icon-size}})]])
 
-(rum/defc indent-outdent [indent? icon]
-  [:div
-   [:button.bottom-action
-    {:on-mouse-down (fn [e]
-                      (util/stop e)
-                      (editor-handler/indent-outdent indent?))}
-    (ui/icon icon {:style {:fontSize ui/icon-size}})]])
-
 (rum/defc timestamp-submenu
   [parent-id]
   (let [callback (fn [event]
@@ -127,8 +119,6 @@
           sorted-commands (sort-by (comp :counts second) > @commands-stats)]
       [:div#mobile-editor-toolbar.bg-base-2
        [:div.toolbar-commands
-        (indent-outdent false "indent-decrease")
-        (indent-outdent true "indent-increase")
         (command (editor-handler/move-up-down true) "arrow-bar-to-up")
         (command (editor-handler/move-up-down false) "arrow-bar-to-down")
         (command #(if (state/sub :document/mode?)

+ 9 - 10
src/main/frontend/modules/outliner/pipeline.cljs

@@ -9,13 +9,12 @@
 
 (defn invoke-hooks
   [tx-report]
-  (let [{:keys [pages blocks]} (ds-report/get-blocks-and-pages tx-report)]
-    (when-not (:from-disk? (:tx-meta tx-report))
-      (doseq [p (seq pages)] (updated-page-hook tx-report p)))
-    (when (and state/lsp-enabled? (seq blocks))
-      (state/pub-event! [:plugin/hook-db-tx
-                         {:blocks  blocks
-                          :tx-data (:tx-data tx-report)
-                          :tx-meta (:tx-meta tx-report)}]))
-    ;; TODO: Add blocks to hooks
-    #_(doseq [b (seq blocks)])))
+  (when (and (not (:from-disk? (:tx-meta tx-report)))
+             (not (:new-graph? (:tx-meta tx-report))))
+    (let [{:keys [pages blocks]} (ds-report/get-blocks-and-pages tx-report)]
+      (doseq [p (seq pages)] (updated-page-hook tx-report p))
+      (when (and state/lsp-enabled? (seq blocks))
+        (state/pub-event! [:plugin/hook-db-tx
+                           {:blocks  blocks
+                            :tx-data (:tx-data tx-report)
+                            :tx-meta (:tx-meta tx-report)}])))))

+ 7 - 0
src/main/frontend/modules/outliner/tree.cljs

@@ -79,3 +79,10 @@
   [blocks-exclude-root root]
   (let [parent-groups (atom (group-by :block/parent blocks-exclude-root))]
     (flatten (concat (sort-blocks-aux [root] parent-groups) (vals @parent-groups)))))
+
+(defn get-sorted-block-and-children
+  [repo db-id]
+  (when-let [root-block (db/pull db-id)]
+    (let [blocks (db/get-block-and-children repo (:block/uuid root-block))
+          blocks-exclude-root (remove (fn [b] (= (:db/id b) db-id)) blocks)]
+      (sort-blocks blocks-exclude-root root-block))))

+ 1 - 1
src/main/frontend/state.cljs

@@ -1437,7 +1437,7 @@
 (defn set-copied-full-blocks
   [content blocks]
   (set-state! :copy/blocks {:copy/graph (get-current-repo)
-                            :copy/content content
+                            :copy/content (or content (get-in @state [:copy/blocks :copy/content]))
                             :copy/full-blocks blocks}))
 
 (defn set-copied-full-blocks!

+ 2 - 1
src/main/frontend/ui.cljs

@@ -137,7 +137,8 @@
                       nil
                       [:div.flex.items-center
                        (when icon icon)
-                       [:div {:style {:margin-right "8px"}} title]])]
+                       [:div {:style {:margin-right "8px"
+                                      :margin-left "4px"}} title]])]
           (if hr
             [:hr.my-1 {:key "dropdown-hr"}]
             (rum/with-key

+ 15 - 0
src/test/frontend/modules/outliner/core_test.cljs

@@ -321,6 +321,21 @@
              :block/parent #:db{:id 6},
              :block/uuid 9}]))))
 
+(deftest test-get-sorted-block-and-children
+  (testing "get-sorted-block-and-children"
+    (transact-tree! tree)
+    (is (=
+         '(2 3 4 5 6 7 8 9 10 11)
+         (map :block/uuid (tree/get-sorted-block-and-children test-db (:db/id (get-block 2))))))
+
+    (is (=
+         '(22 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17)
+         (map :block/uuid (tree/get-sorted-block-and-children test-db (:db/id (get-block 22))))))
+
+    (is (=
+         '(16 17)
+         (map :block/uuid (tree/get-sorted-block-and-children test-db (:db/id (get-block 16))))))))
+
 ;;; Fuzzy tests
 
 (def init-id (atom 100))

+ 4 - 4
yarn.lock

@@ -5312,10 +5312,10 @@ mkdirp@^1.0.3:
   resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
   integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
 
-mldoc@1.3.9:
-  version "1.3.9"
-  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-1.3.9.tgz#9e45a25ba79596f3b0b0eace65f651a4c5a0c30a"
-  integrity sha512-UfqNuBphOj7paSBvozTdin5BLB5+W2tr2SGKTfp5eae6VQPx23oICx6RPQprft7KGFtn8T3rpM1YMUN8FaJLhg==
+mldoc@1.4.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-1.4.0.tgz#10dd8b57b1941a66b3d30fd031881ad31d499edb"
+  integrity sha512-6s1utUm03SCR1XH2EnHD3s0qAd+RLLGRc+1qb4SuHIjjmT5HMWbWGP+vADBLHKQKP6nwYCKsUJkiwLFjOXfP6w==
   dependencies:
     yargs "^12.0.2"