mirror of
https://github.com/logseq/logseq.git
synced 2026-04-26 15:15:01 +00:00
246 lines
7.5 KiB
Clojure
246 lines
7.5 KiB
Clojure
(ns frontend.handler.route
|
|
"Provides fns used for routing throughout the app"
|
|
(:require [clojure.string :as string]
|
|
[frontend.config :as config]
|
|
[frontend.date :as date]
|
|
[frontend.db :as db]
|
|
[frontend.db.model :as model]
|
|
[frontend.handler.recent :as recent-handler]
|
|
[frontend.handler.search :as search-handler]
|
|
[frontend.handler.ui :as ui-handler]
|
|
[frontend.state :as state]
|
|
[frontend.util :as util]
|
|
[frontend.extensions.pdf.utils :as pdf-utils]
|
|
[logseq.graph-parser.text :as text]
|
|
[reitit.frontend.easy :as rfe]
|
|
[frontend.context.i18n :refer [t]]))
|
|
|
|
(defn redirect!
|
|
"If `push` is truthy, previous page will be left in history."
|
|
[{:keys [to path-params query-params push]
|
|
:or {push true}}]
|
|
(let [route-fn (if push rfe/push-state rfe/replace-state)]
|
|
(route-fn to path-params query-params))
|
|
;; force return nil for usage in render phase of React
|
|
nil)
|
|
|
|
(defn redirect-to-home!
|
|
([]
|
|
(redirect-to-home! true))
|
|
([pub-event?]
|
|
(when pub-event? (state/pub-event! [:redirect-to-home]))
|
|
(redirect! {:to :home})))
|
|
|
|
(defn redirect-to-all-pages!
|
|
[]
|
|
(redirect! {:to :all-pages}))
|
|
|
|
(defn redirect-to-graph-view!
|
|
[]
|
|
(redirect! {:to :graph}))
|
|
|
|
(defn redirect-to-all-graphs
|
|
[]
|
|
(redirect! {:to :repos}))
|
|
|
|
(defn redirect-to-whiteboard-dashboard!
|
|
[]
|
|
(redirect! {:to :whiteboards}))
|
|
|
|
;; Named block links only works on web (and publishing)
|
|
(if util/web-platform?
|
|
(defn- default-page-route [page-name-or-block-uuid]
|
|
;; Only query if in a block context
|
|
(let [block (when (uuid? page-name-or-block-uuid)
|
|
(model/get-block-by-uuid page-name-or-block-uuid))]
|
|
(if (get-in block [:block/properties :heading])
|
|
{:to :page-block
|
|
:path-params {:name (get-in block [:block/page :block/name])
|
|
:block-route-name (model/heading-content->route-name (:block/content block))}}
|
|
{:to :page
|
|
:path-params {:name (if (string? page-name-or-block-uuid)
|
|
(util/page-name-sanity-lc page-name-or-block-uuid)
|
|
(str page-name-or-block-uuid))}})))
|
|
|
|
(defn- default-page-route [page-name]
|
|
{:to :page
|
|
:path-params {:name (str page-name)}}))
|
|
|
|
(defn redirect-to-page!
|
|
"Must ensure `page-name` is dereferenced (not an alias), or it will create a
|
|
wrong new page with that name (#3511). page-name can be a block name or uuid"
|
|
([page-name]
|
|
(redirect-to-page! page-name {}))
|
|
([page-name {:keys [anchor push click-from-recent?]
|
|
:or {click-from-recent? false}}]
|
|
(when (or (uuid? page-name) (seq page-name))
|
|
(recent-handler/add-page-to-recent! (state/get-current-repo) page-name
|
|
click-from-recent?)
|
|
(let [m (cond->
|
|
(default-page-route page-name)
|
|
|
|
anchor
|
|
(assoc :query-params {:anchor anchor})
|
|
|
|
(boolean? push)
|
|
(assoc :push push))]
|
|
(redirect! m)))))
|
|
|
|
(defn redirect-to-whiteboard!
|
|
([name]
|
|
(redirect-to-whiteboard! name nil))
|
|
([name {:keys [block-id new-whiteboard? click-from-recent?]}]
|
|
;; Always skip onboarding when loading an existing whiteboard
|
|
(when-not new-whiteboard? (state/set-onboarding-whiteboard! true))
|
|
(recent-handler/add-page-to-recent! (state/get-current-repo) name click-from-recent?)
|
|
(if (= name (state/get-current-whiteboard))
|
|
(state/focus-whiteboard-shape block-id)
|
|
(redirect! {:to :whiteboard
|
|
:path-params {:name (str name)}
|
|
:query-params (merge {:block-id block-id})}))))
|
|
|
|
(defn get-title
|
|
[name path-params]
|
|
(case name
|
|
:home
|
|
"Logseq"
|
|
:whiteboards
|
|
(t :whiteboards)
|
|
:repos
|
|
"Repos"
|
|
:repo-add
|
|
"Add another repo"
|
|
:graph
|
|
(t :graph)
|
|
:all-files
|
|
(t :all-files)
|
|
:all-pages
|
|
(t :all-pages)
|
|
:all-journals
|
|
(t :all-journals)
|
|
:file
|
|
(str "File " (:path path-params))
|
|
:new-page
|
|
"Create a new page"
|
|
:page
|
|
(let [name (:name path-params)
|
|
block? (util/uuid-string? name)]
|
|
(if block?
|
|
(if-let [block (db/entity [:block/uuid (uuid name)])]
|
|
(let [content (text/remove-level-spaces (:block/content block)
|
|
(:block/format block) (config/get-block-pattern (:block/format block)))]
|
|
(if (> (count content) 48)
|
|
(str (subs content 0 48) "...")
|
|
content))
|
|
"Page no longer exists!!")
|
|
(let [page (db/pull [:block/name (util/page-name-sanity-lc name)])]
|
|
(or (util/get-page-original-name page)
|
|
"Logseq"))))
|
|
:whiteboard
|
|
(let [name (:name path-params)
|
|
block? (util/uuid-string? name)]
|
|
(str
|
|
(if block?
|
|
(t :untitled)
|
|
(let [page (db/pull [:block/name (util/page-name-sanity-lc name)])]
|
|
(or (util/get-page-original-name page)
|
|
"Logseq"))) " - " (t :whiteboard)))
|
|
:tag
|
|
(str "#" (:name path-params))
|
|
:diff
|
|
"Git diff"
|
|
:draw
|
|
"Draw"
|
|
:settings
|
|
"Settings"
|
|
:import
|
|
"Import data into Logseq"
|
|
"Logseq"))
|
|
|
|
(defn update-page-title!
|
|
[route]
|
|
(let [{:keys [data path-params]} route
|
|
title (get-title (:name data) path-params)
|
|
hls? (pdf-utils/hls-file? title)]
|
|
(util/set-title! (if hls? (pdf-utils/fix-local-asset-pagename title) title))))
|
|
|
|
(defn update-page-label!
|
|
[route]
|
|
(let [{:keys [data]} route]
|
|
(when-let [data-name (:name data)]
|
|
(set! (. js/document.body.dataset -page) (name data-name)))))
|
|
|
|
(defn jump-to-anchor!
|
|
[anchor-text]
|
|
(when anchor-text
|
|
(js/setTimeout #(ui-handler/highlight-element! anchor-text) 200)))
|
|
|
|
(defn set-route-match!
|
|
[route]
|
|
(let [route route]
|
|
(swap! state/state assoc :route-match route)
|
|
(update-page-title! route)
|
|
(update-page-label! route)
|
|
(if-let [anchor (get-in route [:query-params :anchor])]
|
|
(jump-to-anchor! anchor)
|
|
(js/setTimeout #(util/scroll-to (util/app-scroll-container-node)
|
|
(state/get-saved-scroll-position)
|
|
false)
|
|
100))))
|
|
|
|
(defn go-to-search!
|
|
[search-mode]
|
|
(search-handler/clear-search! false)
|
|
(when search-mode
|
|
(state/set-search-mode! search-mode))
|
|
(state/pub-event! [:go/search]))
|
|
|
|
(defn go-to-cmdk! []
|
|
(state/pub-event! [:go/search]))
|
|
|
|
(defn sidebar-journals!
|
|
[]
|
|
(state/sidebar-add-block!
|
|
(state/get-current-repo)
|
|
(:db/id (db/get-page (date/today)))
|
|
:page))
|
|
|
|
(defn go-to-journals!
|
|
[]
|
|
(state/set-journals-length! 3)
|
|
(let [route (if (state/custom-home-page?)
|
|
:all-journals
|
|
:home)]
|
|
(redirect! {:to route}))
|
|
(util/scroll-to-top))
|
|
|
|
(defn- redirect-to-file!
|
|
[page]
|
|
(when-let [path (-> (db/get-page-file (string/lower-case page))
|
|
:db/id
|
|
(db/entity)
|
|
:file/path)]
|
|
(redirect! {:to :file
|
|
:path-params {:path path}})))
|
|
|
|
(defn toggle-between-page-and-file!
|
|
[_e]
|
|
(let [current-route (state/get-current-route)]
|
|
(case current-route
|
|
:home
|
|
(redirect-to-file! (date/today))
|
|
|
|
:all-journals
|
|
(redirect-to-file! (date/today))
|
|
|
|
:page
|
|
(when-let [page-name (get-in (state/get-route-match) [:path-params :name])]
|
|
(redirect-to-file! page-name))
|
|
|
|
:file
|
|
(when-let [path (get-in (state/get-route-match) [:path-params :path])]
|
|
(when-let [page (db/get-file-page path)]
|
|
(redirect-to-page! page)))
|
|
|
|
nil)))
|