mirror of https://github.com/logseq/logseq
feat: add block page-search autocomplete with page preview
parent
e89ef6009f
commit
60de6516e4
|
@ -371,58 +371,55 @@
|
|||
:else
|
||||
(get page-entity :block/original-name page-name)))])
|
||||
|
||||
(rum/defc page-preview-trigger
|
||||
[{:keys [children sidebar? tippy-position fixed-position?] :as config} page-name]
|
||||
(let [page-entity (db/entity [:block/name page-name])
|
||||
redirect-page-name (model/get-redirect-page-name page-name (:block/alias? config))
|
||||
page-original-name (model/get-page-original-name redirect-page-name)]
|
||||
(ui/tippy {:html (fn []
|
||||
[:div.tippy-wrapper.overflow-y-auto.p-4
|
||||
{:style {:width 600
|
||||
:text-align "left"
|
||||
:font-weight 500
|
||||
:max-height 600
|
||||
:padding-bottom 64}}
|
||||
(if (and (string? page-original-name) (string/includes? page-original-name "/"))
|
||||
[:div.my-2
|
||||
(->>
|
||||
(for [page (string/split page-original-name #"/")]
|
||||
(when (and (string? page) page)
|
||||
(page-reference false page {} nil)))
|
||||
(interpose [:span.mx-2.opacity-30 "/"]))]
|
||||
[:h2.font-bold.text-lg (if (= page-name redirect-page-name)
|
||||
page-original-name
|
||||
[:span
|
||||
[:span.text-sm.mr-2 "Alias:"]
|
||||
page-original-name])])
|
||||
(let [page (db/entity [:block/name (string/lower-case redirect-page-name)])]
|
||||
(editor-handler/insert-first-page-block-if-not-exists! redirect-page-name)
|
||||
(when-let [f (state/get-page-blocks-cp)]
|
||||
(f (state/get-current-repo) page {:sidebar? sidebar? :preview? true})))])
|
||||
:interactive true
|
||||
:delay [1000, 100]
|
||||
:fixed-position? fixed-position?
|
||||
:position (or tippy-position "top")}
|
||||
children)))
|
||||
|
||||
(rum/defc page-cp
|
||||
[{:keys [html-export? label children contents-page? sidebar? preview?] :as config} page]
|
||||
(when-let [page-name (:block/name page)]
|
||||
(let [page (string/lower-case page-name)
|
||||
page-entity (db/entity [:block/name page])
|
||||
redirect-page-name (cond
|
||||
(:block/alias? config)
|
||||
page
|
||||
|
||||
(db/page-empty-or-dummy? (state/get-current-repo) (:db/id page-entity))
|
||||
(let [source-page (model/get-alias-source-page (state/get-current-repo)
|
||||
(string/lower-case page-name))]
|
||||
(or (when source-page (:block/name source-page))
|
||||
page))
|
||||
|
||||
:else
|
||||
page)
|
||||
(let [page-name (string/lower-case page-name)
|
||||
page-entity (db/entity [:block/name page-name])
|
||||
redirect-page-name (model/get-redirect-page-name page-name (:block/alias? config))
|
||||
page-original-name (model/get-page-original-name redirect-page-name)
|
||||
href (if html-export?
|
||||
(util/encode-str page)
|
||||
(util/encode-str page-name)
|
||||
(rfe/href :page {:name redirect-page-name}))
|
||||
inner (page-inner config
|
||||
page-name
|
||||
href redirect-page-name page-entity contents-page? children html-export? label)]
|
||||
(if (and (not (util/mobile?)) (not preview?))
|
||||
(ui/tippy {:html (fn []
|
||||
[:div.tippy-wrapper.overflow-y-auto.p-4
|
||||
{:style {:width 600
|
||||
:text-align "left"
|
||||
:font-weight 500
|
||||
:max-height 600
|
||||
:padding-bottom 64}}
|
||||
(if (and (string? page-original-name) (string/includes? page-original-name "/"))
|
||||
[:div.my-2
|
||||
(->>
|
||||
(for [page (string/split page-original-name #"/")]
|
||||
(when (and (string? page) page)
|
||||
(page-reference false page {} nil)))
|
||||
(interpose [:span.mx-2.opacity-30 "/"]))]
|
||||
[:h2.font-bold.text-lg (if (= page redirect-page-name)
|
||||
page-original-name
|
||||
[:span
|
||||
[:span.text-sm.mr-2 "Alias:"]
|
||||
page-original-name])])
|
||||
|
||||
(let [page (db/entity [:block/name (string/lower-case redirect-page-name)])]
|
||||
(editor-handler/insert-first-page-block-if-not-exists! redirect-page-name)
|
||||
(when-let [f (state/get-page-blocks-cp)]
|
||||
(f (state/get-current-repo) page {:sidebar? sidebar? :preview? true})))])
|
||||
:interactive true
|
||||
:delay [1000, 100]}
|
||||
inner)
|
||||
(page-preview-trigger (assoc config :children inner) page-name)
|
||||
inner))))
|
||||
|
||||
(rum/defc asset-reference
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
[frontend.components.datetime :as datetime-comp]
|
||||
[frontend.components.search :as search]
|
||||
[frontend.components.svg :as svg]
|
||||
[frontend.components.block :as block]
|
||||
[frontend.config :as config]
|
||||
[frontend.db :as db]
|
||||
[frontend.handler.editor :as editor-handler :refer [get-state]]
|
||||
|
@ -94,11 +95,19 @@
|
|||
(editor-handler/get-matched-pages q))]
|
||||
(ui/auto-complete
|
||||
matched-pages
|
||||
{:on-chosen (page-handler/on-chosen-handler input id q pos format)
|
||||
:on-enter #(page-handler/page-not-exists-handler input id q current-pos)
|
||||
:item-render (fn [item] [:div.py-2 (search/highlight-exact-query item q)])
|
||||
:empty-div [:div.text-gray-500.pl-4.pr-4 "Search for a page"]
|
||||
:class "black"}))))))
|
||||
{:on-chosen (page-handler/on-chosen-handler input id q pos format)
|
||||
:on-enter #(page-handler/page-not-exists-handler input id q current-pos)
|
||||
:item-render (fn [item chosen?]
|
||||
[:div.py-2.flex.page-search-menu-item
|
||||
[[:div (search/highlight-exact-query item q)]
|
||||
[:div.flex-1]
|
||||
;; Ideally, we may want to trigger preview on focused
|
||||
(block/page-preview-trigger
|
||||
{:children [:div.page-search-menu-item-preview "Preview"]
|
||||
:tippy-position "right"}
|
||||
item)]])
|
||||
:empty-div [:div.text-gray-500.pl-4.pr-4 "Search for a page"]
|
||||
:class "black"}))))))
|
||||
|
||||
(rum/defcs block-search-auto-complete < rum/reactive
|
||||
{:init (fn [state]
|
||||
|
|
|
@ -63,3 +63,17 @@ pre {
|
|||
background: #f6f8fa;
|
||||
background: var(--ls-secondary-background-color);
|
||||
}
|
||||
|
||||
|
||||
.page-search-menu-item-preview {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.page-search-menu-item:hover {
|
||||
.page-search-menu-item-preview {
|
||||
opacity: 0.5;
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -710,6 +710,23 @@
|
|||
(vector? block)
|
||||
(= "Heading" (first block))))
|
||||
|
||||
(defn get-redirect-page-name
|
||||
([page-name] (get-redirect-page-name page-name false))
|
||||
([page-name alias?]
|
||||
(let [page-entity (db-utils/entity [:block/name page-name])]
|
||||
(cond
|
||||
alias?
|
||||
page-name
|
||||
|
||||
(page-empty-or-dummy? (state/get-current-repo) (:db/id page-entity))
|
||||
(let [source-page (get-alias-source-page (state/get-current-repo)
|
||||
(string/lower-case page-name))]
|
||||
(or (when source-page (:block/name source-page))
|
||||
page-name))
|
||||
|
||||
:else
|
||||
page-name))))
|
||||
|
||||
(defn get-page-original-name
|
||||
[page-name]
|
||||
(when page-name
|
||||
|
|
|
@ -368,16 +368,16 @@
|
|||
{:key idx}
|
||||
(let [item-cp
|
||||
[:div {:key idx}
|
||||
(menu-link
|
||||
{:id (str "ac-" idx)
|
||||
:class (when (= @current-idx idx)
|
||||
"chosen")
|
||||
:on-mouse-down (fn [e]
|
||||
(util/stop e)
|
||||
(if (and (gobj/get e "shiftKey") on-shift-chosen)
|
||||
(on-shift-chosen item)
|
||||
(on-chosen item)))}
|
||||
(if item-render (item-render item) item))]]
|
||||
(let [chosen? (= @current-idx idx)]
|
||||
(menu-link
|
||||
{:id (str "ac-" idx)
|
||||
:class (when chosen? "chosen")
|
||||
:on-mouse-down (fn [e]
|
||||
(util/stop e)
|
||||
(if (and (gobj/get e "shiftKey") on-shift-chosen)
|
||||
(on-shift-chosen item)
|
||||
(on-chosen item)))}
|
||||
(if item-render (item-render item chosen?) item)))]]
|
||||
|
||||
(if get-group-name
|
||||
(if-let [group-name (get-group-name item)]
|
||||
|
@ -628,7 +628,7 @@
|
|||
|
||||
(rum/defcs tippy < rum/static
|
||||
(rum/local false ::mounted?)
|
||||
[state opts child]
|
||||
[state {:keys [fixed-position?] :as opts} child]
|
||||
(let [*mounted? (::mounted? state)
|
||||
mounted? @*mounted?]
|
||||
(Tippy (->
|
||||
|
@ -638,6 +638,12 @@
|
|||
:disabled (not (state/enable-tooltip?))
|
||||
:unmountHTMLWhenHide true
|
||||
:open @*mounted?
|
||||
;; See https://github.com/tvkhoa/react-tippy/issues/13
|
||||
:popperOptions (if fixed-position?
|
||||
{:modifiers {:preventOverflow {:enabled false}
|
||||
:flip {:enabled false}
|
||||
:hide {:enabled false}}}
|
||||
{})
|
||||
:onShow #(reset! *mounted? true)
|
||||
:onHide #(reset! *mounted? false)}
|
||||
opts)
|
||||
|
|
Loading…
Reference in New Issue