mirror of https://github.com/usememos/memos.git
fix(web): add clipboard fallback for CodeBlock copy button in non-secure contexts
The CodeBlock component was refactored in v0.25.3 to use navigator.clipboard.writeText(), which requires HTTPS or localhost. This caused the copy button to fail silently for users accessing Memos over HTTP. This fix adds a fallback to the copy-to-clipboard library (already used by all other copy operations in the codebase) when the native clipboard API is unavailable or fails, ensuring the copy button works reliably in all deployment scenarios. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
a2ddf05933
commit
b1a52f20ed
|
|
@ -1,3 +1,4 @@
|
||||||
|
import copy from "copy-to-clipboard";
|
||||||
import hljs from "highlight.js";
|
import hljs from "highlight.js";
|
||||||
import { CheckIcon, CopyIcon } from "lucide-react";
|
import { CheckIcon, CopyIcon } from "lucide-react";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
|
|
@ -82,11 +83,31 @@ export const CodeBlock = observer(({ children, className, ...props }: CodeBlockP
|
||||||
|
|
||||||
const handleCopy = async () => {
|
const handleCopy = async () => {
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(codeContent);
|
// Try native clipboard API first (requires HTTPS or localhost)
|
||||||
setCopied(true);
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
setTimeout(() => setCopied(false), 2000);
|
await navigator.clipboard.writeText(codeContent);
|
||||||
|
setCopied(true);
|
||||||
|
setTimeout(() => setCopied(false), 2000);
|
||||||
|
} else {
|
||||||
|
// Fallback to copy-to-clipboard library for non-secure contexts
|
||||||
|
const success = copy(codeContent);
|
||||||
|
if (success) {
|
||||||
|
setCopied(true);
|
||||||
|
setTimeout(() => setCopied(false), 2000);
|
||||||
|
} else {
|
||||||
|
console.error("Failed to copy code");
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Failed to copy code:", err);
|
// If native API fails, try fallback
|
||||||
|
console.warn("Native clipboard failed, using fallback:", err);
|
||||||
|
const success = copy(codeContent);
|
||||||
|
if (success) {
|
||||||
|
setCopied(true);
|
||||||
|
setTimeout(() => setCopied(false), 2000);
|
||||||
|
} else {
|
||||||
|
console.error("Failed to copy code:", err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue