import { useEffect, useRef, useState } from "react"; import { Modal, Button, ColorPicker, Group, Grid } from "@mantine/core"; import { Terminal } from "xterm"; import { FitAddon } from "@xterm/addon-fit"; interface Props { opened: boolean; onClose: () => void; onSave: () => void; } export default function ModalConfig({ opened, onClose, onSave }: Props) { const [color, setColor] = useState("#41ee4a"); const [loaded, setLoaded] = useState(false); const xtermRef = useRef(null); const terminal = useRef(null); const fitRef = useRef(null); useEffect(() => { // Load saved color from localStorage const saved = localStorage.getItem("terminal-text-color"); if (saved) setColor(saved); }, []); const handleSave = () => { localStorage.setItem("terminal-text-color", color); onClose(); onSave(); }; useEffect(() => { if (!loaded || fitRef.current || terminal.current || !xtermRef.current) return; const textColor = localStorage.getItem("terminal-text-color") || "#41ee4a"; terminal.current = new Terminal({ disableStdin: true, cursorBlink: true, convertEol: true, fontFamily: "Consolas, 'Courier New', monospace", fontSize: 12, theme: { background: "#000000", foreground: textColor, cursor: "#ffffff", }, rows: 24, cols: 80, }); const fitAddon = new FitAddon(); fitRef.current = fitAddon; terminal.current.loadAddon(fitAddon); if (xtermRef.current) terminal.current.open(xtermRef.current); terminal.current?.write( "Change color \nChange color\nChange color\nChange color" ); fitAddon.fit(); }, [loaded, xtermRef]); useEffect(() => { if (terminal.current && terminal.current.options.theme) { terminal.current.options.theme = { background: "#000000", foreground: color, cursor: "#ffffff", }; } }, [color]); useEffect(() => { if (opened) { setTimeout(() => { setLoaded(true); }, 100); } else { setLoaded(false); fitRef.current = null; terminal.current = null; const saved = localStorage.getItem("terminal-text-color"); if (saved) setColor(saved); } }, [opened]); return (
{ event.preventDefault(); event.stopPropagation(); }} ref={xtermRef} style={{ width: "100%", paddingLeft: "10px", paddingBottom: "10px", fontSize: "12px", maxHeight: "220px", height: "220px", padding: "4px", paddingRight: 0, }} onDoubleClick={(event) => { event.preventDefault(); event.stopPropagation(); }} />
); }