sandbox-web-ide/frontend/context/TerminalContext.tsx

96 lines
2.8 KiB
TypeScript
Raw Normal View History

2024-07-23 17:30:35 -04:00
"use client";
import React, { createContext, useContext, useState } from 'react';
2024-07-23 17:30:35 -04:00
import { Terminal } from '@xterm/xterm';
2024-07-23 20:17:50 -04:00
import { createTerminal as createTerminalHelper, closeTerminal as closeTerminalHelper } from '@/lib/terminal';
import { useSocket } from '@/context/SocketContext';
2024-07-23 17:30:35 -04:00
interface TerminalContextType {
terminals: { id: string; terminal: Terminal | null }[];
setTerminals: React.Dispatch<React.SetStateAction<{ id: string; terminal: Terminal | null }[]>>;
activeTerminalId: string;
setActiveTerminalId: React.Dispatch<React.SetStateAction<string>>;
creatingTerminal: boolean;
setCreatingTerminal: React.Dispatch<React.SetStateAction<boolean>>;
createNewTerminal: (command?: string) => Promise<void>;
2024-07-23 17:30:35 -04:00
closeTerminal: (id: string) => void;
deploy: (callback: () => void) => void;
2024-07-23 17:30:35 -04:00
}
const TerminalContext = createContext<TerminalContextType | undefined>(undefined);
export const TerminalProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const { socket } = useSocket();
2024-07-23 17:30:35 -04:00
const [terminals, setTerminals] = useState<{ id: string; terminal: Terminal | null }[]>([]);
const [activeTerminalId, setActiveTerminalId] = useState<string>('');
const [creatingTerminal, setCreatingTerminal] = useState<boolean>(false);
const createNewTerminal = async (command?: string): Promise<void> => {
2024-07-23 17:30:35 -04:00
if (!socket) return;
setCreatingTerminal(true);
try {
createTerminalHelper({
setTerminals,
setActiveTerminalId,
setCreatingTerminal,
command,
2024-07-23 17:30:35 -04:00
socket,
});
} catch (error) {
console.error("Error creating terminal:", error);
} finally {
setCreatingTerminal(false);
}
};
const closeTerminal = (id: string) => {
if (!socket) return;
const terminalToClose = terminals.find(term => term.id === id);
if (terminalToClose) {
closeTerminalHelper({
term: terminalToClose,
terminals,
setTerminals,
setActiveTerminalId,
setClosingTerminal: () => {},
socket,
activeTerminalId,
});
}
};
const deploy = (callback: () => void) => {
if (!socket) console.error("Couldn't deploy: No socket");
console.log("Deploying...")
socket?.emit("deploy", () => {
callback();
});
}
2024-07-23 17:30:35 -04:00
const value = {
terminals,
setTerminals,
activeTerminalId,
setActiveTerminalId,
creatingTerminal,
setCreatingTerminal,
createNewTerminal,
closeTerminal,
deploy
2024-07-23 17:30:35 -04:00
};
return (
<TerminalContext.Provider value={value}>
{children}
</TerminalContext.Provider>
);
};
export const useTerminal = (): TerminalContextType => {
const context = useContext(TerminalContext);
if (!context) {
throw new Error('useTerminal must be used within a TerminalProvider');
}
return context;
};