fix(ui): fallback to execCommand for clipboard copy when navigator.clipboard fails (#27993)
Co-authored-by: SpiritChen51 <spiritchen51@users.noreply.github.com>
This commit is contained in:
co-authored by
SpiritChen51
parent
e94aecaa08
commit
fe143df151
@@ -58,6 +58,27 @@ import { animate } from "motion"
|
|||||||
import { useLocation } from "@solidjs/router"
|
import { useLocation } from "@solidjs/router"
|
||||||
import { attached, inline, kind } from "./message-file"
|
import { attached, inline, kind } from "./message-file"
|
||||||
|
|
||||||
|
async function writeClipboard(text: string): Promise<boolean> {
|
||||||
|
const body = typeof document === "undefined" ? undefined : document.body
|
||||||
|
if (body) {
|
||||||
|
const textarea = document.createElement("textarea")
|
||||||
|
textarea.value = text
|
||||||
|
textarea.setAttribute("readonly", "")
|
||||||
|
textarea.style.position = "fixed"
|
||||||
|
textarea.style.opacity = "0"
|
||||||
|
textarea.style.pointerEvents = "none"
|
||||||
|
body.appendChild(textarea)
|
||||||
|
textarea.select()
|
||||||
|
const copied = document.execCommand("copy")
|
||||||
|
body.removeChild(textarea)
|
||||||
|
if (copied) return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const clipboard = typeof navigator === "undefined" ? undefined : navigator.clipboard
|
||||||
|
if (!clipboard?.writeText) return false
|
||||||
|
return clipboard.writeText(text).then(() => true, () => false)
|
||||||
|
}
|
||||||
|
|
||||||
function ShellSubmessage(props: { text: string; animate?: boolean }) {
|
function ShellSubmessage(props: { text: string; animate?: boolean }) {
|
||||||
let widthRef: HTMLSpanElement | undefined
|
let widthRef: HTMLSpanElement | undefined
|
||||||
let valueRef: HTMLSpanElement | undefined
|
let valueRef: HTMLSpanElement | undefined
|
||||||
@@ -1064,9 +1085,10 @@ export function UserMessageDisplay(props: { message: UserMessage; parts: PartTyp
|
|||||||
const handleCopy = async () => {
|
const handleCopy = async () => {
|
||||||
const content = text()
|
const content = text()
|
||||||
if (!content) return
|
if (!content) return
|
||||||
await navigator.clipboard.writeText(content)
|
if (await writeClipboard(content)) {
|
||||||
setState("copied", true)
|
setState("copied", true)
|
||||||
setTimeout(() => setState("copied", false), 2000)
|
setTimeout(() => setState("copied", false), 2000)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const revert = () => {
|
const revert = () => {
|
||||||
@@ -1490,9 +1512,10 @@ PART_MAPPING["text"] = function TextPartDisplay(props) {
|
|||||||
const handleCopy = async () => {
|
const handleCopy = async () => {
|
||||||
const content = text()
|
const content = text()
|
||||||
if (!content) return
|
if (!content) return
|
||||||
await navigator.clipboard.writeText(content)
|
if (await writeClipboard(content)) {
|
||||||
setCopied(true)
|
setCopied(true)
|
||||||
setTimeout(() => setCopied(false), 2000)
|
setTimeout(() => setCopied(false), 2000)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -1834,9 +1857,10 @@ ToolRegistry.register({
|
|||||||
const handleCopy = async () => {
|
const handleCopy = async () => {
|
||||||
const content = text()
|
const content = text()
|
||||||
if (!content) return
|
if (!content) return
|
||||||
await navigator.clipboard.writeText(content)
|
if (await writeClipboard(content)) {
|
||||||
setCopied(true)
|
setCopied(true)
|
||||||
setTimeout(() => setCopied(false), 2000)
|
setTimeout(() => setCopied(false), 2000)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user