writeln() does not write a new line and every write is shown twice and i need to click on the div to update the text #4615
-
*Edit: in production it works fine Details
Steps to reproduce
import {Component} from "react";
import React from "react";
import {Alert, Button, Divider, LinearProgress, styled, Theme, useTheme} from "@mui/joy";
import WarningAmberRoundedIcon from '@mui/icons-material/WarningAmberRounded';
import '../../../wailsjs/runtime/runtime';
import {EventsOff, EventsOn, LogPrint} from "../../../wailsjs/runtime";
import {Install} from '../../../wailsjs/go/installer/Installer';
import {Terminal} from "xterm";
import 'xterm/css/xterm.css';
//ts
interface State {
buttonVisible: boolean;
}
export class Installer extends Component<{}, State> {
//PROPS AND STATE
private term: Terminal = new Terminal();
constructor(props: {}) {
super(props);
this.state = {
buttonVisible: true,
};
}
// region EVENTS
componentDidMount() {
EventsOn("printToConsole", (line: string) => {
this.WriteLineToLog(line);
});
const element = document.getElementById('console') as HTMLElement;
this.term.open(element);
this.term.writeln('Hello from \x1B[1;3;31mxterm.js\x1B[0m $ \r\n');
this.term.writeln('Hello from \x1B[1;3;31mxterm.js\x1B[0m $ \r\n');
}
componentWillUnmount() {
// Cleanup the event listener here when the component is unmounted
EventsOff("printToConsole");
if (this.term) {
this.term.dispose();
}
}
WriteLineToLog(line: string){
}
handleButtonClick = () => {
if (this.term) {
this.term.writeln('New line written on button click!\r\n\n\n'); // Add a new line when the button is clicked
}
};
//endregion
render() {
const Level1Div = styled('div')(({ theme }) => ({
// The result is 'var(--joy-palette-primary-500)'
backgroundColor: theme.vars.palette.background.level1,
}));
return (
<>
<Level1Div className="">
<LinearProgress value={40} className="mt-1" />
<p className="text-center text-xl mt-2">Installing Rust server </p>
<Divider orientation="horizontal"/>
<p className="font-bold ">Log:</p>
<Button onClick={this.handleButtonClick} ></Button>
<div className="" id="console"></div>
</Level1Div>
</>
);
}
}
I've been messing with it for 3 hourse now, can't find the problem |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 23 replies
-
Ok, i found out that the double printing is because its being called in componentDidMount without that and just clicking the button a couple of times i get: |
Beta Was this translation helpful? Give feedback.
-
Try setting options.logLevel to |
Beta Was this translation helpful? Give feedback.
-
New news! if i just build my project for production it works fine? |
Beta Was this translation helpful? Give feedback.
-
Update it kind of was not xterm but react, ill explain: export class Installer extends Component<{}, State> {
//PROPS AND STATE
private term: Terminal = new Terminal();
constructor(props: {}) {
super(props);
this.state = {
buttonVisible: true,
};
}
// region EVENTS
componentDidMount() {
EventsOn("printToConsole", (line: string) => {
this.WriteLineToLog(line);
});
const element = document.getElementById('console') as HTMLElement;
this.term.open(element);
this.term.writeln('Hello from \x1B[1;3;31mxterm.js\x1B[0m $ \r\n');
this.term.writeln('Hello from \x1B[1;3;31mxterm.js\x1B[0m $ \r\n');
}
componentWillUnmount() {
// Cleanup the event listener here when the component is unmounted
EventsOff("printToConsole");
if (this.term) {
this.term.dispose();
}
}
WriteLineToLog(line: string){
}
handleButtonClick = () => {
if (this.term) {
this.term.writeln('New line written on button click!\r\n\n\n'); // Add a new line when the button is clicked
}
};
//endregion
render() {
const Level1Div = styled('div')(({ theme }) => ({
// The result is 'var(--joy-palette-primary-500)'
backgroundColor: theme.vars.palette.background.level1,
}));
return (
<>
<Level1Div className="">
<LinearProgress value={40} className="mt-1" />
<p className="text-center text-xl mt-2">Installing Rust server </p>
<Divider orientation="horizontal"/>
<p className="font-bold ">Log:</p>
<Button onClick={this.handleButtonClick} ></Button>
<div className="" id="console"></div>
</Level1Div>
</>
);
}
} The terminal instance gets created outside of the constructor and componentDidMount like: export class Installer extends Component<{}, State> {
//PROPS AND STATE
private term: Terminal = new Terminal();
........ This does not work, the following does work: export class Installer extends Component {
//don't make a new terminal instance here because it will break the terminal
terminalRef: Terminal | null = null;
componentDidMount() {
// Handle events
EventsOn('printToConsole', (line: string) => {
//this.WriteLineToLog(line);
});
// Create a new terminal instance
const term = new Terminal({ logLevel: 'debug', windowsMode: true });
this.terminalRef = term;
const termEle = document.getElementById('terminal');
// Attach the terminal to the DOM element
if (termEle) {
term.open(termEle);
}
// Write initial text to the terminal
term.writeln('Hello from xterm.js $');
term.writeln('Hello from xterm.js $');
}
componentWillUnmount() {
// Clean up the terminal instance and event listeners when the component unmounts
const term = this.terminalRef;
if (term) {
term.dispose();
}
// Cleanup events
EventsOff('printToConsole');
}
handleButtonClick = () => {
const term = this.terminalRef;
if (term) {
term.writeln('New line written on button click!'); // Add a new line when the button is clicked
}
};
render() {
const Level1Div = styled('div')(({ theme }) => ({
// The result is 'var(--joy-palette-primary-500)'
backgroundColor: theme.vars.palette.background.level1,
}));
return (
<>
<Level1Div className="">
<LinearProgress value={40} className="mt-1" />
<p className="text-center text-xl mt-2">Installing Rust server</p>
<Divider orientation="horizontal" />
<p className="font-bold">Log:</p>
<Button onClick={this.handleButtonClick}></Button>
<div className="" id="terminal"></div>
</Level1Div>
</>
);
}
}
export default Installer; So the terminal instance must be created after the component mounted. const Installer = () => {
const terminalRef = useRef<Terminal>();
const [buttonVisible, setButtonVisible] = React.useState(true);
useEffect(() => {
//handle events
EventsOn("printToConsole", (line: string) => {
//this.WriteLineToLog(line);
});
// Create a new terminal instance
const term = new Terminal({logLevel : 'debug', windowsMode: true});
terminalRef.current = term;
const termele = document.getElementById("terminal");
// Attach the terminal to the DOM element
if (termele) {
term.open(termele);
}
// Write initial text to the terminal
term.writeln('Hello from xterm.js $');
term.writeln('Hello from xterm.js $');
//componentwillunmount
return () => {
// Clean up the terminal instance when the component unmounts
term.dispose();
//cleanup events
EventsOff("printToConsole");
};
}, []);
const Level1Div = styled('div')(({ theme }) => ({
// The result is 'var(--joy-palette-primary-500)'
backgroundColor: theme.vars.palette.background.level1,
}));
const handleButtonClick = () => {
const term = terminalRef.current;
if (term) {
term.writeln("New line written on button click!"); // Add a new line when the button is clicked
}
};
return (
<>
<Level1Div className="">
<LinearProgress value={40} className="mt-1" />
<p className="text-center text-xl mt-2">Installing Rust server </p>
<Divider orientation="horizontal"/>
<p className="font-bold ">Log:</p>
<Button onClick={handleButtonClick} ></Button>
<div className="" id="terminal"></div>
</Level1Div>
</>
);
};
export default Installer; It took me a long time to find the real answer but i'm happy now :) |
Beta Was this translation helpful? Give feedback.
Update it kind of was not xterm but react, ill explain:
Dont know if this is just a stupid error on my side but:
this is the old code: