Move input from text box to terminal
- Removed separate input box and send button from UI
- Added terminal input handling via onData() event listener
- Users can now type directly in the terminal
- Support for:
- Regular input (echoed in terminal)
- Backspace (with visual feedback)
- Enter key to send command
- Ctrl+C to clear current input
- Removed old keyboard event handlers for input box
- Terminal now has focus by default for seamless input experience
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
73f1d4ba9d
commit
5249b36b7f
122
web/process.html
122
web/process.html
|
|
@ -87,41 +87,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-area {
|
.input-area {
|
||||||
background: #16213e;
|
display: none;
|
||||||
padding: 10px 20px;
|
|
||||||
border-top: 1px solid #0f3460;
|
|
||||||
display: flex;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-area input {
|
|
||||||
flex: 1;
|
|
||||||
padding: 8px 12px;
|
|
||||||
border: 1px solid #0f3460;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: #1a1a2e;
|
|
||||||
color: #eee;
|
|
||||||
font-size: 14px;
|
|
||||||
font-family: 'Consolas', 'Monaco', monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-area input:focus {
|
|
||||||
outline: none;
|
|
||||||
border-color: #e94560;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-area button {
|
|
||||||
padding: 8px 16px;
|
|
||||||
background: #e94560;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-area button:hover {
|
|
||||||
background: #ff6b6b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading {
|
.loading {
|
||||||
|
|
@ -152,7 +118,6 @@
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div id="terminal">
|
<div id="terminal">
|
||||||
<div class="loading">正在连接游戏服务器...</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="input-area">
|
<div class="input-area">
|
||||||
<input type="text" id="game-input" placeholder="输入命令..." disabled>
|
<input type="text" id="game-input" placeholder="输入命令..." disabled>
|
||||||
|
|
@ -167,6 +132,7 @@
|
||||||
let fitAddon = null;
|
let fitAddon = null;
|
||||||
let ws = null;
|
let ws = null;
|
||||||
let connected = false;
|
let connected = false;
|
||||||
|
let inputBuffer = ''; // 缓存用户输入
|
||||||
|
|
||||||
// 初始化终端
|
// 初始化终端
|
||||||
function initTerminal() {
|
function initTerminal() {
|
||||||
|
|
@ -176,8 +142,8 @@
|
||||||
cursorBlink: true,
|
cursorBlink: true,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontFamily: '"Source Code Pro", "Courier New", monospace',
|
fontFamily: '"Source Code Pro", "Courier New", monospace',
|
||||||
letterSpacing: 0, // 禁用自动间距调整
|
letterSpacing: 0,
|
||||||
lineHeight: 1.2, // 调整行高
|
lineHeight: 1.3,
|
||||||
theme: {
|
theme: {
|
||||||
background: '#1a1a2e',
|
background: '#1a1a2e',
|
||||||
foreground: '#eee',
|
foreground: '#eee',
|
||||||
|
|
@ -211,11 +177,49 @@
|
||||||
terminal.open(document.getElementById('terminal'));
|
terminal.open(document.getElementById('terminal'));
|
||||||
fitAddon.fit();
|
fitAddon.fit();
|
||||||
|
|
||||||
|
// 监听终端输入事件
|
||||||
|
terminal.onData((data) => {
|
||||||
|
// 处理输入
|
||||||
|
if (data === '\r' || data === '\n') {
|
||||||
|
// 用户按了回车
|
||||||
|
if (inputBuffer) {
|
||||||
|
sendInput();
|
||||||
|
}
|
||||||
|
} else if (data === '\u007F') {
|
||||||
|
// 处理退格键
|
||||||
|
if (inputBuffer.length > 0) {
|
||||||
|
inputBuffer = inputBuffer.slice(0, -1);
|
||||||
|
terminal.write('\b \b');
|
||||||
|
}
|
||||||
|
} else if (data === '\u0003') {
|
||||||
|
// Ctrl+C - 中断
|
||||||
|
inputBuffer = '';
|
||||||
|
terminal.write('^C\r\n');
|
||||||
|
} else {
|
||||||
|
// 普通字符
|
||||||
|
inputBuffer += data;
|
||||||
|
terminal.write(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
fitAddon.fit();
|
fitAddon.fit();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 发送输入到服务器
|
||||||
|
function sendInput() {
|
||||||
|
if (!inputBuffer) return;
|
||||||
|
|
||||||
|
const input = inputBuffer;
|
||||||
|
inputBuffer = '';
|
||||||
|
|
||||||
|
sendMessage({
|
||||||
|
type: 'input',
|
||||||
|
input: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 连接WebSocket
|
// 连接WebSocket
|
||||||
function connectWebSocket() {
|
function connectWebSocket() {
|
||||||
const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||||
|
|
@ -233,13 +237,9 @@
|
||||||
terminal.clear();
|
terminal.clear();
|
||||||
terminal.writeln('\x1b[32m[✓] WebSocket 连接成功,游戏进程已启动\x1b[0m');
|
terminal.writeln('\x1b[32m[✓] WebSocket 连接成功,游戏进程已启动\x1b[0m');
|
||||||
terminal.writeln('');
|
terminal.writeln('');
|
||||||
|
terminal.focus(); // 设置终端焦点以接收输入
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启用输入
|
|
||||||
document.getElementById('game-input').disabled = false;
|
|
||||||
document.getElementById('send-btn').disabled = false;
|
|
||||||
document.getElementById('game-input').focus();
|
|
||||||
|
|
||||||
// 启动心跳
|
// 启动心跳
|
||||||
startHeartbeat();
|
startHeartbeat();
|
||||||
};
|
};
|
||||||
|
|
@ -279,8 +279,11 @@
|
||||||
}
|
}
|
||||||
switch (data.type) {
|
switch (data.type) {
|
||||||
case 'output':
|
case 'output':
|
||||||
// 进程输出 - 直接写入,游戏进程负责清屏
|
terminal.clear();
|
||||||
terminal.write(data.text);
|
const lines = data.text.split('\n');
|
||||||
|
lines.forEach(line => {
|
||||||
|
terminal.writeln(line);
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'system':
|
case 'system':
|
||||||
|
|
@ -312,28 +315,6 @@
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送输入
|
|
||||||
function sendInput() {
|
|
||||||
const inputEl = document.getElementById('game-input');
|
|
||||||
const input = inputEl.value;
|
|
||||||
inputEl.value = '';
|
|
||||||
|
|
||||||
if (!input) return;
|
|
||||||
|
|
||||||
// 立即在终端显示用户输入(带换行)
|
|
||||||
if (terminal) {
|
|
||||||
terminal.writeln(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 发送到服务器
|
|
||||||
sendMessage({
|
|
||||||
type: 'input',
|
|
||||||
input: input
|
|
||||||
});
|
|
||||||
|
|
||||||
inputEl.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 断开连接
|
// 断开连接
|
||||||
function disconnect() {
|
function disconnect() {
|
||||||
if (ws) {
|
if (ws) {
|
||||||
|
|
@ -356,13 +337,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 键盘处理
|
|
||||||
document.addEventListener('keypress', (e) => {
|
|
||||||
if (e.key === 'Enter' && document.activeElement.id === 'game-input') {
|
|
||||||
sendInput();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 心跳保活
|
// 心跳保活
|
||||||
function startHeartbeat() {
|
function startHeartbeat() {
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user