Skip to content

Commit ec4c3c1

Browse files
committed
test(frontend): connected screenreader-test to the mud
1 parent c63d5f8 commit ec4c3c1

File tree

3 files changed

+42
-40
lines changed

3 files changed

+42
-40
lines changed

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

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@ import {
22
AfterViewInit,
33
Component,
44
ElementRef,
5+
inject,
56
OnDestroy,
67
ViewChild,
78
} from '@angular/core';
89
import { FitAddon } from '@xterm/addon-fit';
910
import { IDisposable, Terminal } from '@xterm/xterm';
11+
import { Subscription } from 'rxjs';
12+
13+
import { MudService } from '../../services/mud.service';
1014

1115
/**
12-
* Lightweight xterm wrapper that is decoupled from the backend and is optimized
13-
* for screen-reader experiments. It renders a static intro text and mirrors any
14-
* user input back to the terminal, including a delayed echo so assistive tech can
15-
* be tested without talking to the backend.
16+
* Lightweight xterm wrapper that streams directly to/from the backend for
17+
* screen-reader experiments. It forwards raw server output 1:1 to xterm and
18+
* ships user input to the server on CR, echoing the submitted line locally.
1619
*/
1720
@Component({
1821
selector: 'app-mud-screenreader-client',
@@ -23,6 +26,8 @@ import { IDisposable, Terminal } from '@xterm/xterm';
2326
export class MudScreenreaderClientComponent
2427
implements AfterViewInit, OnDestroy
2528
{
29+
private readonly mudService = inject(MudService);
30+
2631
private readonly terminal = new Terminal({
2732
fontFamily: 'JetBrainsMono, monospace',
2833
theme: { background: '#000', foreground: '#ccc' },
@@ -33,9 +38,9 @@ export class MudScreenreaderClientComponent
3338
private readonly fitAddon = new FitAddon();
3439
private readonly terminalDisposables: IDisposable[] = [];
3540
private readonly resizeObs = new ResizeObserver(() => this.handleResize());
41+
private mudOutputSubscription?: Subscription;
3642

3743
private currentInput = '';
38-
private readonly pendingEchoTimeouts: number[] = [];
3944

4045
@ViewChild('hostRef', { static: true })
4146
private readonly terminalRef!: ElementRef<HTMLDivElement>;
@@ -46,25 +51,37 @@ export class MudScreenreaderClientComponent
4651
this.fitAddon.fit();
4752
this.resizeObs.observe(this.terminalRef.nativeElement);
4853

49-
this.renderStaticIntro();
54+
this.mudOutputSubscription = this.mudService.mudOutput$.subscribe(
55+
({ data }) => this.terminal.write(data),
56+
);
57+
5058
this.terminal.focus();
5159

5260
this.terminalDisposables.push(
5361
this.terminal.onData((data) => this.handleInput(data)),
5462
);
63+
64+
this.connectToBackend();
5565
}
5666

5767
ngOnDestroy(): void {
5868
this.resizeObs.disconnect();
59-
this.pendingEchoTimeouts.forEach((timeoutId) => clearTimeout(timeoutId));
60-
this.pendingEchoTimeouts.length = 0;
6169

70+
this.mudOutputSubscription?.unsubscribe();
6271
this.terminalDisposables.forEach((disposable) => disposable.dispose());
72+
this.mudService.disconnect();
6373
this.terminal.dispose();
6474
}
6575

6676
private handleResize(): void {
6777
this.fitAddon.fit();
78+
79+
const columns = this.terminal.cols;
80+
const rows = this.terminal.rows;
81+
82+
if (Number.isFinite(columns) && Number.isFinite(rows)) {
83+
this.mudService.updateViewportSize(columns, rows);
84+
}
6885
}
6986

7087
private handleInput(data: string): void {
@@ -104,38 +121,25 @@ export class MudScreenreaderClientComponent
104121
}
105122

106123
private commitInput(): void {
107-
this.terminal.write('\r\n');
124+
// this.terminal.write('\r\n');
108125
const inputSnapshot = this.currentInput;
109-
this.terminal.writeln(`Eingabe: ${inputSnapshot}`);
110-
this.scheduleEcho(inputSnapshot);
126+
// this.terminal.writeln(`Eingabe: ${inputSnapshot}`);
127+
if (inputSnapshot.length > 0) {
128+
this.mudService.sendMessage(inputSnapshot);
129+
}
111130
this.currentInput = '';
112131
this.terminal.writeln('');
113132
}
114133

115-
private renderStaticIntro(): void {
116-
this.terminal.writeln('Willkommen zum barrierefreien Testlauf.');
117-
this.terminal.writeln('Die Verbindung zum Server ist deaktiviert.');
118-
this.terminal.writeln('');
119-
this.terminal.writeln(
120-
'Tippen Sie Ihre Eingabe und bestaetigen Sie mit Enter.',
121-
);
122-
this.terminal.writeln('');
123-
}
124-
125134
private isPrintable(char: string): boolean {
126135
const code = char.charCodeAt(0);
127136
return code >= 0x20 && code !== 0x7f;
128137
}
129138

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);
139+
private connectToBackend(): void {
140+
const columns = this.terminal.cols;
141+
const rows = this.terminal.rows;
138142

139-
this.pendingEchoTimeouts.push(timeoutId);
143+
this.mudService.connect({ columns, rows });
140144
}
141145
}

frontend/src/app/features/sockets/sockets.service.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export class SocketsService {
4747
this.sessionId = this.resolveSessionId();
4848
this.storageKey = this.buildOutputStorageKey(this.sessionId);
4949

50-
this.storedOutputCache = this.restoreStoredOutputs();
50+
// this.storedOutputCache = this.restoreStoredOutputs();
5151
this.skipDuplicateOutputsQueue = [...this.storedOutputCache];
5252

5353
const socketUrl = serverConfigService.getBackendUrl();
@@ -385,10 +385,7 @@ export class SocketsService {
385385
outputs.length - SocketsService.OUTPUT_STORAGE_LIMIT,
386386
);
387387

388-
this.localStorageRef.setItem(
389-
this.storageKey,
390-
JSON.stringify(trimmed),
391-
);
388+
this.localStorageRef.setItem(this.storageKey, JSON.stringify(trimmed));
392389

393390
return trimmed;
394391
}

frontend/src/main.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { enableProdMode } from '@angular/core';
1+
import { enableProdMode, inject, provideAppInitializer } from '@angular/core';
22

33
import { environment } from './environments/environment';
44
import {
@@ -7,6 +7,7 @@ import {
77
} from '@angular/common/http';
88
import { bootstrapApplication } from '@angular/platform-browser';
99
import { AppComponent } from './app/app.component';
10+
import { ServerConfigService } from 'src/app/features/serverconfig/server-config.service';
1011

1112
if (environment.production) {
1213
enableProdMode();
@@ -15,10 +16,10 @@ if (environment.production) {
1516
bootstrapApplication(AppComponent, {
1617
providers: [
1718
provideHttpClient(withInterceptorsFromDi()),
18-
// provideAppInitializer(() => {
19-
// const config = inject(ServerConfigService);
19+
provideAppInitializer(() => {
20+
const config = inject(ServerConfigService);
2021

21-
// return config.load();
22-
// }),
22+
return config.load();
23+
}),
2324
],
2425
}).catch((err) => console.error(err));

0 commit comments

Comments
 (0)