Implement WebSocket support for terminal connections and enhance terminal UI
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import React from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { X } from "lucide-react";
|
||||
|
||||
const Panel = ({
|
||||
@@ -21,9 +20,67 @@ const Panel = ({
|
||||
setActiveTab(initialTab);
|
||||
}, [initialTab]);
|
||||
|
||||
// Update the renderTerminal function to create an interactive terminal
|
||||
const renderTerminal = () => {
|
||||
const terminalRef = useRef(null);
|
||||
const [inputBuffer, setInputBuffer] = useState("");
|
||||
|
||||
// Auto-scroll terminal to bottom when content changes
|
||||
useEffect(() => {
|
||||
if (terminalRef.current) {
|
||||
terminalRef.current.scrollTop = terminalRef.current.scrollHeight;
|
||||
}
|
||||
}, [terminalOutput]);
|
||||
|
||||
// Set up keyboard event listeners when terminal is focused
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e) => {
|
||||
if (!isRunning) return;
|
||||
|
||||
if (e.key === 'Enter') {
|
||||
// Send current input buffer through WebSocket
|
||||
if (inputBuffer.trim() && onInputSubmit) {
|
||||
e.preventDefault(); // Prevent default Enter behavior
|
||||
|
||||
// Important: Set user input and THEN call submit in a sequence
|
||||
onUserInputChange(inputBuffer);
|
||||
|
||||
// Add a small delay before submitting to ensure state update
|
||||
setTimeout(() => {
|
||||
onInputSubmit();
|
||||
// Clear buffer after submission is processed
|
||||
setInputBuffer("");
|
||||
}, 10);
|
||||
}
|
||||
} else if (e.key === 'Backspace') {
|
||||
// Handle backspace to remove characters
|
||||
setInputBuffer(prev => prev.slice(0, -1));
|
||||
} else if (e.key.length === 1) {
|
||||
// Add regular characters to input buffer
|
||||
setInputBuffer(prev => prev + e.key);
|
||||
}
|
||||
};
|
||||
|
||||
// Add event listener
|
||||
if (terminalRef.current) {
|
||||
terminalRef.current.addEventListener('keydown', handleKeyDown);
|
||||
}
|
||||
|
||||
// Clean up
|
||||
return () => {
|
||||
if (terminalRef.current) {
|
||||
terminalRef.current.removeEventListener('keydown', handleKeyDown);
|
||||
}
|
||||
};
|
||||
}, [isRunning, inputBuffer, onInputSubmit, onUserInputChange]);
|
||||
|
||||
return (
|
||||
<div className="panel-terminal">
|
||||
<div
|
||||
className="panel-terminal"
|
||||
ref={terminalRef}
|
||||
tabIndex={0} // Make div focusable
|
||||
onClick={() => terminalRef.current?.focus()} // Focus when clicked
|
||||
>
|
||||
{terminalOutput.length > 0 ? (
|
||||
// Render output from EditorArea when available
|
||||
<>
|
||||
@@ -32,36 +89,18 @@ const Panel = ({
|
||||
{line.type === 'command' ? <span className="terminal-prompt">$</span> : ''} {line.content}
|
||||
</div>
|
||||
))}
|
||||
{waitingForInput && (
|
||||
<div className="terminal-line">
|
||||
<span className="terminal-prompt">Input:</span>
|
||||
<input
|
||||
type="text"
|
||||
className="terminal-input"
|
||||
value={userInput}
|
||||
onChange={(e) => onUserInputChange && onUserInputChange(e.target.value)}
|
||||
placeholder="Enter input for your program here..."
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' && onInputSubmit) {
|
||||
onInputSubmit();
|
||||
}
|
||||
}}
|
||||
autoFocus
|
||||
/>
|
||||
|
||||
{/* Show current input with blinking cursor only when connection is active */}
|
||||
{isRunning && (
|
||||
<div className="terminal-line terminal-input-line">
|
||||
<span className="terminal-prompt">$</span> {inputBuffer}
|
||||
<span className="terminal-cursor"></span>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
// Default terminal content when no output
|
||||
// Default terminal content
|
||||
<>
|
||||
<div className="terminal-line">
|
||||
<span className="terminal-prompt">$</span> npm start
|
||||
</div>
|
||||
<div className="terminal-line terminal-output">Starting the development server...</div>
|
||||
<div className="terminal-line terminal-output">Compiled successfully!</div>
|
||||
<div className="terminal-line terminal-output">You can now view vscode-clone in the browser.</div>
|
||||
<div className="terminal-line terminal-output">Local: http://localhost:3000</div>
|
||||
<div className="terminal-line terminal-output">On Your Network: http://192.168.1.5:3000</div>
|
||||
<div className="terminal-line">
|
||||
<span className="terminal-prompt">$</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user