fix
This commit is contained in:
114
src/screens/FrpConfigForm.jsx
Normal file
114
src/screens/FrpConfigForm.jsx
Normal file
@@ -0,0 +1,114 @@
|
||||
import React, { useState } from "react";
|
||||
import { Box, Text, useInput } from "ink";
|
||||
import TextInput from "ink-text-input";
|
||||
|
||||
import {
|
||||
bootstrapPlan,
|
||||
frpInstallPlan,
|
||||
frpInitConfigPlan,
|
||||
DEFAULTS,
|
||||
} from "../lib/tasks.js";
|
||||
import { defaultInstallDir } from "../lib/frp-config.js";
|
||||
|
||||
const FIELDS = [
|
||||
{ key: "serverAddr", label: "Server address" },
|
||||
{ key: "serverPort", label: "Server port" },
|
||||
{ key: "installDir", label: "Install dir" },
|
||||
];
|
||||
|
||||
export default function FrpConfigForm({ nav, token, purpose }) {
|
||||
const [values, setValues] = useState({
|
||||
serverAddr: DEFAULTS.serverAddr,
|
||||
serverPort: String(DEFAULTS.serverPort),
|
||||
installDir: defaultInstallDir(),
|
||||
});
|
||||
const [step, setStep] = useState(0);
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
useInput((input, key) => {
|
||||
if (key.tab || key.downArrow) {
|
||||
setStep((s) => Math.min(s + 1, FIELDS.length - 1));
|
||||
return;
|
||||
}
|
||||
if (key.upArrow) {
|
||||
setStep((s) => Math.max(s - 1, 0));
|
||||
return;
|
||||
}
|
||||
if (key.return) {
|
||||
if (step < FIELDS.length - 1) {
|
||||
setStep((s) => s + 1);
|
||||
return;
|
||||
}
|
||||
submit();
|
||||
}
|
||||
});
|
||||
|
||||
const update = (key) => (value) => {
|
||||
setValues((v) => ({ ...v, [key]: value }));
|
||||
};
|
||||
|
||||
const submit = () => {
|
||||
const port = Number(values.serverPort);
|
||||
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
||||
setError("Server port must be an integer between 1 and 65535.");
|
||||
return;
|
||||
}
|
||||
|
||||
const options = {
|
||||
token,
|
||||
serverAddr: values.serverAddr.trim() || DEFAULTS.serverAddr,
|
||||
serverPort: port,
|
||||
installDir: values.installDir.trim() || defaultInstallDir(),
|
||||
};
|
||||
|
||||
try {
|
||||
let plan;
|
||||
if (purpose === "bootstrap") {
|
||||
plan = bootstrapPlan(options);
|
||||
} else if (purpose === "frp-install") {
|
||||
plan = frpInstallPlan(options);
|
||||
} else if (purpose === "frp-init") {
|
||||
plan = frpInitConfigPlan({ ...options, force: true });
|
||||
} else {
|
||||
setError(`Unknown purpose: ${purpose}`);
|
||||
return;
|
||||
}
|
||||
nav.replace({ name: "plan", props: { plan, origin: purpose === "bootstrap" ? "main" : "frp" } });
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box flexDirection="column">
|
||||
<Text>FRP configuration ({purpose}):</Text>
|
||||
<Box flexDirection="column" marginTop={1}>
|
||||
{FIELDS.map((field, index) => (
|
||||
<Box key={field.key}>
|
||||
<Box width={18}>
|
||||
<Text color={index === step ? "cyan" : undefined}>
|
||||
{index === step ? "› " : " "}
|
||||
{field.label}
|
||||
</Text>
|
||||
</Box>
|
||||
<TextInput
|
||||
value={values[field.key]}
|
||||
onChange={update(field.key)}
|
||||
focus={index === step}
|
||||
/>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
{error ? (
|
||||
<Box marginTop={1}>
|
||||
<Text color="red">{error}</Text>
|
||||
</Box>
|
||||
) : null}
|
||||
<Box marginTop={1}>
|
||||
<Text dimColor>
|
||||
Tab/↓ next · ↑ prev · Enter on last field submits · Esc back
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user