Skip to content

Commit b6c063b

Browse files
committed
test(frontend): show only static text for xterm
1 parent f35a941 commit b6c063b

File tree

1 file changed

+86
-42
lines changed

1 file changed

+86
-42
lines changed

frontend/src/app/core/mud/components/mud-client/mud-client.component.ts

Lines changed: 86 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { AsyncPipe } from '@angular/common';
1010
import { AttachAddon } from '@xterm/addon-attach';
1111
import { FitAddon } from '@xterm/addon-fit';
1212
import { IDisposable, Terminal } from '@xterm/xterm';
13-
import { Subscription } from 'rxjs';
13+
import { of, Subscription } from 'rxjs';
1414

1515
import { MudService } from '../../services/mud.service';
1616
import { SecureString } from '@mudlet3/frontend/shared';
@@ -48,23 +48,14 @@ const DELETE_SEQUENCE = `${CTRL.ESC}[3~`;
4848
})
4949
export class MudClientComponent implements AfterViewInit, OnDestroy {
5050
private readonly mudService = inject(MudService);
51+
private readonly isStaticTerminalMode = true;
5152

5253
private readonly terminal: Terminal;
53-
private readonly inputController: MudInputController;
54-
private readonly promptManager: MudPromptManager;
54+
private readonly inputController?: MudInputController;
55+
private readonly promptManager?: MudPromptManager;
5556
private readonly terminalFitAddon = new FitAddon();
56-
private readonly socketAdapter = new MudSocketAdapter(
57-
this.mudService.mudOutput$,
58-
{
59-
transformMessage: (data) => this.transformMudOutput(data),
60-
beforeMessage: (data) => this.beforeMudOutput(data),
61-
afterMessage: (data) => this.afterMudOutput(data),
62-
},
63-
);
64-
private readonly terminalAttachAddon = new AttachAddon(
65-
this.socketAdapter as unknown as WebSocket,
66-
{ bidirectional: false },
67-
);
57+
private readonly socketAdapter?: MudSocketAdapter;
58+
private readonly terminalAttachAddon?: AttachAddon;
6859

6960
private readonly terminalDisposables: IDisposable[] = [];
7061
private readonly resizeObs = new ResizeObserver(() => {
@@ -84,8 +75,12 @@ export class MudClientComponent implements AfterViewInit, OnDestroy {
8475
@ViewChild('hostRef', { static: true })
8576
private readonly terminalRef!: ElementRef<HTMLDivElement>;
8677

87-
protected readonly isConnected$ = this.mudService.connectedToMud$;
88-
protected readonly showEcho$ = this.mudService.showEcho$;
78+
protected readonly isConnected$ = this.isStaticTerminalMode
79+
? of(true)
80+
: this.mudService.connectedToMud$;
81+
protected readonly showEcho$ = this.isStaticTerminalMode
82+
? of(true)
83+
: this.mudService.showEcho$;
8984

9085
/**
9186
* Instantiates the terminal plus helper controllers. All services (input/prompt)
@@ -95,20 +90,32 @@ export class MudClientComponent implements AfterViewInit, OnDestroy {
9590
this.terminal = new Terminal({
9691
fontFamily: 'JetBrainsMono, monospace',
9792
theme: { background: '#000', foreground: '#ccc' },
98-
disableStdin: false,
93+
disableStdin: this.isStaticTerminalMode,
9994
screenReaderMode: true,
10095
});
10196

102-
this.inputController = new MudInputController(
103-
this.terminal,
104-
({ message, echoed }) => this.handleCommittedInput(message, echoed),
105-
);
106-
this.inputController.setLocalEcho(this.state.localEchoEnabled);
107-
108-
this.promptManager = new MudPromptManager(
109-
this.terminal,
110-
this.inputController,
111-
);
97+
if (!this.isStaticTerminalMode) {
98+
this.socketAdapter = new MudSocketAdapter(this.mudService.mudOutput$, {
99+
transformMessage: (data) => this.transformMudOutput(data),
100+
beforeMessage: (data) => this.beforeMudOutput(data),
101+
afterMessage: (data) => this.afterMudOutput(data),
102+
});
103+
this.terminalAttachAddon = new AttachAddon(
104+
this.socketAdapter as unknown as WebSocket,
105+
{ bidirectional: false },
106+
);
107+
108+
this.inputController = new MudInputController(
109+
this.terminal,
110+
({ message, echoed }) => this.handleCommittedInput(message, echoed),
111+
);
112+
this.inputController.setLocalEcho(this.state.localEchoEnabled);
113+
114+
this.promptManager = new MudPromptManager(
115+
this.terminal,
116+
this.inputController,
117+
);
118+
}
112119
}
113120

114121
/**
@@ -118,7 +125,16 @@ export class MudClientComponent implements AfterViewInit, OnDestroy {
118125
ngAfterViewInit() {
119126
this.terminal.open(this.terminalRef.nativeElement);
120127
this.terminal.loadAddon(this.terminalFitAddon);
121-
this.terminal.loadAddon(this.terminalAttachAddon);
128+
this.terminalFitAddon.fit();
129+
this.resizeObs.observe(this.terminalRef.nativeElement);
130+
this.setState({ terminalReady: true });
131+
132+
if (this.isStaticTerminalMode) {
133+
this.renderStaticDemoText();
134+
return;
135+
}
136+
137+
this.terminal.loadAddon(this.terminalAttachAddon!);
122138
this.terminal.focus();
123139

124140
this.terminalDisposables.push(
@@ -133,9 +149,6 @@ export class MudClientComponent implements AfterViewInit, OnDestroy {
133149
this.setLinemode(state),
134150
);
135151

136-
this.resizeObs.observe(this.terminalRef.nativeElement);
137-
this.setState({ terminalReady: true });
138-
139152
const columns = this.terminal.cols;
140153
const rows = this.terminal.rows + 1;
141154

@@ -152,12 +165,16 @@ export class MudClientComponent implements AfterViewInit, OnDestroy {
152165
this.showEchoSubscription?.unsubscribe();
153166
this.linemodeSubscription?.unsubscribe();
154167

155-
this.terminalAttachAddon.dispose();
156-
this.socketAdapter.dispose();
168+
this.terminalAttachAddon?.dispose();
169+
this.socketAdapter?.dispose();
157170
this.terminal.dispose();
158171
}
159172

160173
protected connect() {
174+
if (this.isStaticTerminalMode) {
175+
return;
176+
}
177+
161178
const columns = this.terminal.cols;
162179
const rows = this.terminal.rows;
163180

@@ -170,6 +187,9 @@ export class MudClientComponent implements AfterViewInit, OnDestroy {
170187
*/
171188
private handleTerminalResize() {
172189
this.terminalFitAddon.fit();
190+
if (this.isStaticTerminalMode) {
191+
return;
192+
}
173193

174194
const columns = this.terminal.cols;
175195
const rows = this.terminal.rows;
@@ -199,6 +219,10 @@ export class MudClientComponent implements AfterViewInit, OnDestroy {
199219
* Sends a committed line (or secure string) to the server.
200220
*/
201221
private handleCommittedInput(message: string, echoed: boolean) {
222+
if (this.isStaticTerminalMode) {
223+
return;
224+
}
225+
202226
const payload: string | SecureString = echoed
203227
? message
204228
: { value: message };
@@ -211,6 +235,10 @@ export class MudClientComponent implements AfterViewInit, OnDestroy {
211235
* or through the {@link MudInputController}.
212236
*/
213237
private handleInput(data: string) {
238+
if (!this.inputController) {
239+
return;
240+
}
241+
214242
if (!this.state.isEditMode) {
215243
if (data.length > 0) {
216244
const rewritten = this.rewriteBackspaceToDelete(data);
@@ -232,20 +260,20 @@ export class MudClientComponent implements AfterViewInit, OnDestroy {
232260

233261
if (!state.edit) {
234262
if (wasEditMode) {
235-
const pending = this.inputController.flush();
263+
const pending = this.inputController?.flush();
236264

237265
if (pending) {
238266
this.handleCommittedInput(pending.message, pending.echoed);
239267
}
240268
}
241269

242-
this.inputController.reset();
270+
this.inputController?.reset();
243271
} else if (!wasEditMode) {
244-
this.inputController.reset();
272+
this.inputController?.reset();
245273
}
246274

247275
this.setState({ isEditMode: state.edit });
248-
this.promptManager.reset();
276+
this.promptManager?.reset();
249277
this.updateLocalEcho(this.state.showEcho);
250278
}
251279

@@ -257,28 +285,28 @@ export class MudClientComponent implements AfterViewInit, OnDestroy {
257285
const localEchoEnabled = this.state.isEditMode && showEcho;
258286

259287
this.setState({ showEcho, localEchoEnabled });
260-
this.inputController.setLocalEcho(localEchoEnabled);
288+
this.inputController?.setLocalEcho(localEchoEnabled);
261289
}
262290

263291
/**
264292
* Delegates to the prompt manager so it can temporarily hide the local prompt.
265293
*/
266294
private beforeMudOutput(_data: string) {
267-
this.promptManager.beforeServerOutput(this.getPromptContext());
295+
this.promptManager?.beforeServerOutput(this.getPromptContext());
268296
}
269297

270298
/**
271299
* Restores prompt and user input after the server chunk has been rendered.
272300
*/
273301
private afterMudOutput(data: string) {
274-
this.promptManager.afterServerOutput(data, this.getPromptContext());
302+
this.promptManager?.afterServerOutput(data, this.getPromptContext());
275303
}
276304

277305
/**
278306
* Lets the prompt manager strip redundant CR/LF characters.
279307
*/
280308
private transformMudOutput(data: string): string {
281-
return this.promptManager.transformOutput(data);
309+
return this.promptManager?.transformOutput(data) ?? data;
282310
}
283311

284312
/**
@@ -312,4 +340,20 @@ export class MudClientComponent implements AfterViewInit, OnDestroy {
312340

313341
return data;
314342
}
343+
344+
/**
345+
* Renders a short static sample without connecting to the backend.
346+
*/
347+
private renderStaticDemoText(): void {
348+
this.terminal.writeln('');
349+
this.terminal.writeln('Willkommen zum barrierefreien Testlauf.');
350+
this.terminal.writeln('Die Verbindung zum Server ist deaktiviert.');
351+
this.terminal.writeln(
352+
'Das Terminal zeigt ausschließlich diesen statischen Text an.',
353+
);
354+
this.terminal.writeln('');
355+
this.terminal.writeln(
356+
'Drücken von Tasten hat in diesem Modus keine Wirkung.',
357+
);
358+
}
315359
}

0 commit comments

Comments
 (0)