fix: can't copy image on mobile

This commit is contained in:
Tienson Qin
2025-11-27 13:10:10 +08:00
parent 7dfb673a2b
commit f24583d82a
4 changed files with 78 additions and 54 deletions

View File

@@ -114,7 +114,7 @@
"@capacitor/android": "7.2.0",
"@capacitor/app": "7.0.1",
"@capacitor/camera": "7.0.1",
"@capacitor/clipboard": "7.0.1",
"@capacitor/clipboard": "^7.0.2",
"@capacitor/core": "7.2.0",
"@capacitor/device": "^7.0.2",
"@capacitor/dialog": "^7.0.2",

View File

@@ -355,7 +355,9 @@
(let [handle-copy!
(fn [_e]
(-> (util/copy-image-to-clipboard image-src)
(p/then #(notification/show! "Copied!" :success))))
(p/then #(notification/show! "Copied!" :success))
(p/catch (fn [error]
(js/console.error error)))))
handle-delete!
(fn [_e]
(when-let [block-id (get-blockid)]
@@ -381,47 +383,38 @@
:href src
:title title
:full-text full-text})))))))]
[:.asset-action-bar {:aria-hidden "true"}
(shui/button-group
(shui/button
{:variant :outline
:size :icon
:class "h-7 w-7"
:on-pointer-down util/stop
:on-click (fn [e]
(shui/popup-show! (.closest (.-target e) ".asset-action-bar")
(fn []
[:div
{:on-click #(shui/popup-hide!)}
(shui/dropdown-menu-item
{:on-click #(some-> (db/entity [:block/uuid (get-blockid)])
(editor-handler/edit-block! :max {:container-id :unknown-container}))}
[:span.flex.items-center.gap-1
(ui/icon "edit") (t :asset/edit-block)])
(shui/dropdown-menu-item
{:on-click handle-copy!}
[:span.flex.items-center.gap-1
(ui/icon "copy") (t :asset/copy)])
(when (util/electron?)
(shui/dropdown-menu-item
{:on-click (fn [e]
(util/stop e)
(if local?
(ipc/ipc "openFileInFolder" image-src)
(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)
(shui/dropdown-menu-item
{:on-click handle-delete!}
[:span.flex.items-center.gap-1.text-red-700
(ui/icon "trash") (t :asset/delete)])])])
{:align :start
:dropdown-menu? true}))}
(shui/tabler-icon "dots-vertical")))])])])))
(when asset-block
[:.asset-action-bar {:aria-hidden "true"}
(shui/dropdown-menu
{:on-pointer-down util/stop}
(shui/dropdown-menu-trigger
{:as-child true}
(shui/button
{:variant :outline
:size :icon
:class "h-6 w-6"}
(shui/tabler-icon "dots-vertical")))
(shui/dropdown-menu-content
(shui/dropdown-menu-item
{:on-click handle-copy!}
[:span.flex.items-center.gap-1
(ui/icon "copy") (t :asset/copy)])
(when (util/electron?)
(shui/dropdown-menu-item
{:on-click (fn [e]
(util/stop e)
(if local?
(ipc/ipc "openFileInFolder" image-src)
(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)
(shui/dropdown-menu-item
{:on-click handle-delete!}
[:span.flex.items-center.gap-1.text-red-700
(ui/icon "trash") (t :asset/delete)])])))]))])])))
(rum/defcs ^:large-vars/cleanup-todo resizable-image <
(rum/local nil ::size)

View File

@@ -1364,13 +1364,44 @@
(set! (.-src image) data-url))))
#?(:cljs
(defn write-blob-to-clipboard
[blob]
(->> blob
(js-obj (.-type blob))
(js/ClipboardItem.)
(array)
(js/navigator.clipboard.write))))
(def native-clipboard (gobj/get CapacitorClipboard "Clipboard")))
#?(:cljs
(do
;; Helper: Blob -> data URL (returns a JS Promise)
(defn blob->data-url [blob]
(js/Promise.
(fn [resolve reject]
(let [reader (js/FileReader.)]
(set! (.-onload reader)
(fn [_e]
;; result is a "data:<mime>;base64,..." string
(resolve (.-result reader))))
(set! (.-onerror reader)
(fn [_e]
(reject (.-error reader))))
(.readAsDataURL reader blob)))))
(defn write-blob-to-clipboard [blob]
(if native-clipboard
;; 1) Native (Capacitor) path expects a data URL
(-> (blob->data-url blob)
(.then (fn [data-url]
;; Your Capacitor plugin signature: { image: <data-url> }
(.write native-clipboard #js {:image data-url})))
(.then (fn []
(js/console.log "Copied via native clipboard")))
(.catch (fn [err]
(js/console.error "Native clipboard failed" err))))
;; 2) Web Clipboard API path (desktop browsers etc.)
(let [item (js/ClipboardItem.
(js-obj (.-type blob) blob))]
(-> (.write (.-clipboard js/navigator) (array item))
(.then (fn []
(js/console.log "Copied via web clipboard")))
(.catch (fn [err]
(js/console.error "Web clipboard failed" err)))))))))
#?(:cljs
(defn copy-image-to-clipboard

View File

@@ -299,10 +299,10 @@
tslib "^2.8.1"
xml2js "^0.6.2"
"@capacitor/clipboard@7.0.1":
version "7.0.1"
resolved "https://registry.yarnpkg.com/@capacitor/clipboard/-/clipboard-7.0.1.tgz#159fefa56b7d23632e9d08c9efd9cbd75a868b21"
integrity sha512-n4XEHma7apLOYvyeaR9S5u3uGzDYG7WeQxmtZlwP01HneIzMnusVgw4Im6I+pMBcoUN9TfVdf6eqKph97B1bAw==
"@capacitor/clipboard@^7.0.2":
version "7.0.2"
resolved "https://registry.yarnpkg.com/@capacitor/clipboard/-/clipboard-7.0.2.tgz#fe9ea01032581f68feda79c19304c5f82e1995f1"
integrity sha512-Cm37cNPvSzuao3HlcrQT18py5WUfKdaNWBHFuQcubBzBuKhqtAC9P6xZ2d0ucPFdxvsEOgO7mjs2BWIpaKqpgg==
"@capacitor/core@7.2.0":
version "7.2.0"