Skip to content

Commit c63d5f8

Browse files
committed
test(frontend): removed prompt, added echo
1 parent 2c0618e commit c63d5f8

File tree

1 file changed

+23
-11
lines changed

1 file changed

+23
-11
lines changed

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

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import { IDisposable, Terminal } from '@xterm/xterm';
1111
/**
1212
* Lightweight xterm wrapper that is decoupled from the backend and is optimized
1313
* for screen-reader experiments. It renders a static intro text and mirrors any
14-
* user input back to the terminal with a simple prompt (`> `).
14+
* user input back to the terminal, including a delayed echo so assistive tech can
15+
* be tested without talking to the backend.
1516
*/
1617
@Component({
1718
selector: 'app-mud-screenreader-client',
@@ -25,16 +26,16 @@ export class MudScreenreaderClientComponent
2526
private readonly terminal = new Terminal({
2627
fontFamily: 'JetBrainsMono, monospace',
2728
theme: { background: '#000', foreground: '#ccc' },
28-
// cursorBlink: true,
29+
cursorBlink: true,
2930
screenReaderMode: true,
3031
});
3132

3233
private readonly fitAddon = new FitAddon();
3334
private readonly terminalDisposables: IDisposable[] = [];
3435
private readonly resizeObs = new ResizeObserver(() => this.handleResize());
3536

36-
private readonly promptLabel = '> ';
3737
private currentInput = '';
38+
private readonly pendingEchoTimeouts: number[] = [];
3839

3940
@ViewChild('hostRef', { static: true })
4041
private readonly terminalRef!: ElementRef<HTMLDivElement>;
@@ -46,7 +47,6 @@ export class MudScreenreaderClientComponent
4647
this.resizeObs.observe(this.terminalRef.nativeElement);
4748

4849
this.renderStaticIntro();
49-
this.renderPrompt();
5050
this.terminal.focus();
5151

5252
this.terminalDisposables.push(
@@ -56,6 +56,8 @@ export class MudScreenreaderClientComponent
5656

5757
ngOnDestroy(): void {
5858
this.resizeObs.disconnect();
59+
this.pendingEchoTimeouts.forEach((timeoutId) => clearTimeout(timeoutId));
60+
this.pendingEchoTimeouts.length = 0;
5961

6062
this.terminalDisposables.forEach((disposable) => disposable.dispose());
6163
this.terminal.dispose();
@@ -103,21 +105,19 @@ export class MudScreenreaderClientComponent
103105

104106
private commitInput(): void {
105107
this.terminal.write('\r\n');
106-
this.terminal.writeln(`Eingabe: ${this.currentInput}`);
108+
const inputSnapshot = this.currentInput;
109+
this.terminal.writeln(`Eingabe: ${inputSnapshot}`);
110+
this.scheduleEcho(inputSnapshot);
107111
this.currentInput = '';
108-
this.renderPrompt();
109-
}
110-
111-
private renderPrompt(): void {
112-
this.terminal.write(this.promptLabel);
112+
this.terminal.writeln('');
113113
}
114114

115115
private renderStaticIntro(): void {
116116
this.terminal.writeln('Willkommen zum barrierefreien Testlauf.');
117117
this.terminal.writeln('Die Verbindung zum Server ist deaktiviert.');
118118
this.terminal.writeln('');
119119
this.terminal.writeln(
120-
'Tippen Sie Ihre Eingabe nach dem Prompt (>) und bestätigen Sie mit Enter.',
120+
'Tippen Sie Ihre Eingabe und bestaetigen Sie mit Enter.',
121121
);
122122
this.terminal.writeln('');
123123
}
@@ -126,4 +126,16 @@ export class MudScreenreaderClientComponent
126126
const code = char.charCodeAt(0);
127127
return code >= 0x20 && code !== 0x7f;
128128
}
129+
130+
private scheduleEcho(message: string): void {
131+
const timeoutId = window.setTimeout(() => {
132+
this.terminal.writeln(`Echo: ${message}`);
133+
const idx = this.pendingEchoTimeouts.indexOf(timeoutId);
134+
if (idx >= 0) {
135+
this.pendingEchoTimeouts.splice(idx, 1);
136+
}
137+
}, 5000);
138+
139+
this.pendingEchoTimeouts.push(timeoutId);
140+
}
129141
}

0 commit comments

Comments
 (0)