import React, { useState } from "react"; import { Box, Text, useInput } from "ink"; import TextInput from "ink-text-input"; import { frpAddProxyPlan } from "../lib/tasks.js"; const FIELDS = [ { key: "name", label: "Name (e.g. ssh)" }, { key: "type", label: "Type" }, { key: "localIp", label: "Local IP" }, { key: "localPort", label: "Local port" }, { key: "remotePort", label: "Remote port" }, ]; export default function ProxyForm({ nav }) { const [values, setValues] = useState({ name: "", type: "tcp", localIp: "127.0.0.1", localPort: "", remotePort: "", }); const [restart, setRestart] = useState(true); const [step, setStep] = useState(0); const [error, setError] = useState(null); const totalRows = FIELDS.length + 1; useInput((input, key) => { if (key.tab || key.downArrow) { setStep((s) => Math.min(s + 1, totalRows - 1)); return; } if (key.upArrow) { setStep((s) => Math.max(s - 1, 0)); return; } if (step === totalRows - 1) { if (input === " ") { setRestart((r) => !r); return; } if (key.return) { submit(); return; } } if (key.return) { if (step < totalRows - 1) { setStep((s) => s + 1); return; } submit(); } }); const update = (key) => (value) => { setValues((v) => ({ ...v, [key]: value })); }; const submit = () => { setError(null); const localPort = Number(values.localPort); const remotePort = Number(values.remotePort); if (!Number.isInteger(localPort) || localPort < 1 || localPort > 65535) { setError("Local port must be an integer in [1, 65535]."); return; } if (!Number.isInteger(remotePort) || remotePort < 1 || remotePort > 65535) { setError("Remote port must be an integer in [1, 65535]."); return; } try { const plan = frpAddProxyPlan({ name: values.name.trim(), type: values.type.trim() || "tcp", localIp: values.localIp.trim() || "127.0.0.1", localPort, remotePort, restart, }); nav.replace({ name: "plan", props: { plan, origin: "frp" } }); } catch (err) { setError(err.message); } }; return ( Add frp proxy: {FIELDS.map((field, index) => ( {index === step ? "› " : " "} {field.label} ))} {step === FIELDS.length ? "› " : " "} Restart frpc [{restart ? "x" : " "}] (Space to toggle) {error ? ( {error} ) : null} Tab/↓ next · ↑ prev · Space toggles restart · Enter on last submits ); }