mirror of
https://github.com/logseq/logseq.git
synced 2026-05-15 16:32:21 +00:00
enhance(ux): align for the image asset block container (#12425)
* feat(asset): add alignment options for images * enhance(ux): select block for the action of double click in the image asset container * enhance(asset): change alignment property type from string to keyword and normalize alignment handling
This commit is contained in:
@@ -510,7 +510,8 @@
|
||||
[:logseq.property.asset/checksum :string]
|
||||
[:logseq.property.asset/size :int]
|
||||
[:logseq.property.asset/width {:optional true} :int]
|
||||
[:logseq.property.asset/height {:optional true} :int]]
|
||||
[:logseq.property.asset/height {:optional true} :int]
|
||||
[:logseq.property.asset/align {:optional true} :keyword]]
|
||||
block-attrs
|
||||
page-or-block-attrs)))
|
||||
|
||||
|
||||
5
deps/db/src/logseq/db/frontend/property.cljs
vendored
5
deps/db/src/logseq/db/frontend/property.cljs
vendored
@@ -567,6 +567,11 @@
|
||||
:schema {:type :map
|
||||
:hide? true
|
||||
:public? false}}
|
||||
:logseq.property.asset/align {:title "Asset alignment"
|
||||
:schema {:type :keyword
|
||||
:hide? true
|
||||
:public? false}
|
||||
:queryable? false}
|
||||
:logseq.property.fsrs/due {:title "Due"
|
||||
:schema
|
||||
{:type :datetime
|
||||
|
||||
2
deps/db/src/logseq/db/frontend/schema.cljs
vendored
2
deps/db/src/logseq/db/frontend/schema.cljs
vendored
@@ -30,7 +30,7 @@
|
||||
(map (juxt :major :minor)
|
||||
[(parse-schema-version x) (parse-schema-version y)])))
|
||||
|
||||
(def version (parse-schema-version "65.22"))
|
||||
(def version (parse-schema-version "65.23"))
|
||||
|
||||
(defn major-version
|
||||
"Return a number.
|
||||
|
||||
@@ -202,11 +202,24 @@
|
||||
(on-dimensions (.-naturalWidth img) (.-naturalHeight img))))
|
||||
(set! (.-src img) url)))
|
||||
|
||||
(defn- normalize-asset-align
|
||||
[asset-align]
|
||||
(cond
|
||||
(keyword? asset-align) asset-align
|
||||
(string? asset-align) (case asset-align
|
||||
"left" :left
|
||||
"center" :center
|
||||
"right" :right
|
||||
nil)
|
||||
:else nil))
|
||||
|
||||
(defonce *resizing-image? (atom false))
|
||||
|
||||
(rum/defc ^:large-vars/cleanup-todo asset-container
|
||||
[asset-block src title metadata {:keys [breadcrumb? positioned? local? full-text]}]
|
||||
(let [asset-width (:logseq.property.asset/width asset-block)
|
||||
asset-height (:logseq.property.asset/height asset-block)]
|
||||
asset-height (:logseq.property.asset/height asset-block)
|
||||
asset-align (normalize-asset-align (:logseq.property.asset/align asset-block))]
|
||||
(hooks/use-effect!
|
||||
(fn []
|
||||
(when (:block/uuid asset-block)
|
||||
@@ -275,7 +288,13 @@
|
||||
:repo (state/get-current-repo)
|
||||
:href src
|
||||
:title title
|
||||
:full-text full-text})))))))]
|
||||
:full-text full-text})))))))
|
||||
handle-set-align!
|
||||
(fn [align]
|
||||
(when-let [asset-id (:block/uuid asset-block)]
|
||||
(property-handler/set-block-property! asset-id
|
||||
:logseq.property.asset/align
|
||||
align)))]
|
||||
(when asset-block
|
||||
[:.asset-action-bar {:aria-hidden "true"}
|
||||
(shui/dropdown-menu
|
||||
@@ -288,6 +307,33 @@
|
||||
:class "h-6 w-6"}
|
||||
(shui/tabler-icon "dots-vertical")))
|
||||
(shui/dropdown-menu-content
|
||||
(shui/dropdown-menu-sub
|
||||
(shui/dropdown-menu-sub-trigger
|
||||
[:span.flex.items-center.gap-1
|
||||
(ui/icon "layout-align-left") (t :asset/align)])
|
||||
(shui/dropdown-menu-sub-content
|
||||
(shui/dropdown-menu-item
|
||||
{:on-click #(handle-set-align! :left)}
|
||||
[:span.flex.items-center.gap-2
|
||||
(ui/icon "layout-align-left")
|
||||
(t :asset/align-left)
|
||||
(when (or (nil? asset-align) (= asset-align :left))
|
||||
(ui/icon "check"))])
|
||||
(shui/dropdown-menu-item
|
||||
{:on-click #(handle-set-align! :center)}
|
||||
[:span.flex.items-center.gap-2
|
||||
(ui/icon "layout-align-center")
|
||||
(t :asset/align-center)
|
||||
(when (= asset-align :center)
|
||||
(ui/icon "check"))])
|
||||
(shui/dropdown-menu-item
|
||||
{:on-click #(handle-set-align! :right)}
|
||||
[:span.flex.items-center.gap-2
|
||||
(ui/icon "layout-align-right")
|
||||
(t :asset/align-right)
|
||||
(when (= asset-align :right)
|
||||
(ui/icon "check"))])))
|
||||
|
||||
(shui/dropdown-menu-item
|
||||
{:on-click handle-copy!}
|
||||
[:span.flex.items-center.gap-1
|
||||
@@ -301,6 +347,7 @@
|
||||
(js/window.apis.openExternal image-src)))}
|
||||
[:span.flex.items-center.gap-1
|
||||
(ui/icon "folder-pin") (t (if local? :asset/show-in-folder :asset/open-in-browser))]))
|
||||
|
||||
(when-not config/publishing?
|
||||
[:<>
|
||||
(shui/dropdown-menu-separator)
|
||||
@@ -318,6 +365,7 @@
|
||||
(let [breadcrumb? (:breadcrumb? config)
|
||||
positioned? (:property-position config)
|
||||
asset-block (:asset-block config)
|
||||
asset-align (normalize-asset-align (:logseq.property.asset/align asset-block))
|
||||
width (:width metadata)
|
||||
*width (get state ::size)
|
||||
width (or @*width width)
|
||||
@@ -334,30 +382,42 @@
|
||||
(:table-view? config)
|
||||
(not resizable?))
|
||||
asset-container-cp
|
||||
[:div.ls-resize-image.rounded-md
|
||||
asset-container-cp
|
||||
(resize-image-handles
|
||||
(fn [k ^js event]
|
||||
(let [dx (.-dx event)
|
||||
^js target (.-target event)]
|
||||
[:div.ls-resize-inner.w-full.select-none
|
||||
{:on-double-click (fn [^js e]
|
||||
(let [^js target (.-target e)
|
||||
^js container (.closest target ".ls-resize-inner")]
|
||||
(when (or container (= target container))
|
||||
(when-let [block-uuid (or (:block/uuid config)
|
||||
(some-> config :block :block/uuid))]
|
||||
(editor-handler/select-block! block-uuid)))))}
|
||||
[:div.ls-resize-image.rounded-md
|
||||
{:class (case asset-align
|
||||
:center "align-center"
|
||||
:right "align-right"
|
||||
"align-left")}
|
||||
asset-container-cp
|
||||
(resize-image-handles
|
||||
(fn [k ^js event]
|
||||
(let [dx (.-dx event)
|
||||
^js target (.-target event)]
|
||||
|
||||
(case k
|
||||
:start
|
||||
(let [c (.closest target ".ls-resize-image")]
|
||||
(reset! *width (.-offsetWidth c))
|
||||
(reset! *resizing-image? true))
|
||||
:move
|
||||
(let [width' (+ @*width dx)]
|
||||
(when (or (> width' 60)
|
||||
(not (neg? dx)))
|
||||
(reset! *width width')))
|
||||
:end
|
||||
(let [width' @*width]
|
||||
(when (and width' @*resizing-image?)
|
||||
(when-let [block-id (or (:block/uuid config)
|
||||
(some-> config :block (:block/uuid)))]
|
||||
(editor-handler/resize-image! config block-id metadata full-text {:width width'})))
|
||||
(reset! *resizing-image? false))))))])))
|
||||
(case k
|
||||
:start
|
||||
(let [c (.closest target ".ls-resize-image")]
|
||||
(reset! *width (.-offsetWidth c))
|
||||
(reset! *resizing-image? true))
|
||||
:move
|
||||
(let [width' (+ @*width dx)]
|
||||
(when (or (> width' 60)
|
||||
(not (neg? dx)))
|
||||
(reset! *width width')))
|
||||
:end
|
||||
(let [width' @*width]
|
||||
(when (and width' @*resizing-image?)
|
||||
(when-let [block-id (or (:block/uuid config)
|
||||
(some-> config :block (:block/uuid)))]
|
||||
(editor-handler/resize-image! config block-id metadata full-text {:width width'})))
|
||||
(reset! *resizing-image? false))))))]])))
|
||||
|
||||
(rum/defc audio-cp
|
||||
([src] (audio-cp src nil))
|
||||
|
||||
@@ -1194,6 +1194,19 @@ html.is-mac {
|
||||
.ls-resize-image {
|
||||
@apply flex relative w-fit cursor-pointer;
|
||||
|
||||
&.align-left {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
&.align-center {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
&.align-right {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.handle-left, .handle-right {
|
||||
@apply absolute w-[6px] h-[15%] min-h-[30px] bg-black/30 hover:bg-black/70
|
||||
top-[50%] left-[5px] rounded-full cursor-col-resize select-none
|
||||
|
||||
@@ -75,7 +75,8 @@
|
||||
["65.20" {:properties [:logseq.property.class/bidirectional-property-title :logseq.property.class/enable-bidirectional?]}]
|
||||
["65.21" {:properties [:logseq.property.sync/large-title-object]}]
|
||||
["65.22" {:properties [:logseq.property.reaction/emoji-id
|
||||
:logseq.property.reaction/target]}]])
|
||||
:logseq.property.reaction/target]}]
|
||||
["65.23" {:properties [:logseq.property.asset/align]}]])
|
||||
|
||||
(let [[major minor] (last (sort (map (comp (juxt :major :minor) db-schema/parse-schema-version first)
|
||||
schema-version->updates)))]
|
||||
|
||||
@@ -135,6 +135,10 @@
|
||||
:asset/ref-block "Asset ref block"
|
||||
:asset/confirm-delete "Are you sure you want to delete this {1}?"
|
||||
:asset/physical-delete "Remove the file too (notice it can't be restored)"
|
||||
:asset/align "Align"
|
||||
:asset/align-left "Align left"
|
||||
:asset/align-center "Align center"
|
||||
:asset/align-right "Align right"
|
||||
:color/gray "Gray"
|
||||
:color/red "Red"
|
||||
:color/yellow "Yellow"
|
||||
|
||||
Reference in New Issue
Block a user