portio
Version:
A beautiful terminal UI for managing processes on network ports (Windows only)
107 lines (106 loc) • 3.66 kB
JavaScript
import React, { useEffect, useState } from 'react';
import { Box, Text, useApp, useInput } from 'ink';
import { getProcessOnPort, killProcess } from '../utils/portDetector.js';
export const KillMode = ({ port, force = false }) => {
const { exit } = useApp();
const [loading, setLoading] = useState(true);
const [process, setProcess] = useState(null);
const [error, setError] = useState(null);
const [waitingForConfirm, setWaitingForConfirm] = useState(false);
const [killing, setKilling] = useState(false);
const [result, setResult] = useState(null);
useEffect(() => {
const checkPort = async () => {
try {
const proc = await getProcessOnPort(port);
setProcess(proc);
setLoading(false);
if (proc && force) {
await performKill(proc.pid);
}
else if (proc) {
setWaitingForConfirm(true);
}
else {
setTimeout(() => exit(), 100);
}
}
catch (err) {
setError(err instanceof Error ? err.message : 'Unknown error');
setLoading(false);
setTimeout(() => exit(), 100);
}
};
checkPort();
}, [port, force]);
const performKill = async (pid) => {
setKilling(true);
setWaitingForConfirm(false);
try {
const success = await killProcess(pid);
if (success) {
setResult(`✓ Successfully killed process ${pid} on port ${port}`);
}
else {
setResult(`✗ Failed to kill process ${pid}. Try running with elevated privileges.`);
}
}
catch (err) {
setResult(`✗ Error killing process: ${err instanceof Error ? err.message : 'Unknown error'}`);
}
finally {
setKilling(false);
setTimeout(() => exit(), 1000);
}
};
useInput((input, key) => {
if (!waitingForConfirm)
return;
if (input === 'y' || input === 'Y') {
if (process) {
performKill(process.pid);
}
}
else if (input === 'n' || input === 'N' || key.escape) {
setResult('Kill cancelled');
setTimeout(() => exit(), 100);
}
}, { isActive: !force });
if (loading) {
return (React.createElement(Text, { color: "yellow" },
"Checking port ",
port,
"..."));
}
if (error) {
return (React.createElement(Text, { color: "red" },
"Error: ",
error));
}
if (!process) {
return (React.createElement(Text, { color: "green" },
"\u2713 Port ",
port,
" is already free"));
}
if (killing) {
return (React.createElement(Text, { color: "yellow" },
"Killing process ",
process.pid,
"..."));
}
if (result) {
return (React.createElement(Text, { color: result.startsWith('✓') ? 'green' : result === 'Kill cancelled' ? 'yellow' : 'red' }, result));
}
if (waitingForConfirm) {
return (React.createElement(Box, { flexDirection: "column" },
React.createElement(Text, null,
process.processName || 'Unknown',
" (PID: ",
process.pid,
") on port ",
port),
React.createElement(Text, { color: "red" }, "Kill this process? (y/n): ")));
}
return null;
};