Browse Source

enhance: set left sidebar text weight to be font-medium

Tienson Qin 10 tháng trước cách đây
mục cha
commit
aaccbca364
1 tập tin đã thay đổi với 466 bổ sung467 xóa
  1. 466 467
      src/main/frontend/components/container.cljs

+ 466 - 467
src/main/frontend/components/container.cljs

@@ -68,9 +68,9 @@
      [:div.sidebar-content-group-inner
       [:div.hd.items-center
        (cond-> (merge header-props
-                 {:class (util/classnames [(:class header-props)
-                                           {:non-collapsable (false? collapsable?)
-                                            :enter-show-more (true? enter-show-more?)}])})
+                      {:class (util/classnames [(:class header-props)
+                                                {:non-collapsable (false? collapsable?)
+                                                 :enter-show-more (true? enter-show-more?)}])})
 
          (not (false? collapsable?))
          (assoc :on-click (fn [^js/MouseEvent _e]
@@ -90,54 +90,54 @@
         file-rpath (when (util/electron?) (page-util/get-page-file-rpath name))
         ctx-icon #(shui/tabler-icon %1 {:class "scale-90 pr-1 opacity-80"})
         open-in-sidebar #(state/sidebar-add-block!
-                           (state/get-current-repo)
-                           (:db/id page)
-                           :page)
+                          (state/get-current-repo)
+                          (:db/id page)
+                          :page)
         x-menu-content (fn []
                          (let [x-menu-item shui/dropdown-menu-item
                                x-menu-shortcut shui/dropdown-menu-shortcut]
                            [:<>
                             (when-not recent?
                               (x-menu-item
-                                {:on-click #(page-handler/<unfavorite-page! (if db-based? (str (:block/uuid page)) title))}
-                                (ctx-icon "star-off")
-                                (t :page/unfavorite)
-                                (x-menu-shortcut (when-let [binding (shortcut-dh/shortcut-binding :command/toggle-favorite)]
-                                                   (some-> binding
-                                                     (first)
-                                                     (shortcut-utils/decorate-binding))))))
+                               {:on-click #(page-handler/<unfavorite-page! (if db-based? (str (:block/uuid page)) title))}
+                               (ctx-icon "star-off")
+                               (t :page/unfavorite)
+                               (x-menu-shortcut (when-let [binding (shortcut-dh/shortcut-binding :command/toggle-favorite)]
+                                                  (some-> binding
+                                                          (first)
+                                                          (shortcut-utils/decorate-binding))))))
                             (when-let [page-fpath (and (util/electron?) file-rpath
-                                                    (config/get-repo-fpath (state/get-current-repo) file-rpath))]
+                                                       (config/get-repo-fpath (state/get-current-repo) file-rpath))]
                               [:<>
                                (x-menu-item
-                                 {:on-click #(ipc/ipc :openFileInFolder page-fpath)}
-                                 (ctx-icon "folder")
-                                 (t :page/open-in-finder))
+                                {:on-click #(ipc/ipc :openFileInFolder page-fpath)}
+                                (ctx-icon "folder")
+                                (t :page/open-in-finder))
 
                                (x-menu-item
-                                 {:on-click #(js/window.apis.openPath page-fpath)}
-                                 (ctx-icon "file")
-                                 (t :page/open-with-default-app))])
+                                {:on-click #(js/window.apis.openPath page-fpath)}
+                                (ctx-icon "file")
+                                (t :page/open-with-default-app))])
                             (x-menu-item
-                              {:on-click open-in-sidebar}
-                              (ctx-icon "layout-sidebar-right")
-                              (t :content/open-in-sidebar)
-                              (x-menu-shortcut (shortcut-utils/decorate-binding "shift+click")))]))]
+                             {:on-click open-in-sidebar}
+                             (ctx-icon "layout-sidebar-right")
+                             (t :content/open-in-sidebar)
+                             (x-menu-shortcut (shortcut-utils/decorate-binding "shift+click")))]))]
 
     ;; TODO: move to standalone component
     [:a.link-item.group
      (cond->
-       {:on-click
-        (fn [e]
-          (if (gobj/get e "shiftKey")
-            (open-in-sidebar)
-            (route-handler/redirect-to-page! (:block/uuid page) {:click-from-recent? recent?})))
-        :on-context-menu (fn [^js e]
-                           (shui/popup-show! e (x-menu-content)
-                             {:as-dropdown? true
-                              :content-props {:on-click (fn [] (shui/popup-hide!))
-                                              :class "w-60"}})
-                           (util/stop e))}
+      {:on-click
+       (fn [e]
+         (if (gobj/get e "shiftKey")
+           (open-in-sidebar)
+           (route-handler/redirect-to-page! (:block/uuid page) {:click-from-recent? recent?})))
+       :on-context-menu (fn [^js e]
+                          (shui/popup-show! e (x-menu-content)
+                                            {:as-dropdown? true
+                                             :content-props {:on-click (fn [] (shui/popup-hide!))
+                                                             :class "w-60"}})
+                          (util/stop e))}
        (ldb/object? page)
        (assoc :title (title/block-unique-title page)))
      [:span.page-icon icon]
@@ -155,22 +155,22 @@
 
      ;; dots trigger
      (shui/button
-       {:size :sm
-        :variant :ghost
-        :class "absolute !bg-transparent right-0 top-0 px-1.5 scale-75 opacity-40 hidden group-hover:block hover:opacity-80 active:opacity-100"
-        :on-click #(do
-                     (shui/popup-show! (.-target %) (x-menu-content)
-                       {:as-dropdown? true
-                        :content-props {:on-click (fn [] (shui/popup-hide!))
-                                        :class "w-60"}})
-                     (util/stop %))}
-       [:i.relative {:style {:top "4px"}} (shui/tabler-icon "dots")])]))
+      {:size :sm
+       :variant :ghost
+       :class "absolute !bg-transparent right-0 top-0 px-1.5 scale-75 opacity-40 hidden group-hover:block hover:opacity-80 active:opacity-100"
+       :on-click #(do
+                    (shui/popup-show! (.-target %) (x-menu-content)
+                                      {:as-dropdown? true
+                                       :content-props {:on-click (fn [] (shui/popup-hide!))
+                                                       :class "w-60"}})
+                    (util/stop %))}
+      [:i.relative {:style {:top "4px"}} (shui/tabler-icon "dots")])]))
 
 (defn sidebar-item
   [{:keys [on-click-handler class title icon icon-extension? active href shortcut more]}]
   [:div
    {:class (util/classnames [class {:active active}])}
-   [:a.item.group.flex.items-center.text-sm.rounded-md
+   [:a.item.group.flex.items-center.text-sm.rounded-md.font-medium
     {:on-click on-click-handler
      :class (when active "active")
      :href href}
@@ -179,7 +179,7 @@
     (when shortcut
       [:span.ml-1
        (ui/render-keyboard-shortcut
-         (ui/keyboard-shortcut-from-config shortcut {:pick-first? true}))])
+        (ui/keyboard-shortcut-from-config shortcut {:pick-first? true}))])
     more]])
 
 (rum/defc sidebar-graphs
@@ -192,185 +192,184 @@
   (let [[local-navs set-local-navs!] (rum/use-state checked-navs)]
 
     (rum/use-effect!
-      (fn []
-        (set-checked-navs! local-navs))
-      [local-navs])
+     (fn []
+       (set-checked-navs! local-navs))
+     [local-navs])
 
     (for [nav navs
           :let [name' (name nav)]]
       (shui/dropdown-menu-checkbox-item
-        {:checked (contains? (set local-navs) nav)
-         :onCheckedChange (fn [v] (set-local-navs!
-                                    (fn []
-                                      (if v
-                                        (conj local-navs nav)
-                                        (filterv #(not= nav %) local-navs)))))}
-        (tt (keyword "left-side-bar" name')
-          (keyword "right-side-bar" name'))))))
+       {:checked (contains? (set local-navs) nav)
+        :onCheckedChange (fn [v] (set-local-navs!
+                                  (fn []
+                                    (if v
+                                      (conj local-navs nav)
+                                      (filterv #(not= nav %) local-navs)))))}
+       (tt (keyword "left-side-bar" name')
+           (keyword "right-side-bar" name'))))))
 
 (rum/defc ^:large-vars/cleanup-todo sidebar-navigations
   [{:keys [default-home route-match route-name srs-open? db-based? enable-whiteboards?]}]
   (let [navs [:whiteboards :flashcards :graph-view :all-pages :tag/tasks :tag/assets]
         [checked-navs set-checked-navs!] (rum/use-state (or (storage/get :ls-sidebar-navigations)
-                                                          [:whiteboards :flashcards :graph-view :all-pages :tag/tasks]))]
+                                                            [:whiteboards :flashcards :graph-view :all-pages :tag/tasks]))]
 
     (rum/use-effect!
-      (fn []
-        (when (vector? checked-navs)
-          (storage/set :ls-sidebar-navigations checked-navs)))
-      [checked-navs])
+     (fn []
+       (when (vector? checked-navs)
+         (storage/set :ls-sidebar-navigations checked-navs)))
+     [checked-navs])
 
     (sidebar-content-group
-      [:a.wrap-th [:strong.flex-1 "Navigations"]]
-      {:collapsable? false
-       :enter-show-more? true
-       :header-props {:on-click (fn [^js e] (when-let [^js _el (some-> (.-target e) (.closest ".as-edit"))]
-                                              (shui/popup-show! _el
-                                                #(sidebar-navigations-edit-content
-                                                   {:id (:id %) :navs navs
-                                                    :checked-navs checked-navs
-                                                    :set-checked-navs! set-checked-navs!})
-                                                {:as-dropdown? false})))}
-       :more [:a.as-edit {:class "!opacity-60 hover:!opacity-80 relative -top-0.5 right-0"}
-              (shui/tabler-icon "filter-edit" {:size 15})]}
-      [:div.sidebar-navigations.flex.flex-col.mt-1
+     [:a.wrap-th [:strong.flex-1 "Navigations"]]
+     {:collapsable? false
+      :enter-show-more? true
+      :header-props {:on-click (fn [^js e] (when-let [^js _el (some-> (.-target e) (.closest ".as-edit"))]
+                                             (shui/popup-show! _el
+                                                               #(sidebar-navigations-edit-content
+                                                                 {:id (:id %) :navs navs
+                                                                  :checked-navs checked-navs
+                                                                  :set-checked-navs! set-checked-navs!})
+                                                               {:as-dropdown? false})))}
+      :more [:a.as-edit {:class "!opacity-60 hover:!opacity-80 relative -top-0.5 right-0"}
+             (shui/tabler-icon "filter-edit" {:size 15})]}
+     [:div.sidebar-navigations.flex.flex-col.mt-1
        ;; required custom home page
-       (let [page (:page default-home)]
-         (if (and page (not (state/enable-journals? (state/get-current-repo))))
-           (sidebar-item
-             {:class "home-nav"
-              :title page
-              :on-click-handler route-handler/redirect-to-home!
-              :active (and (not srs-open?)
-                        (= route-name :page)
-                        (= page (get-in route-match [:path-params :name])))
-              :icon "home"
-              :shortcut :go/home})
-
-           (sidebar-item
-             {:class "journals-nav"
-              :active (and (not srs-open?)
-                        (or (= route-name :all-journals) (= route-name :home)))
-              :title (t :left-side-bar/journals)
-              :on-click-handler (fn [e]
-                                  (if (gobj/get e "shiftKey")
-                                    (route-handler/sidebar-journals!)
-                                    (route-handler/go-to-journals!)))
-              :icon "calendar"
-              :shortcut :go/journals})))
-
-       (for [nav checked-navs]
-         (cond
-           (= nav :whiteboards)
-           (when enable-whiteboards?
-             (when (or config/dev? (not db-based?))
-               (sidebar-item
-                 {:class "whiteboard"
-                  :title (t :right-side-bar/whiteboards)
-                  :href (rfe/href :whiteboards)
-                  :on-click-handler (fn [_e] (whiteboard-handler/onboarding-show))
-                  :active (and (not srs-open?) (#{:whiteboard :whiteboards} route-name))
-                  :icon "whiteboard"
-                  :icon-extension? true
-                  :shortcut :go/whiteboards})))
-
-           (= nav :flashcards)
-           (when (state/enable-flashcards? (state/get-current-repo))
-             (let [num (state/sub :srs/cards-due-count)]
-               (sidebar-item
-                 {:class "flashcards-nav"
-                  :title (t :right-side-bar/flashcards)
-                  :icon "infinity"
-                  :shortcut :go/flashcards
-                  :active srs-open?
-                  :on-click-handler #(do (fsrs/update-due-cards-count)
+      (let [page (:page default-home)]
+        (if (and page (not (state/enable-journals? (state/get-current-repo))))
+          (sidebar-item
+           {:class "home-nav"
+            :title page
+            :on-click-handler route-handler/redirect-to-home!
+            :active (and (not srs-open?)
+                         (= route-name :page)
+                         (= page (get-in route-match [:path-params :name])))
+            :icon "home"
+            :shortcut :go/home})
+
+          (sidebar-item
+           {:class "journals-nav"
+            :active (and (not srs-open?)
+                         (or (= route-name :all-journals) (= route-name :home)))
+            :title (t :left-side-bar/journals)
+            :on-click-handler (fn [e]
+                                (if (gobj/get e "shiftKey")
+                                  (route-handler/sidebar-journals!)
+                                  (route-handler/go-to-journals!)))
+            :icon "calendar"
+            :shortcut :go/journals})))
+
+      (for [nav checked-navs]
+        (cond
+          (= nav :whiteboards)
+          (when enable-whiteboards?
+            (when (or config/dev? (not db-based?))
+              (sidebar-item
+               {:class "whiteboard"
+                :title (t :right-side-bar/whiteboards)
+                :href (rfe/href :whiteboards)
+                :on-click-handler (fn [_e] (whiteboard-handler/onboarding-show))
+                :active (and (not srs-open?) (#{:whiteboard :whiteboards} route-name))
+                :icon "whiteboard"
+                :icon-extension? true
+                :shortcut :go/whiteboards})))
+
+          (= nav :flashcards)
+          (when (state/enable-flashcards? (state/get-current-repo))
+            (let [num (state/sub :srs/cards-due-count)]
+              (sidebar-item
+               {:class "flashcards-nav"
+                :title (t :right-side-bar/flashcards)
+                :icon "infinity"
+                :shortcut :go/flashcards
+                :active srs-open?
+                :on-click-handler #(do (fsrs/update-due-cards-count)
                                        (state/pub-event! [:modal/show-cards]))
-                  :more (when (and num (not (zero? num)))
-                          [:span.ml-1.inline-block.py-0.5.px-3.text-xs.font-medium.rounded-full.fade-in num])})))
-
-           (= nav :graph-view)
-           (sidebar-item
-             {:class "graph-view-nav"
-              :title (t :right-side-bar/graph-view)
-              :href (rfe/href :graph)
-              :active (and (not srs-open?) (= route-name :graph))
-              :icon "hierarchy"
-              :shortcut :go/graph-view})
-
-           (= nav :all-pages)
-           (sidebar-item
-             {:class "all-pages-nav"
-              :title (t :right-side-bar/all-pages)
-              :href (rfe/href :all-pages)
-              :active (and (not srs-open?) (= route-name :all-pages))
-              :icon "files"})
-
-           (= (namespace nav) "tag")
-           (when db-based?
-             (let [name'' (name nav)
-                   name' (get {"assets" "Asset" "tasks" "Task"} name'')]
-               (when-let [tag-uuid (and name' (:block/uuid (db/entity (keyword "logseq.class" name'))))]
-                 (sidebar-item
-                   {:class (str "tag-view-nav " name'')
-                    :title (tt (keyword "left-side-bar" name'')
+                :more (when (and num (not (zero? num)))
+                        [:span.ml-1.inline-block.py-0.5.px-3.text-xs.font-medium.rounded-full.fade-in num])})))
+
+          (= nav :graph-view)
+          (sidebar-item
+           {:class "graph-view-nav"
+            :title (t :right-side-bar/graph-view)
+            :href (rfe/href :graph)
+            :active (and (not srs-open?) (= route-name :graph))
+            :icon "hierarchy"
+            :shortcut :go/graph-view})
+
+          (= nav :all-pages)
+          (sidebar-item
+           {:class "all-pages-nav"
+            :title (t :right-side-bar/all-pages)
+            :href (rfe/href :all-pages)
+            :active (and (not srs-open?) (= route-name :all-pages))
+            :icon "files"})
+
+          (= (namespace nav) "tag")
+          (when db-based?
+            (let [name'' (name nav)
+                  name' (get {"assets" "Asset" "tasks" "Task"} name'')]
+              (when-let [tag-uuid (and name' (:block/uuid (db/entity (keyword "logseq.class" name'))))]
+                (sidebar-item
+                 {:class (str "tag-view-nav " name'')
+                  :title (tt (keyword "left-side-bar" name'')
                              (keyword "right-side-bar" name''))
-                    :href (rfe/href :page {:name tag-uuid})
-                    :active (= (str tag-uuid) (get-in route-match [:path-params :name]))
-                    :icon "hash"}))))))
-       ])))
+                  :href (rfe/href :page {:name tag-uuid})
+                  :active (= (str tag-uuid) (get-in route-match [:path-params :name]))
+                  :icon "hash"}))))))])))
 
 (rum/defc sidebar-favorites < rum/reactive
   []
   (let [_favorites-updated? (state/sub :favorites/updated?)
         favorite-entities (page-handler/get-favorites)]
     (sidebar-content-group
-      [:a.wrap-th
-       [:strong.flex-1 (t :left-side-bar/nav-favorites)]]
-
-      {:class "favorites"
-       :count (count favorite-entities)
-       :edit-fn
-       (fn [e]
-         (rfe/push-state :page {:name "Favorites"})
-         (util/stop e))}
-      (when (seq favorite-entities)
-        (let [favorite-items (map
-                               (fn [e]
-                                 (let [icon (icon/get-node-icon-cp e {:size 16})]
-                                   {:id (str (:db/id e))
-                                    :value (:block/uuid e)
-                                    :content [:li.favorite-item (page-name e icon false)]}))
-                               favorite-entities)]
-          (dnd-component/items favorite-items
-            {:on-drag-end (fn [favorites']
-                            (page-handler/<reorder-favorites! favorites'))
-             :parent-node :ul.favorites.text-sm}))))))
+     [:a.wrap-th
+      [:strong.flex-1 (t :left-side-bar/nav-favorites)]]
+
+     {:class "favorites"
+      :count (count favorite-entities)
+      :edit-fn
+      (fn [e]
+        (rfe/push-state :page {:name "Favorites"})
+        (util/stop e))}
+     (when (seq favorite-entities)
+       (let [favorite-items (map
+                             (fn [e]
+                               (let [icon (icon/get-node-icon-cp e {:size 16})]
+                                 {:id (str (:db/id e))
+                                  :value (:block/uuid e)
+                                  :content [:li.favorite-item.font-medium (page-name e icon false)]}))
+                             favorite-entities)]
+         (dnd-component/items favorite-items
+                              {:on-drag-end (fn [favorites']
+                                              (page-handler/<reorder-favorites! favorites'))
+                               :parent-node :ul.favorites.text-sm}))))))
 
 (rum/defc sidebar-recent-pages < rum/reactive db-mixins/query
   []
   (let [pages (recent-handler/get-recent-pages)]
     (sidebar-content-group
-      [:a.wrap-th [:strong.flex-1 (t :left-side-bar/nav-recent-pages)]]
+     [:a.wrap-th [:strong.flex-1 (t :left-side-bar/nav-recent-pages)]]
 
-      {:class "recent"
-       :count (count pages)}
+     {:class "recent"
+      :count (count pages)}
 
-      [:ul.text-sm
-       (for [page pages]
-         [:li.recent-item.select-none
-          {:key (str "recent-" (:db/id page))
-           :title (title/block-unique-title page)
-           :draggable true
-           :on-drag-start (fn [event] (editor-handler/block->data-transfer! (:block/name page) event true))
-           :data-ref name}
-          (page-name page (icon/get-node-icon-cp page {:size 16}) true)])])))
+     [:ul.text-sm
+      (for [page pages]
+        [:li.recent-item.select-none.font-medium
+         {:key (str "recent-" (:db/id page))
+          :title (title/block-unique-title page)
+          :draggable true
+          :on-drag-start (fn [event] (editor-handler/block->data-transfer! (:block/name page) event true))
+          :data-ref name}
+         (page-name page (icon/get-node-icon-cp page {:size 16}) true)])])))
 
 (defn get-default-home-if-valid
   []
   (when-let [default-home (state/get-default-home)]
     (let [page (:page default-home)
           page (when (and (string? page)
-                       (not (string/blank? page)))
+                          (not (string/blank? page)))
                  (db/get-page page))]
       (if page
         default-home
@@ -401,43 +400,43 @@
                               (when (< touching-x-offset 0)
                                 (max touching-x-offset (- 0 (:width el-rect))))))
         offset-ratio (and (number? touching-x-offset)
-                       (some->> (:width el-rect)
-                         (/ touching-x-offset)))]
+                          (some->> (:width el-rect)
+                                   (/ touching-x-offset)))]
 
     (rum/use-effect!
-      #(js/setTimeout
-         (fn [] (some-> (rum/deref ref-el)
-                  (.getBoundingClientRect)
-                  (.toJSON)
-                  (js->clj :keywordize-keys true)
-                  (set-el-rect!)))
-         16)
-      [])
+     #(js/setTimeout
+       (fn [] (some-> (rum/deref ref-el)
+                      (.getBoundingClientRect)
+                      (.toJSON)
+                      (js->clj :keywordize-keys true)
+                      (set-el-rect!)))
+       16)
+     [])
 
     (rum/use-layout-effect!
-      (fn []
-        (when (and (rum/deref ref-open?) local-closing?)
-          (reset! *closing? true))
-        (rum/set-ref! ref-open? left-sidebar-open?)
-        #())
-      [local-closing? left-sidebar-open?])
+     (fn []
+       (when (and (rum/deref ref-open?) local-closing?)
+         (reset! *closing? true))
+       (rum/set-ref! ref-open? left-sidebar-open?)
+       #())
+     [local-closing? left-sidebar-open?])
 
     (rum/use-effect!
-      (fn []
-        (when-not (neg? close-signal)
-          (close-fn)))
-      [close-signal])
+     (fn []
+       (when-not (neg? close-signal)
+         (close-fn)))
+     [close-signal])
 
     [:<>
      [:div.left-sidebar-inner.flex-1.flex.flex-col.min-h-0
       {:ref ref-el
        :style (cond-> {}
                 (and (number? offset-ratio)
-                  (> touching-x-offset 0))
+                     (> touching-x-offset 0))
                 (assoc :transform (str "translate3d(calc(" touching-x-offset "px - 100%), 0, 0)"))
 
                 (and (number? offset-ratio)
-                  (< touching-x-offset 0))
+                     (< touching-x-offset 0))
                 (assoc :transform (str "translate3d(" (* offset-ratio 100) "%, 0, 0)")))
        :on-transition-end (fn []
                             (when local-closing?
@@ -446,7 +445,7 @@
                               (close-modal-fn)))
        :on-click #(when-let [^js target (and (util/sm-breakpoint?) (.-target %))]
                     (when (some (fn [sel] (boolean (.closest target sel)))
-                            [".favorites .bd" ".recent .bd" ".dropdown-wrapper" ".nav-header"])
+                                [".favorites .bd" ".recent .bd" ".dropdown-wrapper" ".nav-header"])
                       (close-fn)))}
 
       [:div.wrap
@@ -456,12 +455,12 @@
 
         ;; sidebar sticky navigations
         (sidebar-navigations
-          {:default-home default-home
-           :route-match route-match
-           :db-based? db-based?
-           :enable-whiteboards? enable-whiteboards?
-           :route-name route-name
-           :srs-open? srs-open?})]
+         {:default-home default-home
+          :route-match route-match
+          :db-based? db-based?
+          :enable-whiteboards? enable-whiteboards?
+          :route-name route-name
+          :srs-open? srs-open?})]
 
        [:div.sidebar-contents-container
         {:on-scroll on-contents-scroll}
@@ -487,38 +486,38 @@
 
     ;; restore size
     (rum/use-layout-effect!
-      (fn []
-        (when-let [width (storage/get :ls-left-sidebar-width)]
-          (.setProperty (.-style el-doc) "--ls-left-sidebar-width" width)))
-      [])
+     (fn []
+       (when-let [width (storage/get :ls-left-sidebar-width)]
+         (.setProperty (.-style el-doc) "--ls-left-sidebar-width" width)))
+     [])
 
     ;; draggable handler
     (rum/use-effect!
-      (fn []
-        (when-let [el (and (fn? js/window.interact) (rum/deref *el-ref))]
-          (let [^js sidebar-el (.querySelector el-doc "#left-sidebar")]
-            (-> (js/interact el)
-              (.draggable
+     (fn []
+       (when-let [el (and (fn? js/window.interact) (rum/deref *el-ref))]
+         (let [^js sidebar-el (.querySelector el-doc "#left-sidebar")]
+           (-> (js/interact el)
+               (.draggable
                 #js {:listeners
                      #js {:move (fn [^js/MouseEvent e]
                                   (when-let [offset (.-left (.-rect e))]
                                     (let [width (.toFixed (max (min offset 460) 240) 2)]
                                       (adjust-size! (str width "px")))))}})
-              (.styleCursor false)
-              (.on "dragstart" (fn []
-                                 (.. sidebar-el -classList (add "is-resizing"))
-                                 (.. el-doc -classList (add "is-resizing-buf"))))
-              (.on "dragend" (fn []
-                               (.. sidebar-el -classList (remove "is-resizing"))
-                               (.. el-doc -classList (remove "is-resizing-buf"))))))
-          #()))
-      [])
+               (.styleCursor false)
+               (.on "dragstart" (fn []
+                                  (.. sidebar-el -classList (add "is-resizing"))
+                                  (.. el-doc -classList (add "is-resizing-buf"))))
+               (.on "dragend" (fn []
+                                (.. sidebar-el -classList (remove "is-resizing"))
+                                (.. el-doc -classList (remove "is-resizing-buf"))))))
+         #()))
+     [])
     [:span.left-sidebar-resizer {:ref *el-ref}]))
 
 (rum/defcs left-sidebar < rum/reactive
-                          (rum/local false ::closing?)
-                          (rum/local -1 ::close-signal)
-                          (rum/local nil ::touch-state)
+  (rum/local false ::closing?)
+  (rum/local -1 ::close-signal)
+  (rum/local nil ::touch-state)
   [s {:keys [left-sidebar-open? route-match]}]
   (let [close-fn #(state/set-left-sidebar-open! false)
         *closing? (::closing? s)
@@ -528,9 +527,9 @@
         touch-point-fn (fn [^js e] (some-> (gobj/get e "touches") (aget 0) (#(hash-map :x (.-clientX %) :y (.-clientY %)))))
         srs-open? (= :srs (state/sub :modal/id))
         touching-x-offset (and (some-> @*touch-state :after)
-                            (some->> @*touch-state
-                              ((juxt :after :before))
-                              (map :x) (apply -)))
+                               (some->> @*touch-state
+                                        ((juxt :after :before))
+                                        (map :x) (apply -)))
         touch-pending? (> (abs touching-x-offset) 20)]
 
     [:div#left-sidebar.cp__sidebar-left-layout
@@ -557,7 +556,7 @@
 
      ;; sidebar contents
      (sidebar-container route-match close-fn left-sidebar-open? enable-whiteboards? srs-open? *closing?
-       @*close-signal (and touch-pending? touching-x-offset))
+                        @*close-signal (and touch-pending? touching-x-offset))
 
      ;; resizer
      (sidebar-resizer)]))
@@ -582,12 +581,12 @@
   {:did-mount (fn [state]
                 (when-let [element (gdom/getElement "main-content-container")]
                   (dnd/subscribe!
-                    element
-                    :upload-files
-                    {:drop (fn [_e files]
-                             (when-let [id (state/get-edit-input-id)]
-                               (let [format (:block/format (state/get-edit-block))]
-                                 (editor-handler/upload-asset! id files format editor-handler/*asset-uploading? true))))})
+                   element
+                   :upload-files
+                   {:drop (fn [_e files]
+                            (when-let [id (state/get-edit-input-id)]
+                              (let [format (:block/format (state/get-edit-block))]
+                                (editor-handler/upload-asset! id files format editor-handler/*asset-uploading? true))))})
                   (common-handler/listen-to-scroll! element)
                   (when (:margin-less-pages? (first (:rum/args state))) ;; makes sure full screen pages displaying without scrollbar
                     (set! (.. element -scrollTop) 0)))
@@ -599,8 +598,8 @@
   [{:keys [route-match margin-less-pages? route-name indexeddb-support? db-restoring? main-content show-action-bar? show-recording-bar?]}]
   (let [left-sidebar-open? (state/sub :ui/left-sidebar-open?)
         onboarding-and-home? (and (or (nil? (state/get-current-repo)) (config/demo-graph?))
-                               (not config/publishing?)
-                               (= :home route-name))
+                                  (not config/publishing?)
+                                  (= :home route-name))
         margin-less-pages? (or (and (mobile-util/native-platform?) onboarding-and-home?) margin-less-pages?)]
     [:div#main-container.cp__sidebar-main-layout.flex-1.flex
      {:class (util/classnames [{:is-left-sidebar-open left-sidebar-open?}])}
@@ -620,7 +619,7 @@
       [:div.cp__sidebar-main-content
        {:data-is-margin-less-pages margin-less-pages?
         :data-is-full-width (or margin-less-pages?
-                              (contains? #{:all-files :all-pages :my-publishing} route-name))}
+                                (contains? #{:all-files :all-pages :my-publishing} route-name))}
 
        (when show-recording-bar?
          (recording-bar))
@@ -665,8 +664,8 @@
         total (:total state)
         width (js/Math.round (* (.toFixed (/ finished total) 2) 100))
         display-filename (some-> (:current-parsing-file state)
-                           not-empty
-                           path/filename)
+                                 not-empty
+                                 path/filename)
         left-label [:div.flex.flex-row.font-bold
                     (t :parsing-files)
                     [:div.hidden.md:flex.flex-row
@@ -676,24 +675,24 @@
     (ui/progress-bar-with-label width left-label (str finished "/" total))))
 
 (rum/defc main-content < rum/reactive db-mixins/query
-                         {:init (fn [state]
-                                  (when-not @sidebar-inited?
-                                    (let [current-repo (state/sub :git/current-repo)
-                                          default-home (get-default-home-if-valid)
-                                          sidebar (:sidebar default-home)
-                                          sidebar (if (string? sidebar) [sidebar] sidebar)]
-                                      (when-let [pages (->> (seq sidebar)
-                                                         (remove string/blank?))]
-                                        (doseq [page pages]
-                                          (let [page (util/safe-page-name-sanity-lc page)
-                                                [db-id block-type] (if (= page "contents")
-                                                                     [(or (:db/id (db/get-page page)) "contents") :contents]
-                                                                     [(:db/id (db/get-page page)) :page])]
-                                            (state/sidebar-add-block! current-repo db-id block-type)))
-                                        (reset! sidebar-inited? true))))
-                                  (when (state/mobile?)
-                                    (state/set-state! :mobile/show-tabbar? true))
-                                  state)}
+  {:init (fn [state]
+           (when-not @sidebar-inited?
+             (let [current-repo (state/sub :git/current-repo)
+                   default-home (get-default-home-if-valid)
+                   sidebar (:sidebar default-home)
+                   sidebar (if (string? sidebar) [sidebar] sidebar)]
+               (when-let [pages (->> (seq sidebar)
+                                     (remove string/blank?))]
+                 (doseq [page pages]
+                   (let [page (util/safe-page-name-sanity-lc page)
+                         [db-id block-type] (if (= page "contents")
+                                              [(or (:db/id (db/get-page page)) "contents") :contents]
+                                              [(:db/id (db/get-page page)) :page])]
+                     (state/sidebar-add-block! current-repo db-id block-type)))
+                 (reset! sidebar-inited? true))))
+           (when (state/mobile?)
+             (state/set-state! :mobile/show-tabbar? true))
+           state)}
   []
   (let [default-home (get-default-home-if-valid)
         current-repo (state/sub :git/current-repo)
@@ -703,8 +702,8 @@
         graph-parsing-state (state/sub [:graph/parsing-state current-repo])]
     (cond
       (or
-        (:graph-loading? graph-parsing-state)
-        (not= (:total graph-parsing-state) (:finished graph-parsing-state)))
+       (:graph-loading? graph-parsing-state)
+       (not= (:total graph-parsing-state) (:finished graph-parsing-state)))
       [:div.flex.items-center.justify-center.full-height-without-header
        [:div.flex-1
         (parsing-progress graph-parsing-state)]]
@@ -713,14 +712,14 @@
       [:div
        (cond
          (and default-home
-           (= :home (state/get-current-route))
-           (not (state/route-has-p?))
-           (:page default-home))
+              (= :home (state/get-current-route))
+              (not (state/route-has-p?))
+              (:page default-home))
          (route-handler/redirect-to-page! (:page default-home))
 
          (and config/publishing?
-           (not default-home)
-           (empty? latest-journals))
+              (not default-home)
+              (empty? latest-journals))
          (route-handler/redirect! {:to :all-pages})
 
          loading-files?
@@ -737,21 +736,21 @@
   [e]
   (state/hide-custom-context-menu!)
   (when-not (or (gobj/get e "shiftKey")
-              (util/meta-key? e)
-              (state/get-edit-input-id)
-              (= (shui-dialog/get-last-modal-id) :property-dialog)
-              (some-> (.-target e) (.closest ".ls-block"))
-              (some-> (.-target e) (.closest "[data-keep-selection]")))
+                (util/meta-key? e)
+                (state/get-edit-input-id)
+                (= (shui-dialog/get-last-modal-id) :property-dialog)
+                (some-> (.-target e) (.closest ".ls-block"))
+                (some-> (.-target e) (.closest "[data-keep-selection]")))
     (editor-handler/clear-selection!)))
 
 (rum/defc render-custom-context-menu
   [links position]
   (let [ref (rum/use-ref nil)]
     (rum/use-effect!
-      #(let [el (rum/deref ref)
-             {:keys [x y]} (util/calc-delta-rect-offset el js/document.documentElement)]
-         (set! (.. el -style -transform)
-           (str "translate3d(" (if (neg? x) x 0) "px," (if (neg? y) (- y 10) 0) "px" ",0)"))))
+     #(let [el (rum/deref ref)
+            {:keys [x y]} (util/calc-delta-rect-offset el js/document.documentElement)]
+        (set! (.. el -style -transform)
+              (str "translate3d(" (if (neg? x) x 0) "px," (if (neg? y) (- y 10) 0) "px" ",0)"))))
     [:<>
      [:div.menu-backdrop {:on-pointer-down (fn [e] (hide-context-menu-and-clear-selection e))}]
      [:div#custom-context-menu
@@ -781,9 +780,9 @@
                         [:p.inline-block.mr-1 "Click `D` or type"]
                         [:div.inline-block.mr-1 (ui/render-keyboard-shortcut (shortcut-dh/gen-shortcut-seq :ui/toggle-document-mode))]
                         [:p.inline-block "to toggle document mode"]]]]}
-      [:a.block.px-1.text-sm.font-medium.bg-base-2.rounded-md.mx-2
-       {:on-click state/toggle-document-mode!}
-       "D"])))
+              [:a.block.px-1.text-sm.font-medium.bg-base-2.rounded-md.mx-2
+               {:on-click state/toggle-document-mode!}
+               "D"])))
 
 (def help-menu-items
   [{:title "Handbook" :icon "book-2" :on-click #(handbooks/toggle-handbooks)}
@@ -803,16 +802,16 @@
   []
 
   (rum/use-effect!
-    (fn []
-      (state/set-state! :ui/handbooks-open? false))
-    [])
+   (fn []
+     (state/set-state! :ui/handbooks-open? false))
+   [])
 
   (rum/use-effect!
-    (fn []
-      (let [h #(state/set-state! :ui/help-open? false)]
-        (.addEventListener js/document.body "click" h)
-        #(.removeEventListener js/document.body "click" h)))
-    [])
+   (fn []
+     (let [h #(state/set-state! :ui/help-open? false)]
+       (.addEventListener js/document.body "click" h)
+       #(.removeEventListener js/document.body "click" h)))
+   [])
 
   [:div.cp__sidebar-help-menu-popup
    [:div.list-wrap
@@ -856,83 +855,83 @@
 
 (rum/defc app-context-menu-observer
   < rum/static
-    (mixins/event-mixin
-      (fn [state]
+  (mixins/event-mixin
+   (fn [state]
         ;; fixme: this mixin will register global event listeners on window
         ;; which might cause unexpected issues
-        (mixins/listen state js/window "contextmenu"
-          (fn [^js e]
-            (let [target (gobj/get e "target")
-                  block-el (.closest target ".bullet-container[blockid]")
-                  block-id (some-> block-el (.getAttribute "blockid"))
-                  {:keys [block block-ref]} (state/sub :block-ref/context)
-                  {:keys [page page-entity]} (state/sub :page-title/context)]
-
-              (let [show!
-                    (fn [content]
-                      (shui/popup-show! e
-                        (fn [{:keys [id]}]
-                          [:div {:on-click #(shui/popup-hide! id)
-                                 :data-keep-selection true}
-                           content])
-                        {:on-before-hide state/dom-clear-selection!
-                         :on-after-hide state/state-clear-selection!
-                         :content-props {:class "w-[280px] ls-context-menu-content"}
-                         :as-dropdown? true}))
-
-                    handled
-                    (cond
-                      (and page (not block-id))
-                      (do
-                        (show! (cp-content/page-title-custom-context-menu-content page-entity))
-                        (state/set-state! :page-title/context nil))
-
-                      block-ref
-                      (do
-                        (show! (cp-content/block-ref-custom-context-menu-content block block-ref))
-                        (state/set-state! :block-ref/context nil))
+     (mixins/listen state js/window "contextmenu"
+                    (fn [^js e]
+                      (let [target (gobj/get e "target")
+                            block-el (.closest target ".bullet-container[blockid]")
+                            block-id (some-> block-el (.getAttribute "blockid"))
+                            {:keys [block block-ref]} (state/sub :block-ref/context)
+                            {:keys [page page-entity]} (state/sub :page-title/context)]
+
+                        (let [show!
+                              (fn [content]
+                                (shui/popup-show! e
+                                                  (fn [{:keys [id]}]
+                                                    [:div {:on-click #(shui/popup-hide! id)
+                                                           :data-keep-selection true}
+                                                     content])
+                                                  {:on-before-hide state/dom-clear-selection!
+                                                   :on-after-hide state/state-clear-selection!
+                                                   :content-props {:class "w-[280px] ls-context-menu-content"}
+                                                   :as-dropdown? true}))
+
+                              handled
+                              (cond
+                                (and page (not block-id))
+                                (do
+                                  (show! (cp-content/page-title-custom-context-menu-content page-entity))
+                                  (state/set-state! :page-title/context nil))
+
+                                block-ref
+                                (do
+                                  (show! (cp-content/block-ref-custom-context-menu-content block block-ref))
+                                  (state/set-state! :block-ref/context nil))
 
                       ;; block selection
-                      (and (state/selection?) (not (d/has-class? target "bullet")))
-                      (show! (cp-content/custom-context-menu-content))
+                                (and (state/selection?) (not (d/has-class? target "bullet")))
+                                (show! (cp-content/custom-context-menu-content))
 
                       ;; block bullet
-                      (and block-id (parse-uuid block-id))
-                      (let [block (.closest target ".ls-block")
-                            property-default-value? (when block
-                                                      (= "true" (d/attr block "data-is-property-default-value")))]
-                        (when block
-                          (state/clear-selection!)
-                          (state/conj-selection-block! block :down))
-                        (show! (cp-content/block-context-menu-content target (uuid block-id) property-default-value?)))
-
-                      :else
-                      false)]
-                (when (not (false? handled))
-                  (util/stop e))))))))
+                                (and block-id (parse-uuid block-id))
+                                (let [block (.closest target ".ls-block")
+                                      property-default-value? (when block
+                                                                (= "true" (d/attr block "data-is-property-default-value")))]
+                                  (when block
+                                    (state/clear-selection!)
+                                    (state/conj-selection-block! block :down))
+                                  (show! (cp-content/block-context-menu-content target (uuid block-id) property-default-value?)))
+
+                                :else
+                                false)]
+                          (when (not (false? handled))
+                            (util/stop e))))))))
   []
   nil)
 
 (rum/defcs ^:large-vars/cleanup-todo root-container < rum/reactive
-                                                      (mixins/event-mixin
-                                                        (fn [state]
-                                                          (mixins/listen state js/window "pointerdown" hide-context-menu-and-clear-selection)
-                                                          (mixins/listen state js/window "keydown"
-                                                            (fn [e]
-                                                              (cond
-                                                                (= 27 (.-keyCode e))
-                                                                (if (and (state/modal-opened?)
-                                                                      (not
-                                                                        (and
+  (mixins/event-mixin
+   (fn [state]
+     (mixins/listen state js/window "pointerdown" hide-context-menu-and-clear-selection)
+     (mixins/listen state js/window "keydown"
+                    (fn [e]
+                      (cond
+                        (= 27 (.-keyCode e))
+                        (if (and (state/modal-opened?)
+                                 (not
+                                  (and
                                                                           ;; FIXME: this does not work on CI tests
-                                                                          util/node-test?
-                                                                          (state/editing?))))
-                                                                  (state/close-modal!)
-                                                                  (hide-context-menu-and-clear-selection e)))
-                                                              (state/set-ui-last-key-code! (.-key e))))
-                                                          (mixins/listen state js/window "keyup"
-                                                            (fn [_e]
-                                                              (state/set-state! :editor/latest-shortcut nil)))))
+                                   util/node-test?
+                                   (state/editing?))))
+                          (state/close-modal!)
+                          (hide-context-menu-and-clear-selection e)))
+                      (state/set-ui-last-key-code! (.-key e))))
+     (mixins/listen state js/window "keyup"
+                    (fn [_e]
+                      (state/set-state! :editor/latest-shortcut nil)))))
   [state route-match main-content']
   (let [current-repo (state/sub :git/current-repo)
         granted? (state/sub [:nfs/user-granted? (state/get-current-repo)])
@@ -950,7 +949,7 @@
         right-sidebar-blocks (state/sub-right-sidebar-blocks)
         route-name (get-in route-match [:data :name])
         margin-less-pages? (or (boolean (#{:graph} route-name))
-                             (db-model/whiteboard-page? (state/get-current-page)))
+                               (db-model/whiteboard-page? (state/get-current-page)))
         db-restoring? (state/sub :db/restoring?)
         indexeddb-support? (state/sub :indexeddb/support?)
         page? (= :page route-name)
@@ -965,102 +964,102 @@
         show-recording-bar? (state/sub :mobile/show-recording-bar?)
         preferred-language (state/sub [:preferred-language])]
     (theme/container
-      {:t t
-       :theme theme
-       :accent-color accent-color
-       :editor-font editor-font
-       :route route-match
-       :current-repo current-repo
-       :edit? edit?
-       :nfs-granted? granted?
-       :db-restoring? db-restoring?
-       :sidebar-open? sidebar-open?
-       :settings-open? settings-open?
-       :sidebar-blocks-len (count right-sidebar-blocks)
-       :system-theme? system-theme?
-       :onboarding-state onboarding-state
-       :preferred-language preferred-language
-       :on-click (fn [e]
-                   (editor-handler/unhighlight-blocks!)
-                   (util/fix-open-external-with-shift! e))}
-
-      [:main.theme-container-inner#app-container-wrapper
-       {:class (util/classnames
-                 [{:ls-left-sidebar-open left-sidebar-open?
-                   :ls-right-sidebar-open sidebar-open?
-                   :ls-wide-mode wide-mode?
-                   :ls-window-controls window-controls?
-                   :ls-fold-button-on-right fold-button-on-right?
-                   :ls-hl-colored ls-block-hl-colored?}])
-        :on-pointer-up (fn []
-                         (when-let [container (gdom/getElement "app-container-wrapper")]
-                           (d/remove-class! container "blocks-selection-mode")
-                           (when (> (count (state/get-selection-blocks)) 1)
-                             (util/clear-selection!))))}
-
-       [:button#skip-to-main
-        {:on-click #(ui/focus-element (ui/main-node))
-         :on-key-up (fn [e]
-                      (when (= "Enter" (.-key e))
-                        (ui/focus-element (ui/main-node))))}
-        (t :accessibility/skip-to-main-content)]
-       [:div.#app-container
-        [:div#left-container
-         {:class (if (state/sub :ui/sidebar-open?) "overflow-hidden" "w-full")}
-         (header/header {:light? light?
-                         :current-repo current-repo
-                         :logged? logged?
-                         :page? page?
-                         :route-match route-match
-                         :default-home default-home
-                         :new-block-mode new-block-mode})
-         (when (util/electron?)
-           (find-in-page/search))
-
-         (main {:route-match route-match
-                :margin-less-pages? margin-less-pages?
-                :logged? logged?
-                :home? home?
-                :route-name route-name
-                :indexeddb-support? indexeddb-support?
-                :light? light?
-                :db-restoring? db-restoring?
-                :main-content main-content'
-                :show-action-bar? show-action-bar?
-                :show-recording-bar? show-recording-bar?})]
-
-        (when window-controls?
-          (window-controls/container))
-
-        (right-sidebar/sidebar)
-
-        [:div#app-single-container]]
-
-       (ui/notification)
-
-       (shui-toaster/install-toaster)
-       (shui-dialog/install-modals)
-       (shui-popup/install-popups)
-
-       (custom-context-menu)
-       (plugins/custom-js-installer
-         {:t t
-          :current-repo current-repo
-          :nfs-granted? granted?
-          :db-restoring? db-restoring?})
-       (app-context-menu-observer)
-
-       [:a#download.hidden]
-       [:a#download-as-edn-v2.hidden]
-       [:a#download-as-json-v2.hidden]
-       [:a#download-as-json-debug.hidden]
-       [:a#download-as-sqlite-db.hidden]
-       [:a#download-as-roam-json.hidden]
-       [:a#download-as-html.hidden]
-       [:a#download-as-zip.hidden]
-       [:a#export-as-markdown.hidden]
-       [:a#export-as-opml.hidden]
-       [:a#convert-markdown-to-unordered-list-or-heading.hidden]
-       (when (and (not config/mobile?)
-               (not config/publishing?))
-         (help-button))])))
+     {:t t
+      :theme theme
+      :accent-color accent-color
+      :editor-font editor-font
+      :route route-match
+      :current-repo current-repo
+      :edit? edit?
+      :nfs-granted? granted?
+      :db-restoring? db-restoring?
+      :sidebar-open? sidebar-open?
+      :settings-open? settings-open?
+      :sidebar-blocks-len (count right-sidebar-blocks)
+      :system-theme? system-theme?
+      :onboarding-state onboarding-state
+      :preferred-language preferred-language
+      :on-click (fn [e]
+                  (editor-handler/unhighlight-blocks!)
+                  (util/fix-open-external-with-shift! e))}
+
+     [:main.theme-container-inner#app-container-wrapper
+      {:class (util/classnames
+               [{:ls-left-sidebar-open left-sidebar-open?
+                 :ls-right-sidebar-open sidebar-open?
+                 :ls-wide-mode wide-mode?
+                 :ls-window-controls window-controls?
+                 :ls-fold-button-on-right fold-button-on-right?
+                 :ls-hl-colored ls-block-hl-colored?}])
+       :on-pointer-up (fn []
+                        (when-let [container (gdom/getElement "app-container-wrapper")]
+                          (d/remove-class! container "blocks-selection-mode")
+                          (when (> (count (state/get-selection-blocks)) 1)
+                            (util/clear-selection!))))}
+
+      [:button#skip-to-main
+       {:on-click #(ui/focus-element (ui/main-node))
+        :on-key-up (fn [e]
+                     (when (= "Enter" (.-key e))
+                       (ui/focus-element (ui/main-node))))}
+       (t :accessibility/skip-to-main-content)]
+      [:div.#app-container
+       [:div#left-container
+        {:class (if (state/sub :ui/sidebar-open?) "overflow-hidden" "w-full")}
+        (header/header {:light? light?
+                        :current-repo current-repo
+                        :logged? logged?
+                        :page? page?
+                        :route-match route-match
+                        :default-home default-home
+                        :new-block-mode new-block-mode})
+        (when (util/electron?)
+          (find-in-page/search))
+
+        (main {:route-match route-match
+               :margin-less-pages? margin-less-pages?
+               :logged? logged?
+               :home? home?
+               :route-name route-name
+               :indexeddb-support? indexeddb-support?
+               :light? light?
+               :db-restoring? db-restoring?
+               :main-content main-content'
+               :show-action-bar? show-action-bar?
+               :show-recording-bar? show-recording-bar?})]
+
+       (when window-controls?
+         (window-controls/container))
+
+       (right-sidebar/sidebar)
+
+       [:div#app-single-container]]
+
+      (ui/notification)
+
+      (shui-toaster/install-toaster)
+      (shui-dialog/install-modals)
+      (shui-popup/install-popups)
+
+      (custom-context-menu)
+      (plugins/custom-js-installer
+       {:t t
+        :current-repo current-repo
+        :nfs-granted? granted?
+        :db-restoring? db-restoring?})
+      (app-context-menu-observer)
+
+      [:a#download.hidden]
+      [:a#download-as-edn-v2.hidden]
+      [:a#download-as-json-v2.hidden]
+      [:a#download-as-json-debug.hidden]
+      [:a#download-as-sqlite-db.hidden]
+      [:a#download-as-roam-json.hidden]
+      [:a#download-as-html.hidden]
+      [:a#download-as-zip.hidden]
+      [:a#export-as-markdown.hidden]
+      [:a#export-as-opml.hidden]
+      [:a#convert-markdown-to-unordered-list-or-heading.hidden]
+      (when (and (not config/mobile?)
+                 (not config/publishing?))
+        (help-button))])))