| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721 |
- (ns frontend.components.sidebar
- (:require [cljs-drag-n-drop.core :as dnd]
- [clojure.string :as string]
- [frontend.components.command-palette :as command-palette]
- [frontend.components.header :as header]
- [frontend.components.journal :as journal]
- [frontend.components.onboarding :as onboarding]
- [frontend.components.plugins :as plugins]
- [frontend.components.repo :as repo]
- [frontend.components.right-sidebar :as right-sidebar]
- [frontend.components.select :as select]
- [frontend.components.svg :as svg]
- [frontend.components.theme :as theme]
- [frontend.components.widgets :as widgets]
- [frontend.components.find-in-page :as find-in-page]
- [frontend.config :as config]
- [frontend.context.i18n :refer [t]]
- [frontend.db :as db]
- [frontend.db-mixins :as db-mixins]
- [frontend.db.model :as db-model]
- [frontend.extensions.pdf.assets :as pdf-assets]
- [frontend.extensions.srs :as srs]
- [frontend.handler.common :as common-handler]
- [frontend.handler.editor :as editor-handler]
- [frontend.handler.mobile.swipe :as swipe]
- [frontend.handler.page :as page-handler]
- [frontend.handler.route :as route-handler]
- [frontend.handler.user :as user-handler]
- [frontend.handler.whiteboard :as whiteboard-handler]
- [frontend.mixins :as mixins]
- [frontend.mobile.action-bar :as action-bar]
- [frontend.mobile.footer :as footer]
- [frontend.mobile.mobile-bar :refer [mobile-bar]]
- [frontend.mobile.util :as mobile-util]
- [frontend.modules.shortcut.data-helper :as shortcut-dh]
- [frontend.state :as state]
- [frontend.ui :as ui]
- [frontend.util :as util]
- [frontend.util.cursor :as cursor]
- [goog.dom :as gdom]
- [goog.object :as gobj]
- [logseq.graph-parser.util :as gp-util]
- [react-draggable]
- [reitit.frontend.easy :as rfe]
- [rum.core :as rum]))
- (rum/defc nav-content-item < rum/reactive
- [name {:keys [class]} child]
- [:div.nav-content-item
- {:class (util/classnames [class {:is-expand (not (state/sub [:ui/navigation-item-collapsed? class]))}])}
- [:div.nav-content-item-inner
- [:div.header.items-center.mb-1
- {:on-click (fn [^js/MouseEvent _e]
- (state/toggle-navigation-item-collapsed! class))}
- [:div.font-medium name]
- [:span
- [:a.more svg/arrow-down-v2]]]
- [:div.bd child]]])
- (defn- delta-y
- [e]
- (when-let [target (.. e -target)]
- (let [rect (.. target getBoundingClientRect)]
- (- (.. e -pageY) (.. rect -top)))))
- (defn- move-up?
- [e]
- (let [delta (delta-y e)]
- (< delta 14)))
- (rum/defc page-name
- [name icon recent?]
- (let [original-name (db-model/get-page-original-name name)
- whiteboard-page? (db-model/whiteboard-page? name)]
- [:a.flex.items-center
- {:on-click
- (fn [e]
- (let [name (util/safe-page-name-sanity-lc name)
- source-page (db-model/get-alias-source-page (state/get-current-repo) name)
- name (if (empty? source-page) name (:block/name source-page))]
- (if (and (gobj/get e "shiftKey") (not whiteboard-page?))
- (when-let [page-entity (if (empty? source-page) (db/entity [:block/name name]) source-page)]
- (state/sidebar-add-block!
- (state/get-current-repo)
- (:db/id page-entity)
- :page))
- (if whiteboard-page?
- (route-handler/redirect-to-whiteboard! name)
- (route-handler/redirect-to-page! name {:click-from-recent? recent?})))))}
- [:span.page-icon (if whiteboard-page? (ui/icon "whiteboard" {:extension? true}) icon)]
- [:span.page-title (pdf-assets/fix-local-asset-pagename original-name)]]))
- (defn get-page-icon [page-entity]
- (let [default-icon (ui/icon "page" {:extension? true})
- from-properties (get-in (into {} page-entity) [:block/properties :icon])]
- (or
- (when (not= from-properties "") from-properties)
- default-icon))) ;; Fall back to default if icon is undefined or empty
- (rum/defcs favorite-item <
- (rum/local nil ::up?)
- (rum/local nil ::dragging-over)
- [state _t name icon]
- (let [up? (get state ::up?)
- dragging-over (get state ::dragging-over)
- target (state/sub :favorites/dragging)]
- [:li.favorite-item
- {:key name
- :title name
- :data-ref name
- :class (if (and target @dragging-over (not= target @dragging-over))
- "dragging-target"
- "")
- :draggable true
- :on-drag-start (fn [_event]
- (state/set-state! :favorites/dragging name))
- :on-drag-over (fn [e]
- (util/stop e)
- (reset! dragging-over name)
- (when-not (= name (get @state/state :favorites/dragging))
- (reset! up? (move-up? e))))
- :on-drag-leave (fn [_e]
- (reset! dragging-over nil))
- :on-drop (fn [e]
- (page-handler/reorder-favorites! {:to name
- :up? (move-up? e)})
- (reset! up? nil)
- (reset! dragging-over nil))}
- (page-name name icon false)]))
- (rum/defc favorites < rum/reactive
- [t]
- (nav-content-item
- [:a.flex.items-center.text-sm.font-medium.rounded-md.wrap-th
- (ui/icon "star" {:size 16})
- [:span.flex-1.ml-2 (string/upper-case (t :left-side-bar/nav-favorites))]]
- {:class "favorites"
- :edit-fn
- (fn [e]
- (rfe/push-state :page {:name "Favorites"})
- (util/stop e))}
- (let [favorites (->> (:favorites (state/sub-config))
- (remove string/blank?)
- (filter string?))]
- (when (seq favorites)
- [:ul.favorites.text-sm
- (for [name favorites]
- (when-not (string/blank? name)
- (when-let [entity (db/entity [:block/name (util/safe-page-name-sanity-lc name)])]
- (let [icon (get-page-icon entity)]
- (favorite-item t name icon)))))]))))
- (rum/defc recent-pages < rum/reactive db-mixins/query
- [t]
- (nav-content-item
- [:a.flex.items-center.text-sm.font-medium.rounded-md.wrap-th
- (ui/icon "history" {:size 16})
- [:span.flex-1.ml-2
- (string/upper-case (t :left-side-bar/nav-recent-pages))]]
- {:class "recent"}
- (let [pages (->> (db/sub-key-value :recent/pages)
- (remove string/blank?)
- (filter string?)
- (map (fn [page] {:lowercase (util/safe-page-name-sanity-lc page)
- :page page}))
- (util/distinct-by :lowercase)
- (map :page))]
- [:ul.text-sm
- (for [name pages]
- (when-let [entity (db/entity [:block/name (util/safe-page-name-sanity-lc name)])]
- [:li.recent-item.select-none
- {:key name
- :title name
- :data-ref name}
- (page-name name (get-page-icon entity) true)]))])))
- (rum/defcs flashcards < db-mixins/query rum/reactive
- {:did-mount (fn [state]
- (srs/update-cards-due-count!)
- state)}
- [_state srs-open?]
- (let [num (state/sub :srs/cards-due-count)]
- [:a.item.group.flex.items-center.px-2.py-2.text-sm.font-medium.rounded-md
- {:class (util/classnames [{:active srs-open?}])
- :on-click #(do
- (srs/update-cards-due-count!)
- (state/pub-event! [:modal/show-cards]))}
- (ui/icon "infinity")
- [:span.flex-1 (t :right-side-bar/flashcards)]
- (when (and num (not (zero? num)))
- [:span.ml-3.inline-block.py-0.5.px-3.text-xs.font-medium.rounded-full.fade-in num])]))
- (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)))
- (db/entity [:block/name (util/safe-page-name-sanity-lc page)]))]
- (if page
- default-home
- (dissoc default-home :page)))))
- (defn sidebar-item
- [{on-click-handler :on-click-handler
- class :class
- title :title
- icon :icon
- icon-extension? :icon-extension?
- active :active
- href :href}]
- [:div
- {:class class}
- [:a.item.group.flex.items-center.text-sm.font-medium.rounded-md
- {:on-click on-click-handler
- :class (when active "active")
- :href href}
- (ui/icon (str icon) {:extension? icon-extension?})
- [:span.flex-1 title]]])
- (defn close-sidebar-on-mobile!
- []
- (and (util/sm-breakpoint?)
- (state/toggle-left-sidebar!)))
- (defn create-dropdown
- []
- (ui/dropdown-with-links
- (fn [{:keys [toggle-fn]}]
- [:button#create-button
- {:on-click toggle-fn}
- [:<>
- (ui/icon "plus" {:font? "true"})
- [:span.mx-1 (t :left-side-bar/create)]]])
- (->>
- [{:title (t :left-side-bar/new-page)
- :class "new-page-link"
- :shortcut (ui/keyboard-shortcut-from-config :go/search)
- :options {:on-click #(do (close-sidebar-on-mobile!)
- (state/pub-event! [:go/search]))}
- :icon (ui/type-icon {:name "new-page"
- :class "highlight"
- :extension? true})}
- {:title (t :left-side-bar/new-whiteboard)
- :class "new-whiteboard-link"
- :shortcut (ui/keyboard-shortcut-from-config :editor/new-whiteboard)
- :options {:on-click #(do (close-sidebar-on-mobile!)
- (whiteboard-handler/create-new-whiteboard-and-redirect!))}
- :icon (ui/type-icon {:name "new-whiteboard"
- :class "highlight"
- :extension? true})}])
- {}))
- (rum/defc sidebar-nav < rum/reactive
- [route-match close-modal-fn left-sidebar-open? srs-open?]
- (let [default-home (get-default-home-if-valid)
- route-name (get-in route-match [:data :name])
- enable-whiteboards? (state/enable-whiteboards?)
- on-contents-scroll #(when-let [^js el (.-target %)]
- (let [top (.-scrollTop el)
- cls (.-classList el)
- cls' "is-scrolled"]
- (if (> top 2)
- (.add cls cls')
- (.remove cls cls'))))]
- [:div.left-sidebar-inner.flex-1.flex.flex-col.min-h-0
- {: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"])
- (close-modal-fn)))}
- [:div.flex.flex-col.wrap.gap-1.relative
- (when (mobile-util/native-platform?)
- [:div.fake-bar.absolute
- [:button
- {:on-click state/toggle-left-sidebar!}
- (ui/icon "menu-2" {:size ui/icon-size})]])
- [:nav.px-4.flex.flex-col.gap-1.cp__menubar-repos
- {:aria-label "Navigation menu"}
- (repo/repos-dropdown)
- [:div.nav-header.flex.gap-1.flex-col
- (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"})
- (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"})))
- (when (state/enable-flashcards? (state/get-current-repo))
- [:div.flashcards-nav
- (flashcards srs-open?)])
- (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"})
- (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"})
- (when enable-whiteboards?
- (sidebar-item
- {:class "whiteboard"
- :title (t :right-side-bar/whiteboards)
- :href (rfe/href :whiteboards)
- :active (and (not srs-open?) (#{:whiteboard :whiteboards} route-name))
- :icon "whiteboard"
- :icon-extension? true}))]]
- [:div.nav-contents-container.flex.flex-col.gap-1.pt-1
- {:on-scroll on-contents-scroll}
- (when left-sidebar-open?
- (favorites t))
- (when (and left-sidebar-open? (not config/publishing?))
- (recent-pages t))]
- [:footer.px-2 {:class "create"}
- (when-not config/publishing?
- (if enable-whiteboards?
- (create-dropdown)
- [:a.item.group.flex.items-center.px-2.py-2.text-sm.font-medium.rounded-md.new-page-link
- {:on-click (fn []
- (and (util/sm-breakpoint?)
- (state/toggle-left-sidebar!))
- (state/pub-event! [:go/search]))}
- (ui/icon "circle-plus" {:style {:font-size 20}})
- [:span.flex-1 (t :right-side-bar/new-page)]]))]]]))
- (rum/defc left-sidebar < rum/reactive
- [{:keys [left-sidebar-open? route-match]}]
- (let [close-fn #(state/set-left-sidebar-open! false)
- srs-open? (= :srs (state/sub :modal/id))]
- [:div#left-sidebar.cp__sidebar-left-layout
- {:class (util/classnames [{:is-open left-sidebar-open?}])}
- ;; sidebar contents
- (sidebar-nav route-match close-fn left-sidebar-open? srs-open?)
- [:span.shade-mask {:on-click close-fn}]]))
- (rum/defc recording-bar
- []
- [:> react-draggable
- {:onStart (fn [_event]
- (when-let [pos (some-> (state/get-input) cursor/pos)]
- (state/set-editor-last-pos! pos)))
- :onStop (fn [_event]
- (when-let [block (get-in @state/state [:editor/block :block/uuid])]
- (editor-handler/edit-block! block :max (:block/uuid block))
- (when-let [input (state/get-input)]
- (when-let [saved-cursor (state/get-editor-last-pos)]
- (cursor/move-cursor-to input saved-cursor)))))}
- [:div#audio-record-toolbar
- {:style {:bottom (+ @util/keyboard-height 45)}}
- (footer/audio-record-cp)]])
- (rum/defc main <
- {: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))))})
- (common-handler/listen-to-scroll! element))
- state)}
- [{: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))
- margin-less-pages? (or 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?}])}
- ;; desktop left sidebar layout
- (left-sidebar {:left-sidebar-open? left-sidebar-open?
- :route-match route-match})
- [:div#main-content-container.scrollbar-spacing.w-full.flex.justify-center.flex-row.outline-none
- {:tabIndex "-1"
- :data-is-margin-less-pages margin-less-pages?}
- (when (util/electron?)
- (find-in-page/search))
- (when show-action-bar?
- (action-bar/action-bar))
- [: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))}
- (when show-recording-bar?
- (recording-bar))
- (mobile-bar)
- (footer/footer)
- (when (and (not (mobile-util/native-platform?))
- (contains? #{:page :home} route-name))
- (widgets/demo-graph-alert))
- (cond
- (not indexeddb-support?)
- nil
- db-restoring?
- [:div.mt-20
- [:div.ls-center
- (ui/loading (t :loading))]]
- :else
- [:div
- {:class (if (or onboarding-and-home? margin-less-pages?) "" (util/hiccup->class "mx-auto.pb-24"))
- :style {:margin-bottom (cond
- margin-less-pages? 0
- onboarding-and-home? 0
- :else 120)}}
- main-content])
- (when onboarding-and-home?
- (onboarding/intro onboarding-and-home?))]]]))
- (defonce sidebar-inited? (atom false))
- ;; TODO: simplify logic
- (rum/defc parsing-progress < rum/static
- [state]
- (let [finished (or (:finished state) 0)
- total (:total state)
- width (js/Math.round (* (.toFixed (/ finished total) 2) 100))
- file-basename (util/node-path.basename
- (:current-parsing-file state))
- display-filename (if (mobile-util/native-platform?)
- (gp-util/safe-decode-uri-component file-basename)
- file-basename)
- left-label [:div.flex.flex-row.font-bold
- (t :parsing-files)
- [:div.hidden.md:flex.flex-row
- [:span.mr-1 ": "]
- [:div.text-ellipsis-wrapper {:style {:max-width 300}}
- display-filename]]]]
- (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")
- ["contents" :contents]
- [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)
- loading-files? (when current-repo (state/sub [:repo/loading-files? current-repo]))
- journals-length (state/sub :journals-length)
- latest-journals (db/get-latest-journals (state/get-current-repo) journals-length)
- 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)))
- [:div.flex.items-center.justify-center.full-height-without-header
- [:div.flex-1
- (parsing-progress graph-parsing-state)]]
- :else
- [:div
- (cond
- (and 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))
- (route-handler/redirect! {:to :all-pages})
- loading-files?
- (ui/loading (t :loading-files))
- (seq latest-journals)
- (journal/journals latest-journals)
- ;; FIXME: why will this happen?
- :else
- [:div])])))
- (defn- hide-context-menu-and-clear-selection
- [e]
- (state/hide-custom-context-menu!)
- (let [block (.closest (.-target e) ".ls-block")]
- (when-not (or (gobj/get e "shiftKey")
- (util/meta-key? e)
- (state/get-edit-input-id)
- (and block
- (or (= block (.-target e))
- (.contains block (.-target e)))))
- (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)"))))
- [:<>
- [:div.menu-backdrop {:on-mouse-down (fn [e] (hide-context-menu-and-clear-selection e))}]
- [:div#custom-context-menu
- {:ref ref
- :style {:left (str (first position) "px")
- :top (str (second position) "px")}} links]]))
- (rum/defc custom-context-menu < rum/reactive
- []
- (let [show? (state/sub :custom-context-menu/show?)
- links (state/sub :custom-context-menu/links)
- position (state/sub :custom-context-menu/position)]
- (when (and show? links position)
- (ui/css-transition
- {:class-names "fade"
- :timeout {:enter 500
- :exit 300}}
- (render-custom-context-menu links position)))))
- (rum/defc new-block-mode < rum/reactive
- []
- (when (state/sub [:document/mode?])
- (ui/tippy {:html [:div.p-2
- [:p.mb-2 [:b "Document mode"]]
- [:ul
- [:li
- [:div.inline-block.mr-1 (ui/render-keyboard-shortcut (shortcut-dh/gen-shortcut-seq :editor/new-line))]
- [:p.inline-block "to create new block"]]
- [:li
- [: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"])))
- (rum/defc help-button < rum/reactive
- []
- (when-not (state/sub :ui/sidebar-open?)
- [:div.cp__sidebar-help-btn
- [:div.inner
- {:title (t :help-shortcut-title)
- :on-click (fn []
- (state/sidebar-add-block! (state/get-current-repo) "help" :help))}
- "?"]]))
- (rum/defcs ^:large-vars/cleanup-todo sidebar <
- (mixins/modal :modal/show?)
- rum/reactive
- (mixins/event-mixin
- (fn [state]
- (mixins/listen state js/window "click" hide-context-menu-and-clear-selection)
- (mixins/listen state js/window "keydown"
- (fn [e]
- (when (= 27 (.-keyCode e))
- (if (and (state/modal-opened?)
- (not
- (and
- ;; FIXME: this does not work on CI tests
- util/node-test?
- (:editor/editing? @state/state))))
- (state/close-modal!)
- (hide-context-menu-and-clear-selection e)))))))
- {:did-mount (fn [state]
- (swipe/setup-listeners!)
- state)}
- [state route-match main-content]
- (let [{:keys [open-fn]} state
- current-repo (state/sub :git/current-repo)
- granted? (state/sub [:nfs/user-granted? (state/get-current-repo)])
- theme (state/sub :ui/theme)
- system-theme? (state/sub :ui/system-theme?)
- light? (= "light" (state/sub :ui/theme))
- sidebar-open? (state/sub :ui/sidebar-open?)
- settings-open? (state/sub :ui/settings-open?)
- left-sidebar-open? (state/sub :ui/left-sidebar-open?)
- wide-mode? (state/sub :ui/wide-mode?)
- ls-block-hl-colored? (state/sub :pdf/block-highlight-colored?)
- onboarding-state (state/sub :file-sync/onboarding-state)
- right-sidebar-blocks (state/sub-right-sidebar-blocks)
- route-name (get-in route-match [:data :name])
- margin-less-pages? (boolean (#{:graph :whiteboard} route-name))
- db-restoring? (state/sub :db/restoring?)
- indexeddb-support? (state/sub :indexeddb/support?)
- page? (= :page route-name)
- home? (= :home route-name)
- edit? (:editor/editing? @state/state)
- default-home (get-default-home-if-valid)
- logged? (user-handler/logged-in?)
- show-action-bar? (state/sub :mobile/show-action-bar?)
- show-recording-bar? (state/sub :mobile/show-recording-bar?)
- preferred-language (state/sub [:preferred-language])]
- (theme/container
- {:t t
- :theme theme
- :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-inner
- {:class (util/classnames [{:ls-left-sidebar-open left-sidebar-open?
- :ls-right-sidebar-open sidebar-open?
- :ls-wide-mode wide-mode?
- :ls-hl-colored ls-block-hl-colored?}])}
- [:button#skip-to-main
- {:on-click #(ui/focus-element (ui/main-node))
- :on-key-up (fn [e]
- (when (= (.-key e) "Enter")
- (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 {:open-fn open-fn
- :light? light?
- :current-repo current-repo
- :logged? logged?
- :page? page?
- :route-match route-match
- :default-home default-home
- :new-block-mode new-block-mode})
- (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?})]
- (right-sidebar/sidebar)
- [:div#app-single-container]]
- (ui/notification)
- (ui/modal)
- (ui/sub-modal)
- (command-palette/command-palette-modal)
- (select/select-modal)
- (custom-context-menu)
- (plugins/custom-js-installer {:t t
- :current-repo current-repo
- :nfs-granted? granted?
- :db-restoring? db-restoring?})
- [:a#download.hidden]
- (when
- (and (not config/mobile?)
- (not config/publishing?))
- (help-button))])))
|