mirror of
https://github.com/logseq/logseq.git
synced 2026-06-01 19:01:22 +00:00
cmdk initial implementation
This commit is contained in:
@@ -541,15 +541,16 @@
|
||||
(let [*mouse-down? (::mouse-down? state)
|
||||
tag? (:tag? config)
|
||||
config (assoc config :whiteboard-page? whiteboard-page?)
|
||||
untitled? (model/untitled-page? page-name)
|
||||
gradient-styles (state/sub-color-gradient-text-styles :09)]
|
||||
untitled? (model/untitled-page? page-name)]
|
||||
; gradient-styles (state/sub-color-gradient-text-styles :09)]
|
||||
|
||||
[:a
|
||||
{:tabIndex "0"
|
||||
:class (cond-> (if tag? "tag" "page-ref")
|
||||
(:property? config)
|
||||
(str " page-property-key block-property")
|
||||
untitled? (str " opacity-50"))
|
||||
:style gradient-styles
|
||||
:style {:color "var(--lx-accent-10)"}
|
||||
:data-ref page-name
|
||||
:draggable true
|
||||
:on-drag-start (fn [e] (editor-handler/block->data-transfer! page-name-in-block e))
|
||||
@@ -758,10 +759,7 @@
|
||||
(excalidraw s block-uuid)]
|
||||
[:span.page-reference
|
||||
{:data-ref s
|
||||
:style {:background-image (colors/linear-gradient :grass "09" 5)
|
||||
:background-clip "text"
|
||||
"-webkit-background-clip" "text"
|
||||
:color "transparent"}}
|
||||
:style {:color "var(--lx-accent-09)"}}
|
||||
(when (and (or show-brackets? nested-link?)
|
||||
(not html-export?)
|
||||
(not contents-page?))
|
||||
@@ -2286,12 +2284,12 @@
|
||||
:data-type (name block-type)
|
||||
:style {:width "100%" :pointer-events (when stop-events? "none")}}
|
||||
|
||||
(not (string/blank? (:hl-color properties)))
|
||||
(assoc :data-hl-color (:hl-color properties))
|
||||
(not (string/blank? (:hl-color properties)))
|
||||
(assoc :data-hl-color (:hl-color properties))
|
||||
|
||||
(not block-ref?)
|
||||
(assoc mouse-down-key (fn [e]
|
||||
(block-content-on-mouse-down e block block-id content edit-input-id))))]
|
||||
(not block-ref?)
|
||||
(assoc mouse-down-key (fn [e]
|
||||
(block-content-on-mouse-down e block block-id content edit-input-id))))]
|
||||
[:div.block-content.inline
|
||||
(cond-> {:id (str "block-content-" uuid)
|
||||
:class (when selected? "select-none")
|
||||
@@ -2809,20 +2807,20 @@
|
||||
:blockid (str uuid)
|
||||
:haschild (str (boolean has-child?))}
|
||||
|
||||
level
|
||||
(assoc :level level)
|
||||
level
|
||||
(assoc :level level)
|
||||
|
||||
(not slide?)
|
||||
(merge attrs)
|
||||
(not slide?)
|
||||
(merge attrs)
|
||||
|
||||
(or reference? embed?)
|
||||
(assoc :data-transclude true)
|
||||
(or reference? embed?)
|
||||
(assoc :data-transclude true)
|
||||
|
||||
embed?
|
||||
(assoc :data-embed true)
|
||||
embed?
|
||||
(assoc :data-embed true)
|
||||
|
||||
custom-query?
|
||||
(assoc :data-query true))
|
||||
custom-query?
|
||||
(assoc :data-query true))
|
||||
|
||||
(when (and ref? breadcrumb-show?)
|
||||
(breadcrumb config repo uuid {:show-page? false
|
||||
|
||||
346
src/main/frontend/components/cmdk.cljs
Normal file
346
src/main/frontend/components/cmdk.cljs
Normal file
@@ -0,0 +1,346 @@
|
||||
(ns frontend.components.cmdk
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[frontend.components.block :as block]
|
||||
[frontend.components.command-palette :as cp]
|
||||
[frontend.components.page :as page]
|
||||
[frontend.context.i18n :refer [t]]
|
||||
[frontend.db :as db]
|
||||
[frontend.db.model :as model]
|
||||
[frontend.handler.command-palette :as cp-handler]
|
||||
[frontend.handler.editor :as editor-handler]
|
||||
[frontend.handler.route :as route-handler]
|
||||
[frontend.handler.search :as search-handler]
|
||||
[frontend.modules.shortcut.core :as shortcut]
|
||||
[frontend.modules.shortcut.data-helper :as shortcut-helper]
|
||||
[frontend.search :as search]
|
||||
[frontend.state :as state]
|
||||
[frontend.ui :as ui]
|
||||
[frontend.util :as util]
|
||||
[goog.functions :as gfun]
|
||||
[logseq.shui.context :refer [make-context]]
|
||||
[logseq.shui.core :as shui]
|
||||
[promesa.core :as p]
|
||||
[rum.core :as rum]))
|
||||
|
||||
;; When CMDK opens, we have some default search actions we make avaialbe for quick access
|
||||
(def default-search-actions
|
||||
[{:text "Search only pages" :info "Add filter to search"}
|
||||
{:text "Search only blocks" :info "Add filter to search"}
|
||||
{:text "Create block" :info "Add a block to today's journal page" :icon "block" :icon-theme :color}
|
||||
{:text "Generate short answer" :info "Ask a language model" :icon "question-mark" :icon-theme :gradient}
|
||||
{:text "Open settings" :icon "settings" :icon-theme :gray}])
|
||||
|
||||
;; The results are separated into groups, and loaded/fetched/queried separately
|
||||
(def default-results
|
||||
{:search-actions {:status :success :show-more false :items default-search-actions}
|
||||
:commands {:status :success :show-more false :items nil}
|
||||
:history {:status :success :show-more false :items nil}
|
||||
:current-page {:status :success :show-more false :items nil}
|
||||
:pages {:status :success :show-more false :items nil}
|
||||
:blocks {:status :success :show-more false :items nil}
|
||||
:files {:status :success :show-more false :items nil}})
|
||||
|
||||
;; Each result gorup has it's own load-results function
|
||||
(defmulti load-results (fn [group state] group))
|
||||
|
||||
;; The search-actions are only loaded when there is no query present. It's like a quick access to filters
|
||||
(defmethod load-results :search-actions [group state]
|
||||
(let [!input (::input state)
|
||||
!results (::results state)]
|
||||
(if (empty? @!input)
|
||||
(swap! !results assoc group {:status :success :items default-search-actions})
|
||||
(swap! !results assoc group {:status :success :items nil}))))
|
||||
|
||||
;; The commands search uses the command-palette hander
|
||||
(defmethod load-results :commands [group state]
|
||||
(let [!input (::input state)
|
||||
!results (::results state)]
|
||||
(swap! !results assoc-in [group :status] :loading)
|
||||
(->> (vals (cp-handler/get-commands-unique))
|
||||
(filter #(string/includes? (string/lower-case (pr-str %)) (string/lower-case @!input)))
|
||||
(map #(hash-map :icon "command"
|
||||
:icon-theme :gray
|
||||
:text (cp/translate t %)
|
||||
:value-label (pr-str (:id %))
|
||||
; :info (pr-str (:id %))
|
||||
; :info (:desc %)
|
||||
:shortcut (:shortcut %)
|
||||
:source-command %))
|
||||
(hash-map :status :success :items)
|
||||
(swap! !results assoc group))
|
||||
(js/console.log "commands" (clj->js (get-in @!results [:commands :items])))))
|
||||
|
||||
;; The pages search action uses an existing handler
|
||||
(defmethod load-results :pages [group state]
|
||||
(let [!input (::input state)
|
||||
!results (::results state)]
|
||||
(swap! !results assoc-in [group :status] :loading)
|
||||
(p/let [pages (search/page-search @!input)
|
||||
items (map #(hash-map :icon "page"
|
||||
:icon-theme :gray
|
||||
:text %
|
||||
:source-page %) pages)]
|
||||
(js/console.log "pages" (pr-str pages) (clj->js items))
|
||||
(swap! !results assoc group {:status :success :items items}))))
|
||||
|
||||
;; The blocks search action uses an existing handler
|
||||
(defmethod load-results :blocks [group state]
|
||||
(let [!input (::input state)
|
||||
!results (::results state)
|
||||
repo (state/get-current-repo)
|
||||
opts {:limit 100}]
|
||||
(swap! !results assoc-in [group :status] :loading)
|
||||
(p/let [blocks (search/block-search repo @!input opts)
|
||||
items (map #(hash-map :icon "block"
|
||||
:icon-theme :gray
|
||||
:text (:block/content %)
|
||||
:header (some-> % :block/page db/entity :block/name)
|
||||
:source-block %) blocks)]
|
||||
|
||||
; (js/console.log "blocks" (clj->js items) (map (comp pr-str :block/page) blocks))
|
||||
; (js/console.log "blocks" (clj->js items)
|
||||
; (pr-str (map (comp pr-str :block/page) blocks))
|
||||
; (pr-str (map (comp :block/name :block/page) blocks))
|
||||
; (pr-str (map (comp :block/name db/entity :block/page) blocks)))
|
||||
(swap! !results assoc group {:status :success :items items}))))
|
||||
|
||||
;; The default load-results function triggers all the other load-results function
|
||||
(defmethod load-results :default [_ state]
|
||||
(js/console.log "load-results/default" @(::input state))
|
||||
(load-results :search-actions state)
|
||||
(load-results :commands state)
|
||||
(load-results :blocks state)
|
||||
(load-results :pages state))
|
||||
|
||||
; (def search [query]
|
||||
; (load-results :search-actions state))
|
||||
; (let [repo (state/get-current-repo)
|
||||
; limit 5
|
||||
; current-page-db-id nil
|
||||
; opts {:limit limit}]
|
||||
; (p/let [blocks (search/block-search repo q opts)
|
||||
; pages (search/page-search q)
|
||||
; pages-content (when current-page-db-id (search/page-content-search repo q opts))
|
||||
; files (search/file-search q)
|
||||
; commands])))
|
||||
|
||||
(defmulti handle-action (fn [action _state _item _event] action))
|
||||
|
||||
(defmethod handle-action :cancel [_ state item event]
|
||||
(js/console.log :handle-action/cancel)
|
||||
(state/close-modal!))
|
||||
|
||||
(defmethod handle-action :copy-page-ref [_ state item event]
|
||||
(when-let [page-name (:source-page item)]
|
||||
(util/copy-to-clipboard! page-name)
|
||||
(state/close-modal!)))
|
||||
|
||||
(defmethod handle-action :copy-block-ref [_ state item event]
|
||||
(when-let [block-uuid (some-> item :source-block :block/uuid uuid)]
|
||||
(editor-handler/copy-block-ref! block-uuid)
|
||||
(state/close-modal!)))
|
||||
|
||||
(defmethod handle-action :open-page [_ state item event]
|
||||
(when-let [page-name (:source-page item)]
|
||||
(route-handler/redirect-to-page! page-name)
|
||||
(state/close-modal!)))
|
||||
|
||||
(defmethod handle-action :open-block [_ state item event]
|
||||
(let [get-block-page (partial model/get-block-page (state/get-current-repo))]
|
||||
(when-let [page (some-> item :source-block :block/uuid uuid get-block-page :block/name model/get-redirect-page-name)]
|
||||
(route-handler/redirect-to-page! page)
|
||||
(state/close-modal!))))
|
||||
|
||||
(defmethod handle-action :open-page-right [_ state item event]
|
||||
(when-let [page-uuid (some-> item :source-page model/get-page :block/uuid uuid)]
|
||||
(js/console.log "oepn-page-right" page-uuid)
|
||||
(editor-handler/open-block-in-sidebar! page-uuid)))
|
||||
|
||||
(defmethod handle-action :open-block-right [_ state item event]
|
||||
(when-let [block-uuid (some-> item :source-block :block/uuid uuid)]
|
||||
(js/console.log "oepn-block-right" block-uuid)
|
||||
(editor-handler/open-block-in-sidebar! block-uuid)))
|
||||
|
||||
(defmethod handle-action :trigger [_ state item event])
|
||||
(defmethod handle-action :return [_ state item event])
|
||||
|
||||
(rum/defc result-group < rum/reactive
|
||||
[state title group visible-items highlighted-result]
|
||||
(let [{:keys [show-more items]} (some-> state ::results deref group)]
|
||||
[:div {:class ""}
|
||||
[:div {:class "text-xs py-1.5 px-6 flex justify-between items-center gap-2"
|
||||
:style {:color "var(--lx-gray-11)"
|
||||
:background "var(--lx-gray-02)"}}
|
||||
[:div {:class "font-bold"
|
||||
:style {:color "var(--lx-gray-11)"}} title]
|
||||
[:div {:class "bg-white/20 px-1.5 py-px text-white rounded-full"
|
||||
:style {:font-size "0.6rem"}}
|
||||
(if (<= 100 (count items))
|
||||
(str "99+")
|
||||
(count items))]
|
||||
[:div {:class "flex-1"}]
|
||||
(if show-more
|
||||
[:div {:on-click #(swap! (::results state) update-in [group :show-more] not)} "Show less"]
|
||||
[:div {:on-click #(swap! (::results state) update-in [group :show-more] not)} "Show more"])]
|
||||
|
||||
[:div {:class ""}
|
||||
(for [result visible-items
|
||||
:let [highlighted? (= result highlighted-result)]]
|
||||
(shui/list-item (assoc result
|
||||
:highlighted highlighted?
|
||||
:on-highlight (fn [ref]
|
||||
(.. ref -current (scrollIntoView #js {:block "center"
|
||||
:inline "nearest"
|
||||
:behavior "smooth"}))
|
||||
(case group
|
||||
:search-actions (reset! (::actions state) [:cancel :return])
|
||||
:commands (reset! (::actions state) [:cancel :trigger])
|
||||
:pages (reset! (::actions state) [:cancel :copy-page-ref :open-page-right :open-page])
|
||||
:blocks (reset! (::actions state) [:cancel :copy-block-ref :open-block-right :open-block])
|
||||
nil)))))]]))
|
||||
|
||||
|
||||
|
||||
(defonce keydown-handler
|
||||
(fn [state e]
|
||||
(when (#{"ArrowDown" "ArrowUp"} (.-key e))
|
||||
(.preventDefault e))
|
||||
(case (.-key e)
|
||||
; "Escape" (rum/dispatch! :close)
|
||||
"ArrowDown" (swap! (::highlight-index state) inc)
|
||||
"ArrowUp" (swap! (::highlight-index state) dec)
|
||||
; "j" (when (.-metaKey e)
|
||||
; (if (.-shiftKey e)
|
||||
; (swap! state update :current-engine prev-engine)
|
||||
; (swap! state update :current-engine next-engine)))
|
||||
; "ArrowUp" (rum/dispatch! :highlight-prev)
|
||||
; "Enter" (rum/dispatch! :select)
|
||||
(println (.-key e)))))
|
||||
|
||||
(defn handle-input-change [state e]
|
||||
(let [input (.. e -target -value)
|
||||
!input (::input state)
|
||||
!load-results-throttled (::load-results-throttled state)]
|
||||
;; update the input value in the UI
|
||||
(reset! !input input)
|
||||
|
||||
;; ensure that there is a throttled version of the load-results function
|
||||
(when-not @!load-results-throttled
|
||||
(reset! !load-results-throttled (gfun/throttle load-results 1000)))
|
||||
|
||||
;; retreive the laod-results function and update all the results
|
||||
(when-let [load-results-throttled @!load-results-throttled]
|
||||
(load-results-throttled :all state))))
|
||||
|
||||
(rum/defc page-preview [state highlighted]
|
||||
(let [page-name (:source-page highlighted)]
|
||||
(page/page {:page-name (model/get-redirect-page-name page-name) :whiteboard? true})))
|
||||
|
||||
(rum/defc block-preview [state highlighted]
|
||||
(let [block (:source-block highlighted)
|
||||
block-uuid-str (str (:block/uuid block))]
|
||||
; ((state/get-component :block/single-block) (uuid (:block/uuid block)))))
|
||||
; ((state/get-component :block/container) block)
|
||||
; ((state/get-component :block/embed) (uuid (:block/uuid block)))))
|
||||
; (block/block-container {} block)))
|
||||
(page/page {:parameters {:path {:name block-uuid-str}}
|
||||
:sidebar? true
|
||||
:repo (state/get-current-repo)})))
|
||||
|
||||
(rum/defcs cmdk <
|
||||
shortcut/disable-all-shortcuts
|
||||
(rum/local "" ::input)
|
||||
(rum/local 0 ::highlight-index)
|
||||
(rum/local nil ::keydown-handler)
|
||||
(rum/local default-results ::results)
|
||||
(rum/local nil ::load-results-throttled)
|
||||
(rum/local [:cancel :return] ::actions)
|
||||
{:did-mount (fn [state]
|
||||
(let [next-keydown-handler (partial keydown-handler state)]
|
||||
(when-let [prev-keydown-handler @(::keydown-handler state)]
|
||||
(js/window.removeEventListener "keydown" prev-keydown-handler))
|
||||
(js/window.addEventListener "keydown" next-keydown-handler)
|
||||
(reset! (::keydown-handler state) next-keydown-handler))
|
||||
state)
|
||||
:will-unmount (fn [state]
|
||||
(when-let [current-keydown-handler (some-> state ::keydown-handler deref)]
|
||||
(js/window.removeEventListener "keydown" current-keydown-handler))
|
||||
(reset! (::keydown-handler state) nil)
|
||||
state)}
|
||||
[state {:keys []}]
|
||||
(let [input @(::input state)
|
||||
actions @(::actions state)
|
||||
highlight-index @(::highlight-index state)
|
||||
results @(::results state)
|
||||
visible-items-for-group (fn [group]
|
||||
(let [{:keys [items show-more]} (get results group)]
|
||||
(if show-more items (take 5 items))))
|
||||
results-ordered [["Search actions" :search-actions (visible-items-for-group :search-actions)]
|
||||
["Commands" :commands (visible-items-for-group :commands)]
|
||||
["Pages" :pages (visible-items-for-group :pages)]
|
||||
["Blocks" :blocks (visible-items-for-group :blocks)]]
|
||||
results (mapcat last results-ordered)
|
||||
result-count (count results)
|
||||
highlighted-result-index (cond
|
||||
(zero? result-count) nil
|
||||
(<= 0 (mod highlight-index result-count)) (mod highlight-index result-count)
|
||||
:else (- result-count (mod highlight-index result-count)))
|
||||
highlighted-result (when highlighted-result-index
|
||||
(nth results highlighted-result-index nil))
|
||||
preview? (or (:source-page highlighted-result) (:source-block highlighted-result))]
|
||||
[:div.cp__cmdk {:class "-m-8 max-w-[90dvw] max-h-[90dvh] w-[60rem] h-[30.7rem] "}
|
||||
[:div {:class ""
|
||||
:style {:background "var(--lx-gray-02)"
|
||||
:border-bottom "1px solid var(--lx-gray-07)"}}
|
||||
[:input {:class "text-xl bg-transparent border-none w-full outline-none px-4 py-3"
|
||||
:placeholder "What are you looking for?"
|
||||
:ref #(when % (.focus %))
|
||||
:on-change (partial handle-input-change state)
|
||||
:value input}]]
|
||||
|
||||
[:div {:class (str "grid" (if preview? " grid-cols-2" " grid-cols-1"))}
|
||||
[:div {:class "pt-1 overflow-y-auto h-96"
|
||||
:style {:background "var(--lx-gray-02)"}}
|
||||
(for [[group-name group-key group-items] results-ordered
|
||||
:when (not-empty group-items)]
|
||||
(result-group state group-name group-key group-items highlighted-result))]
|
||||
(when preview?
|
||||
[:div {:class "h-96 overflow-y-auto"}
|
||||
(cond
|
||||
(:source-page highlighted-result)
|
||||
(page-preview state highlighted-result)
|
||||
(:source-block highlighted-result)
|
||||
(block-preview state highlighted-result))])]
|
||||
|
||||
[:div {:class "flex justify-between w-full px-4"
|
||||
:style {:background "var(--lx-gray-03)"
|
||||
:border-top "1px solid var(--lx-gray-07)"}}
|
||||
[:div {:class "flex items-stretch gap-2"}
|
||||
(for [[tab-name tab-icon] [["Search" "search"]
|
||||
["Capture" "square-plus"]]
|
||||
:let [active? (= tab-name "Search")]]
|
||||
[:div {:class "flex items-center px-1.5 gap-1 relative"}
|
||||
(when active?
|
||||
[:div {:class "absolute inset-x-0 top-0 h-0.5 bg-gray-500"}])
|
||||
(when active?
|
||||
(shui/icon tab-icon {:size "16"}))
|
||||
[:div {:class ""} tab-name]])]
|
||||
[:div {:class "flex items-center py-3 gap-4"}
|
||||
(for [action actions
|
||||
:let [on-click (partial handle-action action state highlighted-result)]]
|
||||
(case action
|
||||
:cancel (shui/button {:text "Cancel" :theme :gray :on-click on-click :shortcut ["esc"]})
|
||||
:copy-page-ref (shui/button {:text "Copy" :theme :gray :on-click on-click :shortcut ["cmd" "c"]})
|
||||
:copy-block-ref (shui/button {:text "Copy" :theme :gray :on-click on-click :shortcut ["cmd" "c"]})
|
||||
:open-page-right (shui/button {:text "Open in sidebar" :theme :gray :on-click on-click :shortcut ["shift" "return"]})
|
||||
:open-page (shui/button {:text "Open" :theme :color :on-click on-click :shortcut ["return"]})
|
||||
:open-block-right (shui/button {:text "Open in sidebar" :theme :gray :on-click on-click :shortcut ["shift" "return"]})
|
||||
:open-block (shui/button {:text "Open page" :theme :color :on-click on-click :shortcut ["return"]})
|
||||
:trigger (shui/button {:text "Trigger" :theme :color :on-click on-click :shortcut ["return"]})
|
||||
:return (shui/button {:text "Return" :theme :color :on-click on-click :shortcut ["return"]})))]]]))
|
||||
; (shui/button {:text "AI" :theme :gradient} (make-context {}))]]]))
|
||||
|
||||
(->> (cp-handler/get-commands-unique)
|
||||
vals
|
||||
(map (juxt :shortcut :id)))
|
||||
@@ -319,21 +319,21 @@
|
||||
[:div.cp__right-sidebar-settings.hide-scrollbar.gap-1 {:key "right-sidebar-settings"}
|
||||
[:div.text-sm
|
||||
[:button.button.cp__right-sidebar-settings-btn {:on-click (fn [_e]
|
||||
(state/sidebar-add-block! repo "contents" :contents))}
|
||||
(state/sidebar-add-block! repo "contents" :contents))}
|
||||
(t :right-side-bar/contents)]]
|
||||
|
||||
[:div.text-sm
|
||||
[:button.button.cp__right-sidebar-settings-btn {:on-click (fn []
|
||||
(when-let [page (get-current-page)]
|
||||
(state/sidebar-add-block!
|
||||
repo
|
||||
page
|
||||
:page-graph)))}
|
||||
(when-let [page (get-current-page)]
|
||||
(state/sidebar-add-block!
|
||||
repo
|
||||
page
|
||||
:page-graph)))}
|
||||
(t :right-side-bar/page-graph)]]
|
||||
|
||||
[:div.text-sm
|
||||
[:button.button.cp__right-sidebar-settings-btn {:on-click (fn [_e]
|
||||
(state/sidebar-add-block! repo "help" :help))}
|
||||
(state/sidebar-add-block! repo "help" :help))}
|
||||
(t :right-side-bar/help)]]
|
||||
|
||||
(when config/dev? [:div.text-sm
|
||||
|
||||
@@ -190,9 +190,9 @@
|
||||
'[:find ?path
|
||||
;; ?modified-at
|
||||
:where
|
||||
[?file :file/path ?path]
|
||||
[?file :file/path ?path]]
|
||||
;; [?file :file/last-modified-at ?modified-at]
|
||||
]
|
||||
|
||||
db)
|
||||
(seq)
|
||||
;; (sort-by last)
|
||||
@@ -919,6 +919,7 @@ independent of format as format specific heading characters are stripped"
|
||||
|
||||
(defn get-block-page
|
||||
[repo block-uuid]
|
||||
(assert (uuid? block-uuid) "get-block-page requires block-uuid to be of type uuid")
|
||||
(when-let [block (db-utils/entity repo [:block/uuid block-uuid])]
|
||||
(db-utils/entity repo (:db/id (:block/page block)))))
|
||||
|
||||
|
||||
@@ -190,6 +190,8 @@
|
||||
(state/set-component! :block/linked-references reference/block-linked-references)
|
||||
(state/set-component! :whiteboard/tldraw-preview whiteboard/tldraw-preview)
|
||||
(state/set-component! :block/single-block block/single-block-cp)
|
||||
(state/set-component! :block/container block/block-container)
|
||||
(state/set-component! :block/embed block/block-embed)
|
||||
(state/set-component! :editor/box editor/box)
|
||||
(command-palette/register-global-shortcut-commands))
|
||||
|
||||
|
||||
@@ -193,8 +193,16 @@
|
||||
(state/set-edit-content! edit-id new-value)
|
||||
(cursor/move-cursor-to input (+ cur-pos forward-pos))))))
|
||||
|
||||
(-> (random-uuid) str)
|
||||
|
||||
(defn open-block-in-sidebar!
|
||||
[block-id]
|
||||
; (assert (uuid? block-id) "frontend.handler.editor/open-block-in-sidebar! expects block-id to be of type uuid")
|
||||
(js/console.log "db-entity/block" block-id)
|
||||
(js/console.log "db-entity/entity" (db/entity [:block/uuid block-id]))
|
||||
; (js/console.log "db-entity/types" (str block-id) (uuid block-id))
|
||||
; (js/console.log "db-entity/string" (db/entity [:block/uuid (str block-id)]))
|
||||
; (js/console.log "db-entity/uuid" (db/entity [:block/uuid (uuid block-id)]))
|
||||
(when block-id
|
||||
(when-let [block (db/entity [:block/uuid block-id])]
|
||||
(let [page? (nil? (:block/page block))]
|
||||
@@ -831,9 +839,9 @@
|
||||
concat-prev-block? (boolean (and prev-block new-content))
|
||||
transact-opts (cond->
|
||||
{:outliner-op :delete-blocks}
|
||||
concat-prev-block?
|
||||
(assoc :concat-data
|
||||
{:last-edit-block (:block/uuid block)}))]
|
||||
concat-prev-block?
|
||||
(assoc :concat-data
|
||||
{:last-edit-block (:block/uuid block)}))]
|
||||
(outliner-tx/transact! transact-opts
|
||||
(if concat-prev-block?
|
||||
(let [prev-block' (if (seq (:block/_refs block-e))
|
||||
@@ -1267,7 +1275,7 @@
|
||||
|
||||
(defn save-block!
|
||||
([repo block-or-uuid content]
|
||||
(save-block! repo block-or-uuid content {}))
|
||||
(save-block! repo block-or-uuid content {}))
|
||||
([repo block-or-uuid content {:keys [properties] :as opts}]
|
||||
(let [block (if (or (uuid? block-or-uuid)
|
||||
(string? block-or-uuid))
|
||||
|
||||
@@ -12,12 +12,15 @@
|
||||
[clojure.string :as string]
|
||||
[datascript.core :as d]
|
||||
[frontend.commands :as commands]
|
||||
[frontend.components.block :as block]
|
||||
[frontend.components.cmdk :as cmdk]
|
||||
[frontend.components.command-palette :as command-palette]
|
||||
[frontend.components.conversion :as conversion-component]
|
||||
[frontend.components.diff :as diff]
|
||||
[frontend.components.encryption :as encryption]
|
||||
[frontend.components.file-sync :as file-sync]
|
||||
[frontend.components.git :as git-component]
|
||||
[frontend.components.page :as page]
|
||||
[frontend.components.plugins :as plugin]
|
||||
[frontend.components.search :as component-search]
|
||||
[frontend.components.shell :as shell]
|
||||
@@ -69,7 +72,6 @@
|
||||
[goog.dom :as gdom]
|
||||
[logseq.db.schema :as db-schema]
|
||||
[logseq.graph-parser.config :as gp-config]
|
||||
[logseq.shui.core :refer [cmdk]]
|
||||
[promesa.core :as p]
|
||||
[rum.core :as rum]))
|
||||
|
||||
@@ -412,8 +414,10 @@
|
||||
:label "ls-modal-search"}))
|
||||
|
||||
(defmethod handle :go/cmdk [_]
|
||||
(when-not (= cmdk (:modal/panel-content @state/state))
|
||||
(state/set-modal! cmdk
|
||||
(when-not (= cmdk/cmdk (:modal/panel-content @state/state))
|
||||
(state/set-modal! ; (partial cmdk {} (make-context {:blocks-container block/blocks-container :page-cp block/page-cp :page page/page}))
|
||||
; cmdk
|
||||
cmdk/cmdk
|
||||
{:fullscreen? false
|
||||
:close-btn? false
|
||||
:label "ls-modal-cmdk"
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
(:require
|
||||
[frontend.date :refer [int->local-time-2]]
|
||||
[frontend.state :as state]
|
||||
[logseq.shui.context :refer [make-context]]))
|
||||
[logseq.shui.context :refer [make-context]]
|
||||
[frontend.handler.search :as search-handler]))
|
||||
|
||||
(def default-versions {:logseq.table.version 1})
|
||||
|
||||
@@ -23,4 +24,5 @@
|
||||
:app-config (state/get-config)
|
||||
:inline inline
|
||||
:int->local-time-2 int->local-time-2
|
||||
:state state/state}))
|
||||
:state state/state
|
||||
:search search-handler/search}))
|
||||
|
||||
Reference in New Issue
Block a user