Close terminal when connection is deleted
This commit is contained in:
parent
9ec5bf0788
commit
d60f37f2ed
26
app.js
26
app.js
@ -17,6 +17,7 @@ const duplicateContainerForm = document.getElementById('duplicate-container-form
|
|||||||
|
|
||||||
// Global variables
|
// Global variables
|
||||||
const connections = {};
|
const connections = {};
|
||||||
|
window.openTerminals = {};
|
||||||
let activePeer = null;
|
let activePeer = null;
|
||||||
window.activePeer = null; // Expose to other modules
|
window.activePeer = null; // Expose to other modules
|
||||||
|
|
||||||
@ -130,7 +131,6 @@ function addConnection(topicHex) {
|
|||||||
peer.on('close', () => {
|
peer.on('close', () => {
|
||||||
console.log(`[INFO] Disconnected from peer for topic: ${topicHex}`);
|
console.log(`[INFO] Disconnected from peer for topic: ${topicHex}`);
|
||||||
updateConnectionStatus(topicId, false);
|
updateConnectionStatus(topicId, false);
|
||||||
connections[topicId].peer = null; // Clear the peer reference
|
|
||||||
|
|
||||||
if (window.activePeer === peer) {
|
if (window.activePeer === peer) {
|
||||||
window.activePeer = null;
|
window.activePeer = null;
|
||||||
@ -154,6 +154,26 @@ function addConnection(topicHex) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close and kill any open terminals associated with this connection
|
||||||
|
if (window.openTerminals[topicId]) {
|
||||||
|
console.log(`[INFO] Closing terminals for topic: ${topicId}`);
|
||||||
|
window.openTerminals[topicId].forEach((containerId) => {
|
||||||
|
try {
|
||||||
|
cleanUpTerminal(containerId); // Use the terminal.js cleanup logic
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`[ERROR] Failed to kill terminal for container ${containerId}: ${err.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
delete window.openTerminals[topicId];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide the terminal modal if it is active
|
||||||
|
const terminalModal = document.getElementById('terminal-modal');
|
||||||
|
if (terminalModal.style.display === 'flex') {
|
||||||
|
console.log(`[INFO] Hiding terminal modal for disconnected topic: ${topicId}`);
|
||||||
|
terminalModal.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
// Disconnect the peer and destroy the swarm
|
// Disconnect the peer and destroy the swarm
|
||||||
if (connection.peer) {
|
if (connection.peer) {
|
||||||
connection.peer.destroy();
|
connection.peer.destroy();
|
||||||
@ -173,11 +193,12 @@ function addConnection(topicHex) {
|
|||||||
console.log(`[INFO] Disconnected and removed connection: ${topicId}`);
|
console.log(`[INFO] Disconnected and removed connection: ${topicId}`);
|
||||||
|
|
||||||
// Reset active peer if it was the disconnected connection
|
// Reset active peer if it was the disconnected connection
|
||||||
|
if (window.activePeer === connection.peer) {
|
||||||
window.activePeer = null;
|
window.activePeer = null;
|
||||||
connectionTitle.textContent = 'Choose a Connection'; // Reset title
|
connectionTitle.textContent = 'Choose a Connection'; // Reset title
|
||||||
dashboard.classList.add('hidden');
|
dashboard.classList.add('hidden');
|
||||||
containerList.innerHTML = ''; // Clear the container list
|
containerList.innerHTML = ''; // Clear the container list
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure the container list is cleared regardless of the active connection
|
// Ensure the container list is cleared regardless of the active connection
|
||||||
resetContainerList();
|
resetContainerList();
|
||||||
@ -185,7 +206,6 @@ function addConnection(topicHex) {
|
|||||||
// Refresh the connections view
|
// Refresh the connections view
|
||||||
resetConnectionsView();
|
resetConnectionsView();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to reset the container list
|
// Function to reset the container list
|
||||||
function resetContainerList() {
|
function resetContainerList() {
|
||||||
containerList.innerHTML = ''; // Clear the existing list
|
containerList.innerHTML = ''; // Clear the existing list
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
// terminal.js
|
|
||||||
import { Terminal } from 'xterm';
|
import { Terminal } from 'xterm';
|
||||||
import { FitAddon } from 'xterm-addon-fit';
|
import { FitAddon } from 'xterm-addon-fit';
|
||||||
|
|
||||||
@ -14,6 +13,11 @@ let activeContainerId = null; // Currently displayed containerId
|
|||||||
|
|
||||||
// Kill Terminal button functionality
|
// Kill Terminal button functionality
|
||||||
document.getElementById('kill-terminal-btn').onclick = () => {
|
document.getElementById('kill-terminal-btn').onclick = () => {
|
||||||
|
killActiveTerminal();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Kill the active terminal session
|
||||||
|
function killActiveTerminal() {
|
||||||
const containerId = activeContainerId;
|
const containerId = activeContainerId;
|
||||||
|
|
||||||
if (containerId && terminalSessions[containerId]) {
|
if (containerId && terminalSessions[containerId]) {
|
||||||
@ -23,19 +27,7 @@ document.getElementById('kill-terminal-btn').onclick = () => {
|
|||||||
window.sendCommand('killTerminal', { containerId });
|
window.sendCommand('killTerminal', { containerId });
|
||||||
|
|
||||||
// Clean up terminal session
|
// Clean up terminal session
|
||||||
const session = terminalSessions[containerId];
|
cleanUpTerminal(containerId);
|
||||||
session.xterm.dispose();
|
|
||||||
session.onDataDisposable.dispose();
|
|
||||||
if (session.resizeListener) {
|
|
||||||
window.removeEventListener('resize', session.resizeListener);
|
|
||||||
}
|
|
||||||
// Remove the terminal's container div from DOM
|
|
||||||
session.container.parentNode.removeChild(session.container);
|
|
||||||
|
|
||||||
delete terminalSessions[containerId];
|
|
||||||
|
|
||||||
// Remove from tray if exists
|
|
||||||
removeFromTray(containerId);
|
|
||||||
|
|
||||||
// Hide the terminal modal if this was the active session
|
// Hide the terminal modal if this was the active session
|
||||||
if (activeContainerId === containerId) {
|
if (activeContainerId === containerId) {
|
||||||
@ -45,7 +37,7 @@ document.getElementById('kill-terminal-btn').onclick = () => {
|
|||||||
} else {
|
} else {
|
||||||
console.error('[ERROR] No terminal session found to kill.');
|
console.error('[ERROR] No terminal session found to kill.');
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
// Start terminal session
|
// Start terminal session
|
||||||
function startTerminal(containerId, containerName) {
|
function startTerminal(containerId, containerName) {
|
||||||
@ -55,10 +47,7 @@ function startTerminal(containerId, containerName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (terminalSessions[containerId]) {
|
if (terminalSessions[containerId]) {
|
||||||
// Terminal session already exists
|
|
||||||
console.log(`[INFO] Terminal session already exists for container: ${containerId}`);
|
console.log(`[INFO] Terminal session already exists for container: ${containerId}`);
|
||||||
|
|
||||||
// If terminal is minimized or not active, switch to it
|
|
||||||
if (activeContainerId !== containerId || terminalModal.style.display === 'none') {
|
if (activeContainerId !== containerId || terminalModal.style.display === 'none') {
|
||||||
switchTerminal(containerId);
|
switchTerminal(containerId);
|
||||||
} else {
|
} else {
|
||||||
@ -67,10 +56,8 @@ function startTerminal(containerId, containerName) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new terminal session
|
|
||||||
console.log(`[INFO] Creating new terminal session for container: ${containerId}`);
|
console.log(`[INFO] Creating new terminal session for container: ${containerId}`);
|
||||||
|
|
||||||
// Initialize new terminal session
|
|
||||||
const xterm = new Terminal({
|
const xterm = new Terminal({
|
||||||
cursorBlink: true,
|
cursorBlink: true,
|
||||||
theme: { background: '#000000', foreground: '#ffffff' },
|
theme: { background: '#000000', foreground: '#ffffff' },
|
||||||
@ -78,21 +65,16 @@ function startTerminal(containerId, containerName) {
|
|||||||
const fitAddon = new FitAddon();
|
const fitAddon = new FitAddon();
|
||||||
xterm.loadAddon(fitAddon);
|
xterm.loadAddon(fitAddon);
|
||||||
|
|
||||||
// Create a container div for this terminal
|
|
||||||
const terminalDiv = document.createElement('div');
|
const terminalDiv = document.createElement('div');
|
||||||
terminalDiv.style.width = '100%';
|
terminalDiv.style.width = '100%';
|
||||||
terminalDiv.style.height = '100%';
|
terminalDiv.style.height = '100%';
|
||||||
terminalDiv.style.display = 'none'; // Initially hidden
|
terminalDiv.style.display = 'none'; // Initially hidden
|
||||||
terminalContainer.appendChild(terminalDiv);
|
terminalContainer.appendChild(terminalDiv);
|
||||||
|
|
||||||
// Open the terminal in the container div
|
|
||||||
xterm.open(terminalDiv);
|
xterm.open(terminalDiv);
|
||||||
|
|
||||||
// Set up event listener for terminal input using onData
|
|
||||||
const onDataDisposable = xterm.onData((data) => {
|
const onDataDisposable = xterm.onData((data) => {
|
||||||
console.log(`[DEBUG] Sending terminal input for container ${containerId}: ${data}`);
|
console.log(`[DEBUG] Sending terminal input for container ${containerId}: ${data}`);
|
||||||
|
|
||||||
// Base64 encode the data
|
|
||||||
window.activePeer.write(
|
window.activePeer.write(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
type: 'terminalInput',
|
type: 'terminalInput',
|
||||||
@ -103,7 +85,6 @@ function startTerminal(containerId, containerName) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Store the terminal session
|
|
||||||
terminalSessions[containerId] = {
|
terminalSessions[containerId] = {
|
||||||
xterm,
|
xterm,
|
||||||
fitAddon,
|
fitAddon,
|
||||||
@ -114,13 +95,11 @@ function startTerminal(containerId, containerName) {
|
|||||||
container: terminalDiv,
|
container: terminalDiv,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send startTerminal command to server
|
|
||||||
console.log(`[INFO] Starting terminal for container: ${containerId}`);
|
console.log(`[INFO] Starting terminal for container: ${containerId}`);
|
||||||
window.activePeer.write(
|
window.activePeer.write(
|
||||||
JSON.stringify({ command: 'startTerminal', args: { containerId } })
|
JSON.stringify({ command: 'startTerminal', args: { containerId } })
|
||||||
);
|
);
|
||||||
|
|
||||||
// Switch to the requested terminal session
|
|
||||||
switchTerminal(containerId);
|
switchTerminal(containerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,39 +111,29 @@ function switchTerminal(containerId) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide the current terminal if any
|
|
||||||
if (activeContainerId && activeContainerId !== containerId) {
|
if (activeContainerId && activeContainerId !== containerId) {
|
||||||
const currentSession = terminalSessions[activeContainerId];
|
const currentSession = terminalSessions[activeContainerId];
|
||||||
if (currentSession) {
|
if (currentSession) {
|
||||||
// Remove resize listener for current session
|
|
||||||
if (currentSession.resizeListener) {
|
if (currentSession.resizeListener) {
|
||||||
window.removeEventListener('resize', currentSession.resizeListener);
|
window.removeEventListener('resize', currentSession.resizeListener);
|
||||||
currentSession.resizeListener = null;
|
currentSession.resizeListener = null;
|
||||||
}
|
}
|
||||||
// Hide current terminal's container
|
|
||||||
currentSession.container.style.display = 'none';
|
currentSession.container.style.display = 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show the terminal
|
|
||||||
session.container.style.display = 'block';
|
session.container.style.display = 'block';
|
||||||
|
setTimeout(() => session.fitAddon.fit(), 10);
|
||||||
|
|
||||||
setTimeout(() => session.fitAddon.fit(), 10); // Ensure terminal fits properly after rendering
|
|
||||||
|
|
||||||
// Update modal title
|
|
||||||
terminalTitle.dataset.containerId = containerId;
|
terminalTitle.dataset.containerId = containerId;
|
||||||
terminalTitle.textContent = `Container Terminal: ${session.name}`;
|
terminalTitle.textContent = `Container Terminal: ${session.name}`;
|
||||||
|
|
||||||
// Show the terminal modal
|
|
||||||
terminalModal.style.display = 'flex';
|
terminalModal.style.display = 'flex';
|
||||||
activeContainerId = containerId;
|
activeContainerId = containerId;
|
||||||
|
|
||||||
// Remove from tray if it exists
|
|
||||||
removeFromTray(containerId);
|
removeFromTray(containerId);
|
||||||
|
|
||||||
console.log(`[INFO] Switched to terminal for container: ${containerId}`);
|
console.log(`[INFO] Switched to terminal for container: ${containerId}`);
|
||||||
|
|
||||||
// Adjust resize event listener
|
|
||||||
if (session.resizeListener) {
|
if (session.resizeListener) {
|
||||||
window.removeEventListener('resize', session.resizeListener);
|
window.removeEventListener('resize', session.resizeListener);
|
||||||
}
|
}
|
||||||
@ -187,7 +156,6 @@ function appendTerminalOutput(data, containerId, encoding) {
|
|||||||
outputData = data;
|
outputData = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the decoded data to the terminal
|
|
||||||
session.xterm.write(outputData);
|
session.xterm.write(outputData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,5 +167,30 @@ function removeFromTray(containerId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clean up terminal session
|
||||||
|
function cleanUpTerminal(containerId) {
|
||||||
|
const session = terminalSessions[containerId];
|
||||||
|
if (session) {
|
||||||
|
session.xterm.dispose();
|
||||||
|
session.onDataDisposable.dispose();
|
||||||
|
if (session.resizeListener) {
|
||||||
|
window.removeEventListener('resize', session.resizeListener);
|
||||||
|
}
|
||||||
|
session.container.parentNode.removeChild(session.container);
|
||||||
|
delete terminalSessions[containerId];
|
||||||
|
console.log(`[INFO] Cleaned up terminal for container: ${containerId}`);
|
||||||
|
} else {
|
||||||
|
console.error(`[ERROR] No terminal session to clean up for container: ${containerId}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up all terminals
|
||||||
|
function cleanUpAllTerminals() {
|
||||||
|
Object.keys(terminalSessions).forEach(cleanUpTerminal);
|
||||||
|
terminalModal.style.display = 'none';
|
||||||
|
activeContainerId = null;
|
||||||
|
console.log('[INFO] All terminal sessions cleaned up.');
|
||||||
|
}
|
||||||
|
|
||||||
// Expose functions to app.js
|
// Expose functions to app.js
|
||||||
export { startTerminal, appendTerminalOutput };
|
export { startTerminal, appendTerminalOutput, cleanUpAllTerminals };
|
||||||
|
Loading…
Reference in New Issue
Block a user