style: fmt code

This commit is contained in:
ReaJason
2026-04-26 21:33:15 +08:00
parent d10323a054
commit ee560ff7ee
150 changed files with 948 additions and 1522 deletions
@@ -1,11 +1,9 @@
import type { MemShellFormSchema } from "@/types/schema";
import { Controller, type UseFormReturn } from "react-hook-form";
import { useTranslation } from "react-i18next";
import {
Field,
FieldContent,
FieldError,
FieldLabel,
} from "@/components/ui/field";
import { Field, FieldContent, FieldError, FieldLabel } from "@/components/ui/field";
import {
Select,
SelectContent,
@@ -13,7 +11,6 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import type { MemShellFormSchema } from "@/types/schema";
const JDKVersion = [
{ name: "Java6", value: "50" },
@@ -37,9 +34,7 @@ export function JREVersionFormField({
render={({ field, fieldState }) => (
<Field orientation="vertical" data-invalid={fieldState.invalid}>
<FieldContent>
<FieldLabel htmlFor="targetJdkVersion">
{t("common:targetJdkVersion")}
</FieldLabel>
<FieldLabel htmlFor="targetJdkVersion">{t("common:targetJdkVersion")}</FieldLabel>
<Select
onValueChange={(v) => {
if (Number.parseInt(v ?? "0", 10) >= 53) {
@@ -51,13 +46,8 @@ export function JREVersionFormField({
}}
value={field.value}
>
<SelectTrigger
id="targetJdkVersion"
aria-invalid={fieldState.invalid}
>
<SelectValue
data-placeholder={t("common:placeholders.select")}
/>
<SelectTrigger id="targetJdkVersion" aria-invalid={fieldState.invalid}>
<SelectValue data-placeholder={t("common:placeholders.select")} />
</SelectTrigger>
<SelectContent>
{JDKVersion.map((v) => (
@@ -1,7 +1,10 @@
import type { MemShellFormSchema } from "@/types/schema";
import { ArrowUpRightIcon, InfoIcon, ServerIcon } from "lucide-react";
import { useCallback, useEffect, useMemo } from "react";
import { Controller, type UseFormReturn, useWatch } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { AntSwordTabContent } from "@/components/memshell/tabs/antsword-tab";
import { BehinderTabContent } from "@/components/memshell/tabs/behinder-tab";
import { CommandTabContent } from "@/components/memshell/tabs/command-tab";
@@ -10,12 +13,7 @@ import { GodzillaTabContent } from "@/components/memshell/tabs/godzilla-tab";
import { NeoRegTabContent } from "@/components/memshell/tabs/neoreg-tab";
import { Suo5TabContent } from "@/components/memshell/tabs/suo5-tab";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
Field,
FieldContent,
FieldDescription,
FieldLabel,
} from "@/components/ui/field";
import { Field, FieldContent, FieldDescription, FieldLabel } from "@/components/ui/field";
import { Label } from "@/components/ui/label";
import {
Select,
@@ -26,17 +24,9 @@ import {
} from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { Tabs } from "@/components/ui/tabs";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import {
type MainConfig,
type ServerConfig,
ShellToolType,
} from "@/types/memshell";
import type { MemShellFormSchema } from "@/types/schema";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { type MainConfig, type ServerConfig, ShellToolType } from "@/types/memshell";
import { Spinner } from "../ui/spinner";
import { JREVersionFormField } from "./jreversion-field";
import { ServerVersionFormField } from "./serverversion-field";
@@ -76,9 +66,7 @@ export default function MainConfigCard({
if (!serverToolMap) {
return [];
}
const tools = Object.keys(serverToolMap).map(
(tool) => tool as ShellToolType,
);
const tools = Object.keys(serverToolMap).map((tool) => tool as ShellToolType);
return Array.from(new Set([...tools, ShellToolType.Custom]));
}, [serverToolMap]);
@@ -134,9 +122,7 @@ export default function MainConfigCard({
const currentTargetJdk = form.getValues("targetJdkVersion") as string;
const currentJdkVersion = Number.parseInt(currentTargetJdk, 10);
const shouldRaiseJdkVersion =
(server === "SpringWebFlux" ||
server === "XXLJOB" ||
server === "Dubbo") &&
(server === "SpringWebFlux" || server === "XXLJOB" || server === "Dubbo") &&
currentJdkVersion <= 52;
const nextJdkVersion = shouldRaiseJdkVersion ? "52" : "50";
if (currentTargetJdk !== nextJdkVersion) {
@@ -247,39 +233,27 @@ export default function MainConfigCard({
</CardHeader>
<CardContent>
{!mainConfig ? (
<div className="flex items-center justify-center p-4 gap-4 h-100">
<div className="flex h-100 items-center justify-center gap-4 p-4">
<Spinner />
<span className="text-sm text-muted-foreground">
{t("loading")}
</span>
<span className="text-sm text-muted-foreground">{t("loading")}</span>
</div>
) : (
<div className="flex flex-col gap-2">
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
<div className="grid grid-cols-1 gap-2 md:grid-cols-2">
<Controller
control={form.control}
name="server"
render={({ field }) => (
<Field>
<FieldContent>
<FieldLabel htmlFor="server">
{t("common:server")}
</FieldLabel>
<Select
onValueChange={field.onChange}
value={field.value}
>
<FieldLabel htmlFor="server">{t("common:server")}</FieldLabel>
<Select onValueChange={field.onChange} value={field.value}>
<SelectTrigger id="server">
<SelectValue
data-placeholder={t("common:placeholders.select")}
/>
<SelectValue data-placeholder={t("common:placeholders.select")} />
</SelectTrigger>
<SelectContent>
{serverOptions.map((serverOption) => (
<SelectItem
key={serverOption}
value={serverOption}
>
<SelectItem key={serverOption} value={serverOption}>
{serverOption}
</SelectItem>
))}
@@ -303,26 +277,20 @@ export default function MainConfigCard({
/>
<ServerVersionFormField form={form} />
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
<div className="grid grid-cols-1 gap-2 md:grid-cols-2">
<Controller
control={form.control}
name="shellTool"
render={({ field }) => (
<Field>
<FieldContent>
<FieldLabel htmlFor="shellTool">
{t("common:shellTool")}
</FieldLabel>
<FieldLabel htmlFor="shellTool">{t("common:shellTool")}</FieldLabel>
<Select
value={field.value}
onValueChange={(v) =>
handleShellToolChange(v as string)
}
onValueChange={(v) => handleShellToolChange(v as string)}
>
<SelectTrigger id="shellTool">
<SelectValue
data-placeholder={t("common:placeholders.select")}
/>
<SelectValue data-placeholder={t("common:placeholders.select")} />
</SelectTrigger>
<SelectContent>
{shellTools.map((tool) => (
@@ -338,21 +306,17 @@ export default function MainConfigCard({
/>
<JREVersionFormField form={form} />
</div>
<div className="flex gap-4 mt-4 flex-col lg:grid lg:grid-cols-2 2xl:grid 2xl:grid-cols-3">
<div className="mt-4 flex flex-col gap-4 lg:grid lg:grid-cols-2 2xl:grid 2xl:grid-cols-3">
<Controller
control={form.control}
name="debug"
render={({ field }) => (
<div className="flex items-center gap-2">
<Switch
id="debug"
checked={field.value}
onCheckedChange={field.onChange}
/>
<Switch id="debug" checked={field.value} onCheckedChange={field.onChange} />
<Label htmlFor="debug">{t("common:debug")}</Label>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="h-3.5 w-3.5 text-muted-foreground cursor-help" />
<InfoIcon className="h-3.5 w-3.5 cursor-help text-muted-foreground" />
</TooltipTrigger>
<TooltipContent>
<p>{t("common:debug.description")}</p>
@@ -366,15 +330,11 @@ export default function MainConfigCard({
name="probe"
render={({ field }) => (
<div className="flex items-center gap-2">
<Switch
id="probe"
checked={field.value}
onCheckedChange={field.onChange}
/>
<Switch id="probe" checked={field.value} onCheckedChange={field.onChange} />
<Label htmlFor="probe">{t("common:probe")}</Label>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="h-3.5 w-3.5 text-muted-foreground cursor-help" />
<InfoIcon className="h-3.5 w-3.5 cursor-help text-muted-foreground" />
</TooltipTrigger>
<TooltipContent>
<p>{t("common:probe.description")}</p>
@@ -388,17 +348,11 @@ export default function MainConfigCard({
name="byPassJavaModule"
render={({ field }) => (
<div className="flex items-center gap-2">
<Switch
id="bypass"
checked={field.value}
onCheckedChange={field.onChange}
/>
<Label htmlFor="bypass">
{t("common:byPassJavaModule")}
</Label>
<Switch id="bypass" checked={field.value} onCheckedChange={field.onChange} />
<Label htmlFor="bypass">{t("common:byPassJavaModule")}</Label>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="h-3.5 w-3.5 text-muted-foreground cursor-help" />
<InfoIcon className="h-3.5 w-3.5 cursor-help text-muted-foreground" />
</TooltipTrigger>
<TooltipContent>
<p>{t("common:byPassJavaModule.description")}</p>
@@ -417,12 +371,10 @@ export default function MainConfigCard({
checked={field.value}
onCheckedChange={field.onChange}
/>
<Label htmlFor="lambdaSuffix">
{t("common:lambdaSuffix")}
</Label>
<Label htmlFor="lambdaSuffix">{t("common:lambdaSuffix")}</Label>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="h-3.5 w-3.5 text-muted-foreground cursor-help" />
<InfoIcon className="h-3.5 w-3.5 cursor-help text-muted-foreground" />
</TooltipTrigger>
<TooltipContent>
<p>{t("common:lambdaSuffix.description")}</p>
@@ -436,15 +388,11 @@ export default function MainConfigCard({
name="shrink"
render={({ field }) => (
<div className="flex items-center gap-2">
<Switch
id="shrink"
checked={field.value}
onCheckedChange={field.onChange}
/>
<Switch id="shrink" checked={field.value} onCheckedChange={field.onChange} />
<Label htmlFor="shrink">{t("common:shrink")}</Label>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="h-3.5 w-3.5 text-muted-foreground cursor-help" />
<InfoIcon className="h-3.5 w-3.5 cursor-help text-muted-foreground" />
</TooltipTrigger>
<TooltipContent>
<p>{t("common:shrink.description")}</p>
@@ -463,12 +411,10 @@ export default function MainConfigCard({
checked={field.value}
onCheckedChange={field.onChange}
/>
<Label htmlFor="staticInitialize">
{t("common:staticInitialize")}
</Label>
<Label htmlFor="staticInitialize">{t("common:staticInitialize")}</Label>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="h-3.5 w-3.5 text-muted-foreground cursor-help" />
<InfoIcon className="h-3.5 w-3.5 cursor-help text-muted-foreground" />
</TooltipTrigger>
<TooltipContent>
<p>{t("common:staticInitialize.description")}</p>
@@ -489,11 +435,7 @@ export default function MainConfigCard({
<BehinderTabContent form={form} shellTypes={shellTypes} />
<AntSwordTabContent form={form} shellTypes={shellTypes} />
<Suo5TabContent tabValue="Suo5" form={form} shellTypes={shellTypes} />
<Suo5TabContent
tabValue="Suo5v2"
form={form}
shellTypes={shellTypes}
/>
<Suo5TabContent tabValue="Suo5v2" form={form} shellTypes={shellTypes} />
<NeoRegTabContent form={form} shellTypes={shellTypes} />
<CustomTabContent form={form} shellTypes={shellTypes} />
<ProxyTabContent form={form} shellTypes={shellTypes} />
@@ -1,13 +1,15 @@
import type { PackerConfig } from "@/types/memshell";
import type { MemShellFormSchema } from "@/types/schema";
import { PackageIcon } from "lucide-react";
import { useMemo } from "react";
import { Controller, type UseFormReturn, useWatch } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { FieldLabel, FieldSet } from "@/components/ui/field";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Spinner } from "@/components/ui/spinner";
import type { PackerConfig } from "@/types/memshell";
import type { MemShellFormSchema } from "@/types/schema";
export default function PackageConfigCard({
packerConfig,
@@ -84,11 +86,9 @@ export default function PackageConfigCard({
)}
/>
) : (
<div className="flex items-center justify-center p-4 gap-4 h-50">
<div className="flex h-50 items-center justify-center gap-4 p-4">
<Spinner />
<span className="text-sm text-muted-foreground">
{t("loading")}
</span>
<span className="text-sm text-muted-foreground">{t("loading")}</span>
</div>
)}
</CardContent>
+2 -1
View File
@@ -1,5 +1,6 @@
import { ScrollTextIcon } from "lucide-react";
import { useTranslation } from "react-i18next";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
export function QuickUsage() {
@@ -13,7 +14,7 @@ export function QuickUsage() {
</CardTitle>
</CardHeader>
<CardContent>
<ol className="flex flex-col gap-4 list-decimal list-inside text-sm">
<ol className="flex list-inside list-decimal flex-col gap-4 text-sm">
<li>{t("memshell:quickUsage.step1")}</li>
<li>{t("memshell:quickUsage.step2")}</li>
<li>{t("memshell:quickUsage.step3")}</li>
+7 -10
View File
@@ -1,10 +1,12 @@
import type { MemShellResult } from "@/types/memshell";
import { ScrollTextIcon } from "lucide-react";
import { useTranslation } from "react-i18next";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";
import { downloadBytes, formatBytes } from "@/lib/utils";
import type { MemShellResult } from "@/types/memshell";
export function AgentResult({
packMethod,
@@ -26,11 +28,10 @@ export function AgentResult({
</CardTitle>
</CardHeader>
<CardContent>
<ol className="list-decimal list-inside space-y-4 text-sm">
<ol className="list-inside list-decimal space-y-4 text-sm">
<li className="flex items-center justify-between">
<span>
{t("common:download")} MemShellAgent.jar (
{formatBytes(atob(packResult).length)})
{t("common:download")} MemShellAgent.jar ({formatBytes(atob(packResult).length)})
</span>
<Button
size="sm"
@@ -56,9 +57,7 @@ export function AgentResult({
variant="outline"
className="w-28"
type="button"
onClick={() =>
window.open("https://github.com/jattach/jattach/releases")
}
onClick={() => window.open("https://github.com/jattach/jattach/releases")}
>
{t("common:download")}
</Button>
@@ -72,9 +71,7 @@ export function AgentResult({
</li>
<li>{t("memshell:tips.get-pid")}</li>
<li>
{isPureAgent
? t("memshell:tips.execute-command")
: t("memshell:tips.execute-command1")}
{isPureAgent ? t("memshell:tips.execute-command") : t("memshell:tips.execute-command1")}
</li>
<li>{t("memshell:tips.try-to-use-shell")}</li>
</ol>
@@ -1,6 +1,7 @@
import { FileTextIcon } from "lucide-react";
import { Fragment } from "react/jsx-runtime";
import { useTranslation } from "react-i18next";
import { Fragment } from "react/jsx-runtime";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";
import { notNeedUrlPattern } from "@/lib/utils";
@@ -15,12 +16,11 @@ import {
ShellToolType,
type Suo5ShellToolConfig,
} from "@/types/memshell";
import { CopyableField } from "../../copyable-field";
import { FeedbackAlert } from "./feedback-alert";
export function BasicInfo({
generateResult,
}: Readonly<{ generateResult?: MemShellResult }>) {
export function BasicInfo({ generateResult }: Readonly<{ generateResult?: MemShellResult }>) {
const { t } = useTranslation(["memshell", "common"]);
const isDubbo = generateResult?.shellConfig.server === "Dubbo";
return (
@@ -35,11 +35,8 @@ export function BasicInfo({
</CardTitle>
</CardHeader>
<CardContent>
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
<CopyableField
label={t("common:server")}
text={generateResult?.shellConfig.server}
/>
<div className="grid grid-cols-1 gap-2 md:grid-cols-2">
<CopyableField label={t("common:server")} text={generateResult?.shellConfig.server} />
<CopyableField
label={t("mainConfig.shellTool")}
text={generateResult?.shellConfig.shellTool}
@@ -55,29 +52,21 @@ export function BasicInfo({
value={generateResult?.injectorConfig.urlPattern}
/>
</div>
{generateResult?.shellConfig.shellTool !== ShellToolType.Custom &&
!isDubbo && <Separator className="my-1" />}
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
{generateResult?.shellConfig.shellTool !== ShellToolType.Custom && !isDubbo && (
<Separator className="my-1" />
)}
<div className="grid grid-cols-1 gap-2 md:grid-cols-2">
{generateResult?.shellConfig.shellTool === ShellToolType.Behinder && (
<>
<CopyableField
label={t("shellToolConfig.behinderScriptType")}
text="jsp"
/>
<CopyableField label={t("shellToolConfig.behinderScriptType")} text="jsp" />
<CopyableField
label={t("shellToolConfig.behinderEncryptType")}
text={t("shellToolConfig.behinderDefaultEncryptType")}
/>
<CopyableField
label={t("shellToolConfig.behinder.pass")}
text={
(generateResult?.shellToolConfig as BehinderShellToolConfig)
.pass
}
value={
(generateResult?.shellToolConfig as BehinderShellToolConfig)
.pass
}
text={(generateResult?.shellToolConfig as BehinderShellToolConfig).pass}
value={(generateResult?.shellToolConfig as BehinderShellToolConfig).pass}
/>
<CopyableField
label={t("shellToolConfig.behinder.header")}
@@ -90,25 +79,13 @@ export function BasicInfo({
<>
<CopyableField
label={t("shellToolConfig.godzilla.pass")}
text={
(generateResult?.shellToolConfig as GodzillaShellToolConfig)
.pass
}
value={
(generateResult?.shellToolConfig as GodzillaShellToolConfig)
.pass
}
text={(generateResult?.shellToolConfig as GodzillaShellToolConfig).pass}
value={(generateResult?.shellToolConfig as GodzillaShellToolConfig).pass}
/>
<CopyableField
label={t("shellToolConfig.godzilla.key")}
text={
(generateResult?.shellToolConfig as GodzillaShellToolConfig)
.key
}
value={
(generateResult?.shellToolConfig as GodzillaShellToolConfig)
.key
}
text={(generateResult?.shellToolConfig as GodzillaShellToolConfig).key}
value={(generateResult?.shellToolConfig as GodzillaShellToolConfig).key}
/>
<CopyableField
label={t("shellToolConfig.godzilla.encryptor")}
@@ -125,38 +102,27 @@ export function BasicInfo({
/>
</>
)}
{generateResult?.shellConfig.shellTool === ShellToolType.Command &&
!isDubbo && (
<Fragment>
<CopyableField
hidden={generateResult?.shellConfig.shellType.includes(
"WebSocket",
)}
label={t("common:paramName")}
text={
(generateResult?.shellToolConfig as CommandShellToolConfig)
.paramName
}
value={
(generateResult?.shellToolConfig as CommandShellToolConfig)
.paramName
}
/>
<CopyableField
hidden={
!(
generateResult?.shellConfig.shellType ===
"BypassNginxWebSocket" ||
generateResult?.shellConfig.shellType ===
"BypassNginxJakartaWebSocket"
)
}
label={t("shellToolConfig.httpHeader")}
text={`${(generateResult?.shellToolConfig as CommandShellToolConfig).headerName}: ${(generateResult?.shellToolConfig as CommandShellToolConfig).headerValue}`}
value={`${(generateResult?.shellToolConfig as CommandShellToolConfig).headerName}: ${(generateResult?.shellToolConfig as CommandShellToolConfig).headerValue}`}
/>
</Fragment>
)}
{generateResult?.shellConfig.shellTool === ShellToolType.Command && !isDubbo && (
<Fragment>
<CopyableField
hidden={generateResult?.shellConfig.shellType.includes("WebSocket")}
label={t("common:paramName")}
text={(generateResult?.shellToolConfig as CommandShellToolConfig).paramName}
value={(generateResult?.shellToolConfig as CommandShellToolConfig).paramName}
/>
<CopyableField
hidden={
!(
generateResult?.shellConfig.shellType === "BypassNginxWebSocket" ||
generateResult?.shellConfig.shellType === "BypassNginxJakartaWebSocket"
)
}
label={t("shellToolConfig.httpHeader")}
text={`${(generateResult?.shellToolConfig as CommandShellToolConfig).headerName}: ${(generateResult?.shellToolConfig as CommandShellToolConfig).headerValue}`}
value={`${(generateResult?.shellToolConfig as CommandShellToolConfig).headerName}: ${(generateResult?.shellToolConfig as CommandShellToolConfig).headerValue}`}
/>
</Fragment>
)}
{(generateResult?.shellConfig.shellTool === ShellToolType.Suo5 ||
generateResult?.shellConfig.shellTool === ShellToolType.Suo5v2) && (
<CopyableField
@@ -176,14 +142,8 @@ export function BasicInfo({
<>
<CopyableField
label={t("shellToolConfig.antSword.pass")}
text={
(generateResult?.shellToolConfig as AntSwordShellToolConfig)
.pass
}
value={
(generateResult?.shellToolConfig as AntSwordShellToolConfig)
.pass
}
text={(generateResult?.shellToolConfig as AntSwordShellToolConfig).pass}
value={(generateResult?.shellToolConfig as AntSwordShellToolConfig).pass}
/>
<CopyableField
label={t("shellToolConfig.httpHeader")}
@@ -192,14 +152,9 @@ export function BasicInfo({
/>
</>
)}
{generateResult?.shellConfig.shellTool ===
ShellToolType.NeoreGeorg && (
{generateResult?.shellConfig.shellTool === ShellToolType.NeoreGeorg && (
<>
<CopyableField
label={t("shellToolConfig.neoreGeorgKey")}
text="key"
value="key"
/>
<CopyableField label={t("shellToolConfig.neoreGeorgKey")} text="key" value="key" />
<CopyableField
label={t("shellToolConfig.neoreGeorgHeader")}
text={`${(generateResult?.shellToolConfig as NeoreGeorgShellToolConfig).headerName}: ${(generateResult?.shellToolConfig as NeoreGeorgShellToolConfig).headerValue}`}
@@ -209,7 +164,7 @@ export function BasicInfo({
)}
</div>
<Separator className="my-1" />
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
<div className="grid grid-cols-1 gap-2 md:grid-cols-2">
<CopyableField
label={t("mainConfig.injectorClassName")}
value={generateResult?.injectorClassName}
@@ -1,5 +1,6 @@
import { CircleHelpIcon } from "lucide-react";
import { useTranslation } from "react-i18next";
import {
AlertDialog,
AlertDialogAction,
@@ -1,10 +1,12 @@
import type { MemShellResult } from "@/types/memshell";
import { ScrollTextIcon } from "lucide-react";
import { useTranslation } from "react-i18next";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";
import { downloadBytes, formatBytes } from "@/lib/utils";
import type { MemShellResult } from "@/types/memshell";
export function JarResult({
packMethod,
@@ -25,11 +27,10 @@ export function JarResult({
</CardTitle>
</CardHeader>
<CardContent>
<ol className="list-decimal list-inside space-y-4 text-sm">
<ol className="list-inside list-decimal space-y-4 text-sm">
<li className="flex items-center justify-between">
<span>
{t("common:download")} {packMethod}Shell.jar (
{formatBytes(atob(packResult).length)})
{t("common:download")} {packMethod}Shell.jar ({formatBytes(atob(packResult).length)})
</span>
<Button
size="sm"
@@ -1,6 +1,7 @@
import { DownloadIcon } from "lucide-react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import CodeViewer from "@/components/code-viewer";
import { Button } from "@/components/ui/button";
import {
@@ -26,14 +27,9 @@ export function MultiPackResult({
const showCode = packMethod === "JSP";
const { t } = useTranslation();
const packResults = allPackResults as Record<string, string> | undefined;
const packMethods = useMemo(
() => Object.keys(packResults ?? {}),
[packResults],
);
const packMethods = useMemo(() => Object.keys(packResults ?? {}), [packResults]);
const [selectedMethod, setSelectedMethod] = useState(
() => packMethods[0] ?? "",
);
const [selectedMethod, setSelectedMethod] = useState(() => packMethods[0] ?? "");
const packResult = useMemo(() => {
if (!selectedMethod) {
@@ -55,16 +51,12 @@ export function MultiPackResult({
}, [packMethods, selectedMethod]);
const handleDownload = useCallback(() => {
const fileName =
shellClassName?.substring(shellClassName?.lastIndexOf(".") ?? 0) ?? "";
const fileName = shellClassName?.substring(shellClassName?.lastIndexOf(".") ?? 0) ?? "";
if (packMethod === "JSP") {
const fileExtension = selectedMethod.includes("JSPX") ? ".jspx" : ".jsp";
const content = new Blob([packResult], { type: "text/plain" });
return downloadContent(content, fileName, fileExtension);
} else if (
packMethod === "JavaDeserialize" ||
packMethod.includes("Hessian")
) {
} else if (packMethod === "JavaDeserialize" || packMethod.includes("Hessian")) {
const content = new Blob([base64ToBytes(packResult)], {
type: "application/octet-stream",
});
@@ -73,20 +65,13 @@ export function MultiPackResult({
const base64Content = packResults?.[packMethods[0]] ?? "";
return downloadBytes(base64Content, shellClassName);
}
}, [
packMethod,
packMethods,
packResult,
packResults,
selectedMethod,
shellClassName,
]);
}, [packMethod, packMethods, packResult, packResults, selectedMethod, shellClassName]);
return (
<CodeViewer
code={packResult ?? ""}
header={
<div className="flex items-center justify-between text-xs gap-2">
<div className="flex items-center justify-between gap-2 text-xs">
<Select
onValueChange={(value) => {
setSelectedMethod(value as string);
@@ -94,9 +79,7 @@ export function MultiPackResult({
value={selectedMethod}
>
<SelectTrigger className="h-7 text-xs [&_svg]:h-4 [&_svg]:w-4">
<span className="text-muted-foreground">
{t("common:packerMethod")}:&nbsp;
</span>
<span className="text-muted-foreground">{t("common:packerMethod")}:&nbsp;</span>
<SelectValue data-placeholder={t("common:placeholders.select")} />
</SelectTrigger>
<SelectContent>
@@ -1,13 +1,16 @@
import { useTranslation } from "react-i18next";
import CodeViewer from "@/components/code-viewer";
import type { MemShellResult } from "@/types/memshell";
import { DownloadIcon } from "lucide-react";
import { useCallback } from "react";
import { useTranslation } from "react-i18next";
import CodeViewer from "@/components/code-viewer";
import { Button } from "@/components/ui/button";
import { base64ToBytes, downloadBytes, downloadContent } from "@/lib/utils";
import { AgentResult } from "./agent";
import { JarResult } from "./jar-result";
import { MultiPackResult } from "./multi-packer";
import { useCallback } from "react";
import { base64ToBytes, downloadBytes, downloadContent } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { DownloadIcon } from "lucide-react";
export function ResultComponent({
packResult,
@@ -55,16 +58,12 @@ export function ResultComponent({
const shellClassName = generateResult?.shellClassName;
const handleDownload = useCallback(() => {
const fileName =
shellClassName?.substring(shellClassName?.lastIndexOf(".") ?? 0) ?? "";
const fileName = shellClassName?.substring(shellClassName?.lastIndexOf(".") ?? 0) ?? "";
if (packMethod.includes("JSP")) {
const fileExtension = packMethod.includes("JSPX") ? ".jspx" : ".jsp";
const content = new Blob([packResult as string], { type: "text/plain" });
return downloadContent(content, fileName, fileExtension);
} else if (
packMethod.includes("JavaCommons") ||
packMethod.includes("Hessian")
) {
} else if (packMethod.includes("JavaCommons") || packMethod.includes("Hessian")) {
const content = new Blob([base64ToBytes(packResult as string)], {
type: "application/octet-stream",
});
@@ -78,7 +77,7 @@ export function ResultComponent({
<CodeViewer
code={packResult ?? ""}
header={
<div className="flex items-center justify-between text-xs gap-2">
<div className="flex items-center justify-between gap-2 text-xs">
<span>
{t("common:packerMethod")}{packMethod}
</span>
@@ -1,11 +1,9 @@
import type { MemShellFormSchema } from "@/types/schema";
import { Controller, type UseFormReturn, useWatch } from "react-hook-form";
import { useTranslation } from "react-i18next";
import {
Field,
FieldContent,
FieldError,
FieldLabel,
} from "@/components/ui/field";
import { Field, FieldContent, FieldError, FieldLabel } from "@/components/ui/field";
import {
Select,
SelectContent,
@@ -13,7 +11,6 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import type { MemShellFormSchema } from "@/types/schema";
export function ServerVersionFormField({
form,
@@ -30,17 +27,10 @@ export function ServerVersionFormField({
render={({ field, fieldState }) => (
<Field orientation="vertical" data-invalid={fieldState.invalid}>
<FieldContent>
<FieldLabel htmlFor="serverVersion">
{t("common:serverVersion")}
</FieldLabel>
<FieldLabel htmlFor="serverVersion">{t("common:serverVersion")}</FieldLabel>
<Select onValueChange={field.onChange} value={field.value}>
<SelectTrigger
id="serverVersion"
aria-invalid={fieldState.invalid}
>
<SelectValue
data-placeholder={t("common:placeholders.select")}
/>
<SelectTrigger id="serverVersion" aria-invalid={fieldState.invalid}>
<SelectValue data-placeholder={t("common:placeholders.select")} />
</SelectTrigger>
<SelectContent>
{serverVersionOptions.map((v) => (
+8 -19
View File
@@ -1,3 +1,5 @@
import type { MemShellResult } from "@/types/memshell";
import { DownloadIcon } from "lucide-react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
@@ -6,7 +8,7 @@ import { QuickUsage } from "@/components/memshell/quick-usage";
import { Button } from "@/components/ui/button";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { downloadBytes } from "@/lib/utils";
import type { MemShellResult } from "@/types/memshell";
import CodeViewer from "../code-viewer";
import { BasicInfo } from "./results/basic-info";
import { ResultComponent } from "./results/result-component";
@@ -30,13 +32,9 @@ export default function ShellResult({
return (
<Tabs defaultValue="packResult">
<TabsList className="grid w-full grid-cols-3">
<TabsTrigger value="packResult">
{t("common:generateResult")}
</TabsTrigger>
<TabsTrigger value="packResult">{t("common:generateResult")}</TabsTrigger>
<TabsTrigger value="shell">{t("memshell:shellClass")}</TabsTrigger>
<TabsTrigger value="injector">
{t("memshell:injectorClass")}
</TabsTrigger>
<TabsTrigger value="injector">{t("memshell:injectorClass")}</TabsTrigger>
</TabsList>
<TabsContent value="packResult" className="space-y-2">
<BasicInfo generateResult={generateResult} />
@@ -50,11 +48,7 @@ export default function ShellResult({
<TabsContent value="shell" className="mt-4">
<CodeViewer
showLineNumbers={false}
header={
<div className="text-xs truncate">
{generateResult?.shellClassName}
</div>
}
header={<div className="truncate text-xs">{generateResult?.shellClassName}</div>}
button={
<Button
variant="ghost"
@@ -66,10 +60,7 @@ export default function ShellResult({
toast.warning(t("memshell:tips.shellBytesEmpty"));
return;
}
downloadBytes(
generateResult?.shellBytesBase64Str,
generateResult?.shellClassName,
);
downloadBytes(generateResult?.shellBytesBase64Str, generateResult?.shellClassName);
}}
>
<DownloadIcon className="h-4 w-4" />
@@ -85,9 +76,7 @@ export default function ShellResult({
<CodeViewer
showLineNumbers={false}
wrapLongLines={true}
header={
<div className="text-xs">{generateResult?.injectorClassName}</div>
}
header={<div className="text-xs">{generateResult?.injectorClassName}</div>}
button={
<Button
variant="ghost"
@@ -1,10 +1,13 @@
import type { MemShellFormSchema } from "@/types/schema";
import { Controller, type UseFormReturn } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Card, CardContent } from "@/components/ui/card";
import { Field, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { TabsContent } from "@/components/ui/tabs";
import type { MemShellFormSchema } from "@/types/schema";
import { OptionalClassFormField } from "./classname-field";
import { ShellTypeFormField } from "./shelltype-field";
@@ -19,7 +22,7 @@ export function AntSwordTabContent({
return (
<TabsContent value="AntSword">
<Card>
<CardContent className="space-y-2 mt-4">
<CardContent className="mt-4 space-y-2">
<ShellTypeFormField form={form} shellTypes={shellTypes} />
<Controller
control={form.control}
@@ -29,24 +32,18 @@ export function AntSwordTabContent({
<FieldLabel>
{t("shellToolConfig.antSword.pass")} {t("common:optional")}
</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
<div className="grid grid-cols-1 gap-2 md:grid-cols-2">
<Controller
control={form.control}
name="headerName"
render={({ field }) => (
<Field className="gap-1">
<FieldLabel>{t("common:headerName")}</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
@@ -58,10 +55,7 @@ export function AntSwordTabContent({
<FieldLabel>
{t("common:headerValue")} {t("common:optional")}
</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
@@ -1,10 +1,13 @@
import type { MemShellFormSchema } from "@/types/schema";
import { Controller, type UseFormReturn } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Card, CardContent } from "@/components/ui/card";
import { Field, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { TabsContent } from "@/components/ui/tabs";
import type { MemShellFormSchema } from "@/types/schema";
import { OptionalClassFormField } from "./classname-field";
import { ShellTypeFormField } from "./shelltype-field";
@@ -19,7 +22,7 @@ export function BehinderTabContent({
return (
<TabsContent value="Behinder">
<Card>
<CardContent className="space-y-2 mt-4">
<CardContent className="mt-4 space-y-2">
<ShellTypeFormField form={form} shellTypes={shellTypes} />
<Controller
control={form.control}
@@ -29,24 +32,18 @@ export function BehinderTabContent({
<FieldLabel>
{t("shellToolConfig.behinder.pass")} {t("common:optional")}
</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
<div className="grid grid-cols-1 gap-2 md:grid-cols-2">
<Controller
control={form.control}
name="headerName"
render={({ field }) => (
<Field className="gap-1">
<FieldLabel>{t("common:headerName")}</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
@@ -58,10 +55,7 @@ export function BehinderTabContent({
<FieldLabel>
{t("common:headerValue")} {t("common:optional")}
</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
@@ -1,11 +1,13 @@
import type { MemShellFormSchema } from "@/types/schema";
import { Shuffle } from "lucide-react";
import { Fragment, useEffect, useState } from "react";
import { Controller, type UseFormReturn } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Field, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import type { MemShellFormSchema } from "@/types/schema";
export function OptionalClassFormField({
form,
@@ -16,12 +18,8 @@ export function OptionalClassFormField({
const [useRandomClassName, setUseRandomClassName] = useState(
() => !(initialShellClassName?.trim() || initialInjectorClassName?.trim()),
);
const [savedShellClassName, setSavedShellClassName] = useState(
initialShellClassName,
);
const [savedInjectorClassName, setSavedInjectorClassName] = useState(
initialInjectorClassName,
);
const [savedShellClassName, setSavedShellClassName] = useState(initialShellClassName);
const [savedInjectorClassName, setSavedInjectorClassName] = useState(initialInjectorClassName);
const shellClassName = form.watch("shellClassName");
const injectorClassName = form.watch("injectorClassName");
@@ -38,10 +36,7 @@ export function OptionalClassFormField({
}, [injectorClassName, useRandomClassName]);
useEffect(() => {
if (
useRandomClassName &&
(shellClassName?.trim() || injectorClassName?.trim())
) {
if (useRandomClassName && (shellClassName?.trim() || injectorClassName?.trim())) {
setUseRandomClassName(false);
}
}, [injectorClassName, shellClassName, useRandomClassName]);
@@ -61,7 +56,7 @@ export function OptionalClassFormField({
return (
<Fragment>
<div className="pt-2 flex items-center justify-between gap-3">
<div className="flex items-center justify-between gap-3 pt-2">
<div className="flex items-center gap-2 text-sm font-medium">
<Shuffle className="h-4 w-4" />
<span>{t("mainConfig.randomClassName")}</span>
@@ -82,11 +77,7 @@ export function OptionalClassFormField({
<FieldLabel htmlFor="shellClassName">
{t("mainConfig.shellClassName")} {t("common:optional")}
</FieldLabel>
<Input
id="shellClassName"
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input id="shellClassName" {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
@@ -100,11 +91,7 @@ export function OptionalClassFormField({
<FieldLabel htmlFor="injectClassName">
{t("mainConfig.injectorClassName")} {t("common:optional")}
</FieldLabel>
<Input
id="injectClassName"
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input id="injectClassName" {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
@@ -1,14 +1,13 @@
import type { MemShellFormSchema } from "@/types/schema";
import { useQuery } from "@tanstack/react-query";
import { ChevronDown, ChevronRight, InfoIcon } from "lucide-react";
import { useState } from "react";
import { Controller, type UseFormReturn, useWatch } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Card, CardContent } from "@/components/ui/card";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible";
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
import { Field, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import {
@@ -19,13 +18,9 @@ import {
SelectValue,
} from "@/components/ui/select";
import { TabsContent } from "@/components/ui/tabs";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { env } from "@/config";
import type { MemShellFormSchema } from "@/types/schema";
import { OptionalClassFormField } from "./classname-field";
import { ShellTypeFormField } from "./shelltype-field";
@@ -60,43 +55,36 @@ export function CommandTabContent({
return (
<TabsContent value="Command">
<Card>
<CardContent className="space-y-2 mt-4">
<CardContent className="mt-4 space-y-2">
<ShellTypeFormField form={form} shellTypes={shellTypes} />
{server !== "Dubbo" && (
<Controller
control={form.control}
name="commandParamName"
render={({ field }) => (
<Field
className="gap-1"
hidden={shellType.includes("WebSocket")}
>
<Field className="gap-1" hidden={shellType.includes("WebSocket")}>
<div className="flex items-center gap-1">
<FieldLabel>
{t("common:paramName")} {t("common:optional")}
</FieldLabel>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="h-3.5 w-3.5 text-muted-foreground cursor-help" />
<InfoIcon className="h-3.5 w-3.5 cursor-help text-muted-foreground" />
</TooltipTrigger>
<TooltipContent>
<p>{t("common:paramName.description")}</p>
</TooltipContent>
</Tooltip>
</div>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
)}
<div
className="grid grid-cols-1 md:grid-cols-2 gap-2"
className="grid grid-cols-1 gap-2 md:grid-cols-2"
hidden={
shellType !== "BypassNginxWebSocket" &&
shellType !== "BypassNginxJakartaWebSocket"
shellType !== "BypassNginxWebSocket" && shellType !== "BypassNginxJakartaWebSocket"
}
>
<Controller
@@ -105,10 +93,7 @@ export function CommandTabContent({
render={({ field }) => (
<Field className="gap-1">
<FieldLabel>{t("common:headerName")}</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
@@ -120,16 +105,13 @@ export function CommandTabContent({
<FieldLabel>
{t("common:headerValue")} {t("common:optional")}
</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
</div>
<Collapsible open={isAdvancedOpen} onOpenChange={setIsAdvancedOpen}>
<CollapsibleTrigger className="flex items-center gap-2 w-full py-2 text-sm font-medium hover:underline">
<CollapsibleTrigger className="flex w-full items-center gap-2 py-2 text-sm font-medium hover:underline">
{isAdvancedOpen ? (
<ChevronDown className="h-4 w-4" />
) : (
@@ -138,22 +120,16 @@ export function CommandTabContent({
{t("common:advancedConfig")}
</CollapsibleTrigger>
<CollapsibleContent className="space-y-2 pt-2">
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
<div className="grid grid-cols-1 gap-2 md:grid-cols-2">
<Controller
control={form.control}
name="encryptor"
render={({ field }) => (
<Field className="gap-1">
<FieldLabel>{t("common:encryptor")}</FieldLabel>
<Select
onValueChange={field.onChange}
value={field.value}
defaultValue="RAW"
>
<Select onValueChange={field.onChange} value={field.value} defaultValue="RAW">
<SelectTrigger>
<SelectValue
data-placeholder={t("common:placeholders.select")}
/>
<SelectValue data-placeholder={t("common:placeholders.select")} />
</SelectTrigger>
<SelectContent>
{data?.encryptors?.map((v) => (
@@ -178,9 +154,7 @@ export function CommandTabContent({
defaultValue="RuntimeExec"
>
<SelectTrigger>
<SelectValue
data-placeholder={t("common:placeholders.select")}
/>
<SelectValue data-placeholder={t("common:placeholders.select")} />
</SelectTrigger>
<SelectContent>
{data?.implementationClasses?.map((v) => (
@@ -202,11 +176,8 @@ export function CommandTabContent({
<FieldLabel>
{t("common:commandTemplate")} {t("common:optional")}
</FieldLabel>
<Input
{...field}
placeholder={t("common:commandTemplate.placeholder")}
/>
<p className="text-xs text-muted-foreground mt-1">
<Input {...field} placeholder={t("common:commandTemplate.placeholder")} />
<p className="mt-1 text-xs text-muted-foreground">
{t("common:commandTemplate.description")}
</p>
</Field>
@@ -1,7 +1,10 @@
import type { MemShellFormSchema } from "@/types/schema";
import { useEffect, useRef, useState } from "react";
import { Controller, type UseFormReturn } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { Card, CardContent } from "@/components/ui/card";
import { Field, FieldError, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
@@ -10,7 +13,7 @@ import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { TabsContent } from "@/components/ui/tabs";
import { Textarea } from "@/components/ui/textarea";
import { env } from "@/config";
import type { MemShellFormSchema } from "@/types/schema";
import { OptionalClassFormField } from "./classname-field";
import { ShellTypeFormField } from "./shelltype-field";
@@ -85,7 +88,7 @@ export default function CustomTabContent({
return (
<TabsContent value="Custom">
<Card>
<CardContent className="space-y-2 mt-4">
<CardContent className="mt-4 space-y-2">
<ShellTypeFormField form={form} shellTypes={shellTypes} />
<Controller
control={form.control}
@@ -120,9 +123,7 @@ export default function CustomTabContent({
const reader = new FileReader();
reader.onload = (event) => {
const base64String =
(event.target?.result as string)?.split(
",",
)[1] || "";
(event.target?.result as string)?.split(",")[1] || "";
field.onChange(base64String);
};
reader.readAsDataURL(file);
@@ -1,10 +1,13 @@
import type { MemShellFormSchema } from "@/types/schema";
import { Controller, type UseFormReturn } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Card, CardContent } from "@/components/ui/card";
import { Field, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { TabsContent } from "@/components/ui/tabs";
import type { MemShellFormSchema } from "@/types/schema";
import { OptionalClassFormField } from "./classname-field";
import { ShellTypeFormField } from "./shelltype-field";
@@ -19,9 +22,9 @@ export function GodzillaTabContent({
return (
<TabsContent value="Godzilla">
<Card>
<CardContent className="flex flex-col gap-2 mt-4">
<CardContent className="mt-4 flex flex-col gap-2">
<ShellTypeFormField form={form} shellTypes={shellTypes} />
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
<div className="grid grid-cols-1 gap-2 md:grid-cols-2">
<Controller
control={form.control}
name="godzillaPass"
@@ -30,10 +33,7 @@ export function GodzillaTabContent({
<FieldLabel>
{t("shellToolConfig.godzilla.pass")} {t("common:optional")}
</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
@@ -45,10 +45,7 @@ export function GodzillaTabContent({
<FieldLabel>
{t("shellToolConfig.godzilla.key")} {t("common:optional")}
</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
@@ -58,10 +55,7 @@ export function GodzillaTabContent({
render={({ field }) => (
<Field className="gap-1">
<FieldLabel>{t("common:headerName")}</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
@@ -73,10 +67,7 @@ export function GodzillaTabContent({
<FieldLabel>
{t("common:headerValue")} {t("common:optional")}
</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
@@ -1,10 +1,13 @@
import type { MemShellFormSchema } from "@/types/schema";
import { Controller, type UseFormReturn } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Card, CardContent } from "@/components/ui/card";
import { Field, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { TabsContent } from "@/components/ui/tabs";
import type { MemShellFormSchema } from "@/types/schema";
import { OptionalClassFormField } from "./classname-field";
import { ShellTypeFormField } from "./shelltype-field";
@@ -19,19 +22,16 @@ export function NeoRegTabContent({
return (
<TabsContent value="NeoreGeorg">
<Card>
<CardContent className="space-y-2 mt-4">
<CardContent className="mt-4 space-y-2">
<ShellTypeFormField form={form} shellTypes={shellTypes} />
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
<div className="grid grid-cols-1 gap-2 md:grid-cols-2">
<Controller
control={form.control}
name="headerName"
render={({ field }) => (
<Field className="gap-1">
<FieldLabel>{t("common:headerName")}</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
@@ -43,10 +43,7 @@ export function NeoRegTabContent({
<FieldLabel>
{t("common:headerValue")} {t("common:optional")}
</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
+9 -13
View File
@@ -1,10 +1,13 @@
import type { MemShellFormSchema } from "@/types/schema";
import { Controller, type UseFormReturn, useWatch } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Card, CardContent } from "@/components/ui/card";
import { Field, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { TabsContent } from "@/components/ui/tabs";
import type { MemShellFormSchema } from "@/types/schema";
import { OptionalClassFormField } from "./classname-field";
import { ShellTypeFormField } from "./shelltype-field";
@@ -23,13 +26,12 @@ export function ProxyTabContent({
return (
<TabsContent value="Proxy">
<Card>
<CardContent className="space-y-2 mt-4">
<CardContent className="mt-4 space-y-2">
<ShellTypeFormField form={form} shellTypes={shellTypes} />
<div
className="grid grid-cols-1 md:grid-cols-2 gap-2"
className="grid grid-cols-1 gap-2 md:grid-cols-2"
hidden={
shellType !== "BypassNginxWebSocket" &&
shellType !== "BypassNginxJakartaWebSocket"
shellType !== "BypassNginxWebSocket" && shellType !== "BypassNginxJakartaWebSocket"
}
>
<Controller
@@ -38,10 +40,7 @@ export function ProxyTabContent({
render={({ field }) => (
<Field className="gap-1">
<FieldLabel>{t("common:headerName")}</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
@@ -53,10 +52,7 @@ export function ProxyTabContent({
<FieldLabel>
{t("common:headerValue")} {t("common:optional")}
</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
@@ -1,5 +1,8 @@
import type { MemShellFormSchema } from "@/types/schema";
import { Controller, type UseFormReturn, useWatch } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Field, FieldError, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import {
@@ -10,7 +13,6 @@ import {
SelectValue,
} from "@/components/ui/select";
import { cn, notNeedUrlPattern } from "@/lib/utils";
import type { MemShellFormSchema } from "@/types/schema";
export function ShellTypeFormField({
form,
@@ -23,7 +25,7 @@ export function ShellTypeFormField({
const shellType = useWatch({ control: form.control, name: "shellType" });
const needUrlPattern = !notNeedUrlPattern(shellType);
return (
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
<div className="grid grid-cols-1 gap-2 md:grid-cols-2">
<Controller
control={form.control}
name="shellType"
@@ -38,9 +40,7 @@ export function ShellTypeFormField({
value={field.value}
>
<SelectTrigger>
<SelectValue
data-placeholder={t("common:placeholders.select")}
/>
<SelectValue data-placeholder={t("common:placeholders.select")} />
</SelectTrigger>
<SelectContent key={shellTypes?.join(",")}>
{shellTypes?.length ? (
@@ -50,9 +50,7 @@ export function ShellTypeFormField({
</SelectItem>
))
) : (
<SelectItem value=" ">
{t("tips.shellToolNotSelected")}
</SelectItem>
<SelectItem value=" ">{t("tips.shellToolNotSelected")}</SelectItem>
)}
</SelectContent>
</Select>
+8 -11
View File
@@ -1,10 +1,13 @@
import type { MemShellFormSchema } from "@/types/schema";
import { Controller, type UseFormReturn } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Card, CardContent } from "@/components/ui/card";
import { Field, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { TabsContent } from "@/components/ui/tabs";
import type { MemShellFormSchema } from "@/types/schema";
import { OptionalClassFormField } from "./classname-field";
import { ShellTypeFormField } from "./shelltype-field";
@@ -21,19 +24,16 @@ export function Suo5TabContent({
return (
<TabsContent value={tabValue}>
<Card>
<CardContent className="space-y-2 mt-4">
<CardContent className="mt-4 space-y-2">
<ShellTypeFormField form={form} shellTypes={shellTypes} />
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
<div className="grid grid-cols-1 gap-2 md:grid-cols-2">
<Controller
control={form.control}
name="headerName"
render={({ field }) => (
<Field className="gap-1">
<FieldLabel>{t("common:headerName")}</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>
@@ -45,10 +45,7 @@ export function Suo5TabContent({
<FieldLabel>
{t("common:headerValue")} {t("common:optional")}
</FieldLabel>
<Input
{...field}
placeholder={t("common:placeholders.input")}
/>
<Input {...field} placeholder={t("common:placeholders.input")} />
</Field>
)}
/>