diff --git a/web/src/components/code-viewer.tsx b/web/src/components/code-viewer.tsx index dcd23792..c2547d76 100644 --- a/web/src/components/code-viewer.tsx +++ b/web/src/components/code-viewer.tsx @@ -31,10 +31,7 @@ export function CopyButton({ value, className, src, variant = "ghost", ...props size="icon" type="button" variant={variant} - className={cn( - "relative z-10 h-6 w-6 text-zinc-50 hover:bg-zinc-700 hover:text-zinc-50 [&_svg]:h-3 [&_svg]:w-3", - className, - )} + className={cn("relative z-10 h-6 w-6 text-zinc-50 hover:bg-zinc-700 hover:text-zinc-50", className)} onClick={() => { copyToClipboardWithMeta(value); setHasCopied(true); diff --git a/web/src/components/copyable-field.tsx b/web/src/components/copyable-field.tsx new file mode 100644 index 00000000..acb3240b --- /dev/null +++ b/web/src/components/copyable-field.tsx @@ -0,0 +1,39 @@ +import { Button } from "@/components/ui/button"; +import { Label } from "@/components/ui/label"; +import { Check, Copy } from "lucide-react"; +import { useCallback, useState } from "react"; +import { toast } from "sonner"; + +interface CopyableFieldProps { + label: string; + value?: string; + size?: number; +} + +export function CopyableField({ label, value, size }: CopyableFieldProps) { + const [copied, setCopied] = useState(false); + + const copyToClipboard = useCallback(() => { + if (typeof value === "string") { + navigator.clipboard.writeText(value).then(() => { + setCopied(true); + toast.success(`复制${label}成功`); + setTimeout(() => setCopied(false), 2000); + }); + } + }, [value, label]); + + return ( +
+
+ +

+ {value} {size != null && `(${size} bytes)`} +

+
+ +
+ ); +} diff --git a/web/src/components/main-config-card.tsx b/web/src/components/main-config-card.tsx index 2ebcf520..5b9e5e8a 100644 --- a/web/src/components/main-config-card.tsx +++ b/web/src/components/main-config-card.tsx @@ -34,6 +34,47 @@ export function MainConfigCard({ const [shellTools, setShellTools] = useState([]); const [shellTypes, setShellTypes] = useState([]); + const handleServerChange = (value: string) => { + if (mainConfig) { + setShellToolMap(mainConfig[value]); + setShellTools(Object.keys(mainConfig[value])); + setShellTypes([]); + form.resetField("shellTool"); + form.resetField("shellType"); + } + }; + + const handleShellToolChange = (value: string) => { + const resetCommand = () => { + form.resetField("commandParamName"); + }; + + const resetGodzilla = () => { + form.resetField("godzillaKey"); + form.resetField("godzillaPass"); + form.resetField("godzillaHeaderName"); + form.resetField("godzillaHeaderValue"); + }; + + const resetBehinder = () => { + form.resetField("behinderPass"); + form.resetField("behinderHeaderName"); + form.resetField("behinderHeaderValue"); + }; + + if (shellToolMap) { + setShellTypes(shellToolMap[value]); + form.resetField("urlPattern"); + if (value === "Godzilla") { + resetGodzilla(); + } else if (value === "Behinder") { + resetBehinder(); + } else if (value === "Command") { + resetCommand(); + } + } + }; + return ( @@ -54,11 +95,7 @@ export function MainConfigCard({