fix: copy to clipboard

This commit is contained in:
naiba
2024-11-30 17:08:47 +08:00
parent eca99201b3
commit 5c0c358255
6 changed files with 42 additions and 7 deletions

16
package-lock.json generated
View File

@@ -29,6 +29,7 @@
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"cmdk": "^1.0.0", "cmdk": "^1.0.0",
"copy-to-clipboard": "^3.3.3",
"i18next": "^24.0.2", "i18next": "^24.0.2",
"jotai-zustand": "^0.6.0", "jotai-zustand": "^0.6.0",
"lucide-react": "^0.454.0", "lucide-react": "^0.454.0",
@@ -3627,6 +3628,15 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/copy-to-clipboard": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz",
"integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==",
"license": "MIT",
"dependencies": {
"toggle-selection": "^1.0.6"
}
},
"node_modules/cosmiconfig": { "node_modules/cosmiconfig": {
"version": "9.0.0", "version": "9.0.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
@@ -6231,6 +6241,12 @@
"node": ">=8.0" "node": ">=8.0"
} }
}, },
"node_modules/toggle-selection": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
"integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==",
"license": "MIT"
},
"node_modules/tr46": { "node_modules/tr46": {
"version": "0.0.3", "version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",

View File

@@ -32,6 +32,7 @@
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"cmdk": "^1.0.0", "cmdk": "^1.0.0",
"copy-to-clipboard": "^3.3.3",
"i18next": "^24.0.2", "i18next": "^24.0.2",
"jotai-zustand": "^0.6.0", "jotai-zustand": "^0.6.0",
"lucide-react": "^0.454.0", "lucide-react": "^0.454.0",

View File

@@ -14,7 +14,7 @@ import useWebSocket from "react-use-websocket"
import { toast } from "sonner" import { toast } from "sonner"
import { ColumnDef } from "@tanstack/react-table" import { ColumnDef } from "@tanstack/react-table"
import { Folder, File } from "lucide-react" import { Folder, File } from "lucide-react"
import { fm, formatPath, fmWorker as worker } from "@/lib/utils" import { copyToClipboard, fm, formatPath, fmWorker as worker } from "@/lib/utils"
import { import {
AlertDialog, AlertDialog,
AlertDialogContent, AlertDialogContent,
@@ -293,7 +293,7 @@ const FMComponent: React.FC<FMProps & JSX.IntrinsicElements["div"]> = ({ wsUrl,
<DropdownMenuItem onClick={listFile}>{t('Refresh')}</DropdownMenuItem> <DropdownMenuItem onClick={listFile}>{t('Refresh')}</DropdownMenuItem>
<DropdownMenuItem onClick={ <DropdownMenuItem onClick={
async () => { async () => {
await navigator.clipboard.writeText(formatPath(currentPath)); await copyToClipboard(formatPath(currentPath));
} }
}>{t("CopyPath")}</DropdownMenuItem> }>{t("CopyPath")}</DropdownMenuItem>
<AlertDialogTrigger asChild> <AlertDialogTrigger asChild>

View File

@@ -12,6 +12,7 @@ import { Check, Clipboard } from "lucide-react"
import { toast } from "sonner" import { toast } from "sonner"
import { useTranslation } from "react-i18next" import { useTranslation } from "react-i18next"
import { copyToClipboard } from "@/lib/utils"
enum OSTypes { enum OSTypes {
Linux = 1, Linux = 1,
@@ -29,7 +30,8 @@ export const InstallCommandsMenu = forwardRef<HTMLButtonElement, ButtonProps>((p
try { try {
setCopy(true); setCopy(true);
if (settings) if (settings)
await navigator.clipboard.writeText(generateCommand(type, settings) || ''); await copyToClipboard(generateCommand(type, settings) || '');
} catch (e) { } catch (e) {
console.error(e); console.error(e);
toast(t("Error"), { toast(t("Error"), {
@@ -52,9 +54,9 @@ export const InstallCommandsMenu = forwardRef<HTMLButtonElement, ButtonProps>((p
</Button> </Button>
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent> <DropdownMenuContent>
<DropdownMenuItem onClick={async () => { switchState(OSTypes.Linux) }}>Linux</DropdownMenuItem> <DropdownMenuItem className="nezha-copy" onClick={async () => { switchState(OSTypes.Linux) }}>Linux</DropdownMenuItem>
<DropdownMenuItem onClick={async () => { switchState(OSTypes.macOS) }}>macOS</DropdownMenuItem> <DropdownMenuItem className="nezha-copy" onClick={async () => { switchState(OSTypes.macOS) }}>macOS</DropdownMenuItem>
<DropdownMenuItem onClick={async () => { switchState(OSTypes.Windows) }}>Windows</DropdownMenuItem> <DropdownMenuItem className="nezha-copy" onClick={async () => { switchState(OSTypes.Windows) }}>Windows</DropdownMenuItem>
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
); );

View File

@@ -10,6 +10,7 @@ import { IconButton } from "./xui/icon-button"
import { toast } from "sonner"; import { toast } from "sonner";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { copyToClipboard } from "@/lib/utils";
interface NoteMenuProps extends ButtonProps { interface NoteMenuProps extends ButtonProps {
note: { private?: string, public?: string }; note: { private?: string, public?: string };
@@ -29,7 +30,7 @@ export const NoteMenu = forwardRef<HTMLButtonElement, NoteMenuProps>((props, ref
if (!copy) { if (!copy) {
setCopy(true); setCopy(true);
await navigator.clipboard.writeText(text); await copyToClipboard(text);
setTimeout(() => { setTimeout(() => {
setCopy(false); setCopy(false);
}, 2 * 1000); }, 2 * 1000);

View File

@@ -3,6 +3,7 @@ import { twMerge } from "tailwind-merge"
import { z } from "zod" import { z } from "zod"
import { FMEntry, FMOpcode, ModelIP } from "@/types" import { FMEntry, FMOpcode, ModelIP } from "@/types"
import FMWorker from "./fm?worker" import FMWorker from "./fm?worker"
import copy from "copy-to-clipboard"
export function cn(...inputs: ClassValue[]) { export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs)) return twMerge(clsx(inputs))
@@ -165,3 +166,17 @@ function ipv6BinaryToString(binary: Uint8Array) {
return ipv6; return ipv6;
} }
export async function copyToClipboard(text: string) {
try {
return await navigator.clipboard.writeText(text);
} catch (error) {
console.error('navigator', error);
}
try {
return copy(text)
} catch (error) {
console.error('copy', error);
}
throw new Error('Failed to copy text to clipboard');
}