Przeglądaj źródła

fix: selected blocks order

also, catch all the errors for the main view so that it will not
crash the whole app.
Tienson Qin 4 lat temu
rodzic
commit
0e31cdd8bd

+ 8 - 0
resources/css/common.css

@@ -650,6 +650,14 @@ span.warning {
   color: #fff;
   color: #fff;
 }
 }
 
 
+a.error,
+span.error {
+    background: red;
+    padding: 0.1em 0.4em;
+    border-radius: var(--ls-border-radius-low);
+    color: #fff;
+}
+
 img.small {
 img.small {
   display: inline;
   display: inline;
   width: 20px;
   width: 20px;

+ 40 - 27
src/main/frontend/components/sidebar.cljs

@@ -22,6 +22,8 @@
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.export :as export]
             [frontend.handler.export :as export]
+            [frontend.handler.repo :as repo-handler]
+            [frontend.handler.web.nfs :as nfs-handler]
             [frontend.config :as config]
             [frontend.config :as config]
             [dommy.core :as d]
             [dommy.core :as d]
             [clojure.string :as string]
             [clojure.string :as string]
@@ -105,35 +107,46 @@
 
 
 (rum/defc main
 (rum/defc main
   [{:keys [route-match global-graph-pages? logged? home? route-name indexeddb-support? white? db-restoring? main-content]}]
   [{:keys [route-match global-graph-pages? logged? home? route-name indexeddb-support? white? db-restoring? main-content]}]
-  (rum/with-context [[t] i18n/*tongue-context*]
-    [:div#main-content.cp__sidebar-main-layout.flex-1.flex
-     [:div#sidebar-nav-wrapper.flex-col.pt-4.hidden.sm:block
-      {:style {:flex (if (state/get-left-sidebar-open?)
-                       "0 1 20%"
-                       "0 0 0px")
-               :border-right (str "1px solid "
-                                  (if white? "#f0f8ff" "#073642"))}}
-      (when (state/sub :ui/left-sidebar-open?)
-        (sidebar-nav route-match nil))]
-     [:div#main-content-container.w-full.flex.justify-center
-      {:style {:margin-top (if global-graph-pages? 0 "2rem")}}
-      [:div.cp__sidebar-main-content
-       {:data-is-global-graph-pages global-graph-pages?
-        :data-is-full-width (or global-graph-pages?
-                                (contains? #{:all-files :all-pages :my-publishing} route-name))}
-       (cond
-         (not indexeddb-support?)
-         nil
+  (ui/catch-error
+   [:div#main-content-container.w-full.flex.justify-center
+    [:div.mt-8
+     [:span.error "⚠️ Oops, Something Went Wrong, please back up your data first!"]
+     [:div.my-2 "Usually, a re-index could fix it. If it doesn't, you can join our "
+      [:a.inline {:href "https://discord.gg/KpN4eHY"
+                  :target "_blank"}
+       "discord group"]
+      " to ask for help."]
+     (ui/button "Re-index current graph"
+       :on-click #(repo-handler/re-index! nfs-handler/rebuild-index!))]]
+   (rum/with-context [[t] i18n/*tongue-context*]
+     [:div#main-content.cp__sidebar-main-layout.flex-1.flex
+      [:div#sidebar-nav-wrapper.flex-col.pt-4.hidden.sm:block
+       {:style {:flex (if (state/get-left-sidebar-open?)
+                        "0 1 20%"
+                        "0 0 0px")
+                :border-right (str "1px solid "
+                                   (if white? "#f0f8ff" "#073642"))}}
+       (when (state/sub :ui/left-sidebar-open?)
+         (sidebar-nav route-match nil))]
+      [:div#main-content-container.w-full.flex.justify-center
+       {:style {:margin-top (if global-graph-pages? 0 "2rem")}}
+       [:div.cp__sidebar-main-content
+        {:data-is-global-graph-pages global-graph-pages?
+         :data-is-full-width (or global-graph-pages?
+                                 (contains? #{:all-files :all-pages :my-publishing} route-name))}
+        (cond
+          (not indexeddb-support?)
+          nil
 
 
-         db-restoring?
-         [:div.mt-20
-          [:div.ls-center
-           (ui/loading (t :loading))]]
+          db-restoring?
+          [:div.mt-20
+           [:div.ls-center
+            (ui/loading (t :loading))]]
 
 
-         :else
-         [:div.pb-24 {:class (if global-graph-pages? "" (util/hiccup->class "max-w-7xl.mx-auto"))
-                      :style {:margin-bottom (if global-graph-pages? 0 120)}}
-          main-content])]]]))
+          :else
+          [:div.pb-24 {:class (if global-graph-pages? "" (util/hiccup->class "max-w-7xl.mx-auto"))
+                       :style {:margin-bottom (if global-graph-pages? 0 120)}}
+           main-content])]]])))
 
 
 (rum/defc footer
 (rum/defc footer
   []
   []

+ 17 - 22
src/main/frontend/handler/editor.cljs

@@ -851,16 +851,16 @@
   (when (seq block-uuids)
   (when (seq block-uuids)
     (let [lookup-refs (map (fn [id] [:block/uuid id]) block-uuids)
     (let [lookup-refs (map (fn [id] [:block/uuid id]) block-uuids)
           blocks (db/pull-many repo '[*] lookup-refs)
           blocks (db/pull-many repo '[*] lookup-refs)
-          blocks (reorder-blocks blocks)]
-      (let [start-node (outliner-core/block (first blocks))
-            end-node (get-top-level-end-node blocks)]
-        (if (= start-node end-node)
-          (delete-block-aux! (first blocks) true)
-          (when (outliner-core/delete-nodes start-node end-node lookup-refs)
-            (let [opts {:key :block/change
-                        :data blocks}]
-              (db/refresh! repo opts)
-              (ui-handler/re-render-root!))))))))
+          blocks (reorder-blocks blocks)
+          start-node (outliner-core/block (first blocks))
+          end-node (get-top-level-end-node blocks)]
+      (if (= start-node end-node)
+        (delete-block-aux! (first blocks) true)
+        (when (outliner-core/delete-nodes start-node end-node lookup-refs)
+          (let [opts {:key :block/change
+                      :data blocks}]
+            (db/refresh! repo opts)
+            (ui-handler/re-render-root!)))))))
 
 
 (defn- block-property-aux!
 (defn- block-property-aux!
   [block-id key value]
   [block-id key value]
@@ -956,11 +956,12 @@
 
 
 (defn- get-selected-blocks-with-children
 (defn- get-selected-blocks-with-children
   []
   []
-  (when-let [blocks (seq (get @state/state :selection/blocks))]
-    (mapcat (fn [block]
-              (cons block
-                    (array-seq (dom/by-class block "ls-block"))))
-            blocks)))
+  (when-let [blocks (seq (state/get-selection-blocks))]
+    (->> (mapcat (fn [block]
+                   (cons block
+                         (array-seq (dom/by-class block "ls-block"))))
+                 blocks)
+         distinct)))
 
 
 (defn- blocks-with-level
 (defn- blocks-with-level
   [blocks]
   [blocks]
@@ -1048,9 +1049,6 @@
           ids (->> (distinct (map #(when-let [id (dom/attr % "blockid")]
           ids (->> (distinct (map #(when-let [id (dom/attr % "blockid")]
                                      (uuid id)) blocks))
                                      (uuid id)) blocks))
                    (remove nil?))
                    (remove nil?))
-          ids (if (= :up (state/get-selection-direction))
-                (reverse ids)
-                ids)
           [content tree] (compose-copied-blocks-contents-&-block-tree repo ids)
           [content tree] (compose-copied-blocks-contents-&-block-tree repo ids)
           block (db/pull [:block/uuid (first ids)])]
           block (db/pull [:block/uuid (first ids)])]
       (common-handler/copy-to-clipboard-without-id-property! (:block/format block) content)
       (common-handler/copy-to-clipboard-without-id-property! (:block/format block) content)
@@ -1065,10 +1063,7 @@
     (let [blocks (remove (fn [block] (= "true" (dom/attr block "data-transclude"))) blocks)]
     (let [blocks (remove (fn [block] (= "true" (dom/attr block "data-transclude"))) blocks)]
       (when (seq blocks)
       (when (seq blocks)
         (let [repo (dom/attr (first blocks) "repo")
         (let [repo (dom/attr (first blocks) "repo")
-              ids (distinct (map #(uuid (dom/attr % "blockid")) blocks))
-              ids (if (= :up (state/get-selection-direction))
-                    (reverse ids)
-                    ids)]
+              ids (distinct (map #(uuid (dom/attr % "blockid")) blocks))]
           (delete-blocks! repo ids))))))
           (delete-blocks! repo ids))))))
 
 
 (defn- get-nearest-page
 (defn- get-nearest-page

+ 35 - 22
src/main/frontend/modules/outliner/core.cljs

@@ -440,28 +440,41 @@
   (ds/auto-transact!
   (ds/auto-transact!
    [txs-state (ds/new-outliner-txs-state)]
    [txs-state (ds/new-outliner-txs-state)]
    {:outliner-op :delete-nodes}
    {:outliner-op :delete-nodes}
-   (if (= start-node end-node)
-     (delete-node start-node true)
-     (let [sibling? (= (tree/-get-parent-id start-node)
-                       (tree/-get-parent-id end-node))
-           right-node (tree/-get-right end-node)]
-       (when (tree/satisfied-inode? right-node)
-         (let [left-node-id (if sibling?
-                              (tree/-get-id (tree/-get-left start-node))
-                              (let [end-node-left-nodes (get-left-nodes end-node (count block-ids))
-                                    parents (->>
-                                             (db/get-block-parents
-                                              (state/get-current-repo)
-                                              (tree/-get-id start-node)
-                                              1000)
-                                             (map :block/uuid)
-                                             (set))]
-                                (first (set/intersection (set end-node-left-nodes) parents))))]
-           (assert left-node-id "Can't find the left-node-id")
-           (let [new-right-node (tree/-set-left-id right-node left-node-id)]
-             (tree/-save new-right-node txs-state))))
-       (let [txs (db-outliner/del-blocks block-ids)]
-         (ds/add-txs txs-state txs))))))
+   (let [end-node-parents (->>
+                           (db/get-block-parents
+                            (state/get-current-repo)
+                            (tree/-get-id end-node)
+                            1000)
+                           (map :block/uuid)
+                           (set))
+         self-block? (contains? end-node-parents (tree/-get-id start-node))]
+     (if (or (= start-node end-node)
+             self-block?)
+       (delete-node start-node true)
+       (let [sibling? (= (tree/-get-parent-id start-node)
+                         (tree/-get-parent-id end-node))
+             right-node (tree/-get-right end-node)]
+         (when (tree/satisfied-inode? right-node)
+           (let [left-node-id (if sibling?
+                                (tree/-get-id (tree/-get-left start-node))
+                                (let [end-node-left-nodes (get-left-nodes end-node (count block-ids))
+                                      parents (->>
+                                               (db/get-block-parents
+                                                (state/get-current-repo)
+                                                (tree/-get-id start-node)
+                                                1000)
+                                               (map :block/uuid)
+                                               (set))
+                                      result (first (set/intersection (set end-node-left-nodes) parents))]
+                                  (when-not result
+                                    (util/pprint {:parents parents
+                                                  :end-node-left-nodes end-node-left-nodes}))
+                                  result))]
+             (assert left-node-id "Can't find the left-node-id")
+             (let [new-right-node (tree/-set-left-id right-node left-node-id)]
+               (tree/-save new-right-node txs-state))))
+         (let [txs (db-outliner/del-blocks block-ids)]
+           (ds/add-txs txs-state txs)))))))
 
 
 (defn first-child?
 (defn first-child?
   [node]
   [node]

+ 8 - 5
src/main/frontend/state.cljs

@@ -551,10 +551,12 @@
    (set-selection-blocks! blocks :down))
    (set-selection-blocks! blocks :down))
   ([blocks direction]
   ([blocks direction]
    (when (seq blocks)
    (when (seq blocks)
-     (swap! state assoc
-            :selection/mode true
-            :selection/blocks blocks
-            :selection/direction direction))))
+     (let [blocks (util/sort-by-height blocks)]
+       (swap! state assoc
+             :selection/mode true
+             :selection/blocks blocks
+             :selection/direction direction)))))
+
 (defn into-selection-mode!
 (defn into-selection-mode!
   []
   []
   (swap! state assoc :selection/mode true))
   (swap! state assoc :selection/mode true))
@@ -588,7 +590,8 @@
   (dom/add-class! block "selected noselect")
   (dom/add-class! block "selected noselect")
   (swap! state assoc
   (swap! state assoc
          :selection/mode true
          :selection/mode true
-         :selection/blocks (conj (:selection/blocks @state) block)
+         :selection/blocks (-> (conj (:selection/blocks @state) block)
+                               util/sort-by-height)
          :selection/direction direction))
          :selection/direction direction))
 
 
 (defn drop-last-selection-block!
 (defn drop-last-selection-block!

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

@@ -17,7 +17,8 @@
             [medley.core :as medley]
             [medley.core :as medley]
             [frontend.ui.date-picker]
             [frontend.ui.date-picker]
             [frontend.context.i18n :as i18n]
             [frontend.context.i18n :as i18n]
-            [frontend.modules.shortcut.core :as shortcut]))
+            [frontend.modules.shortcut.core :as shortcut]
+            [lambdaisland.glogi :as log]))
 
 
 (defonce transition-group (r/adapt-class TransitionGroup))
 (defonce transition-group (r/adapt-class TransitionGroup))
 (defonce css-transition (r/adapt-class CSSTransition))
 (defonce css-transition (r/adapt-class CSSTransition))
@@ -566,6 +567,9 @@
        (js/console.dir error)
        (js/console.dir error)
        (assoc state ::error error))}
        (assoc state ::error error))}
   [{error ::error, c :rum/react-component} error-view view]
   [{error ::error, c :rum/react-component} error-view view]
+  (when error
+    (js/console.error error)
+    (log/error :ui/catch-error error))
   (if (some? error)
   (if (some? error)
     error-view
     error-view
     view))
     view))

+ 12 - 0
src/main/frontend/util.cljc

@@ -1235,3 +1235,15 @@
                    (when v (name k)))
                    (when v (name k)))
                  (name %))
                  (name %))
               args)))
               args)))
+
+#?(:cljs
+   (defn- get-dom-top
+     [node]
+     (gobj/get (.getBoundingClientRect node) "top")))
+
+#?(:cljs
+   (defn sort-by-height
+     [elements]
+     (sort (fn [x y]
+             (< (get-dom-top x) (get-dom-top y)))
+           elements)))