From 993703012f86ec3ffd89686dbb3a03a24432aac7 Mon Sep 17 00:00:00 2001 From: Andre Lammers <andre.lammers@mni.thm.de> Date: Tue, 17 Sep 2019 11:54:05 +0200 Subject: [PATCH] Added extended live-announcer function for all sites (hidden button) home-page, all room-pages, comment-page, moderation-page, user-page --- .../home/user-home/user-home.component.html | 1 + .../home/user-home/user-home.component.ts | 10 +++++--- .../moderator-comment-page.component.html | 6 ++--- .../moderator-comment-page.component.ts | 21 ++++++++++++++--- .../room-moderator-page.component.html | 3 ++- .../room-moderator-page.component.ts | 23 +++++++++++++++---- .../room-participant-page.component.html | 1 + .../room-participant-page.component.ts | 13 +++++++---- .../comment-page/comment-page.component.html | 1 + .../comment-page/comment-page.component.ts | 10 +++++--- src/assets/i18n/creator/de.json | 4 +++- src/assets/i18n/creator/en.json | 4 +++- src/assets/i18n/home/de.json | 1 + src/assets/i18n/home/en.json | 1 + src/assets/i18n/participant/de.json | 2 ++ src/assets/i18n/participant/en.json | 2 ++ 16 files changed, 79 insertions(+), 24 deletions(-) diff --git a/src/app/components/home/user-home/user-home.component.html b/src/app/components/home/user-home/user-home.component.html index 91368fa40..ed885a33c 100644 --- a/src/app/components/home/user-home/user-home.component.html +++ b/src/app/components/home/user-home/user-home.component.html @@ -12,5 +12,6 @@ <div fxLayout="row" fxLayoutAlign="center" fxLayoutGap="15px"> <app-room-list [user]="user"></app-room-list> </div> + <button id="live_announcer-button" tabIndex="-1" (click)="announce()" class="visually-hidden">{{ 'home-page.live-announcer-user' | translate }}</button> </div> diff --git a/src/app/components/home/user-home/user-home.component.ts b/src/app/components/home/user-home/user-home.component.ts index 441d46319..0a1769e1a 100644 --- a/src/app/components/home/user-home/user-home.component.ts +++ b/src/app/components/home/user-home/user-home.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, OnDestroy, Renderer2 } from '@angular/core'; +import { Component, OnInit, OnDestroy, Renderer2, AfterContentInit } from '@angular/core'; import { MatDialog } from '@angular/material'; import { TranslateService } from '@ngx-translate/core'; import { LanguageService } from '../../../services/util/language.service'; @@ -16,7 +16,7 @@ import { KeyboardKey } from '../../../utils/keyboard/keys'; templateUrl: './user-home.component.html', styleUrls: [ './user-home.component.scss' ] }) -export class UserHomeComponent implements OnInit, OnDestroy { +export class UserHomeComponent implements OnInit, OnDestroy, AfterContentInit { user: User; creatorRole: UserRole = UserRole.CREATOR; participantRole: UserRole = UserRole.PARTICIPANT; @@ -35,10 +35,14 @@ export class UserHomeComponent implements OnInit, OnDestroy { langService.langEmitter.subscribe(lang => translateService.use(lang)); } + ngAfterContentInit(): void { + setTimeout( () => { + document.getElementById('live_announcer-button').focus(); + }, 700); + } ngOnInit() { this.translateService.use(localStorage.getItem('currentLang')); this.authenticationService.watchUser.subscribe(newUser => this.user = newUser); - this.announce(); this.listenerFn = this._r.listen(document, 'keyup', (event) => { if (KeyboardUtils.isKeyEvent(event, KeyboardKey.Digit1) === true && this.eventService.focusOnInput === false) { document.getElementById('session_id-input').focus(); diff --git a/src/app/components/moderator/moderator-comment-page/moderator-comment-page.component.html b/src/app/components/moderator/moderator-comment-page/moderator-comment-page.component.html index 7bf34b687..8777583be 100644 --- a/src/app/components/moderator/moderator-comment-page/moderator-comment-page.component.html +++ b/src/app/components/moderator/moderator-comment-page/moderator-comment-page.component.html @@ -2,6 +2,6 @@ <div fxLayout="row" fxLayoutAlign="center"> <app-moderator-comment-list [user]="user" [roomId]="roomId" comments></app-moderator-comment-list> </div> - </div> - - \ No newline at end of file + <button id="live_announcer-button" tabIndex="-1" (click)="announce()" class="visually-hidden">{{ 'comment-page.live-announcer-moderation' | translate }}</button> +</div> + diff --git a/src/app/components/moderator/moderator-comment-page/moderator-comment-page.component.ts b/src/app/components/moderator/moderator-comment-page/moderator-comment-page.component.ts index c657955ae..4dc7a408a 100644 --- a/src/app/components/moderator/moderator-comment-page/moderator-comment-page.component.ts +++ b/src/app/components/moderator/moderator-comment-page/moderator-comment-page.component.ts @@ -1,25 +1,40 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, AfterContentInit, Renderer2 } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { User } from '../../../models/user'; import { NotificationService } from '../../../services/util/notification.service'; import { AuthenticationService } from '../../../services/http/authentication.service'; +import { LiveAnnouncer } from '@angular/cdk/a11y'; +import { EventService } from '../../../services/util/event.service'; @Component({ selector: 'app-moderator-comment-page', templateUrl: './moderator-comment-page.component.html', styleUrls: ['./moderator-comment-page.component.scss'] }) -export class ModeratorCommentPageComponent implements OnInit { +export class ModeratorCommentPageComponent implements OnInit, AfterContentInit { roomId: string; user: User; constructor(private route: ActivatedRoute, private notification: NotificationService, - private authenticationService: AuthenticationService) { } + private authenticationService: AuthenticationService, + private liveAnnouncer: LiveAnnouncer, + private _r: Renderer2, + public eventService: EventService) { } + ngAfterContentInit(): void { + setTimeout( () => { + document.getElementById('live_announcer-button').focus(); + }, 500); + } ngOnInit(): void { this.roomId = localStorage.getItem('roomId'); this.user = this.authenticationService.getUser(); } + public announce() { + this.liveAnnouncer.clear(); + this.liveAnnouncer.announce('', 'assertive'); + } + } diff --git a/src/app/components/moderator/room-moderator-page/room-moderator-page.component.html b/src/app/components/moderator/room-moderator-page/room-moderator-page.component.html index 66fa3bc4c..77c3d19ff 100644 --- a/src/app/components/moderator/room-moderator-page/room-moderator-page.component.html +++ b/src/app/components/moderator/room-moderator-page/room-moderator-page.component.html @@ -57,4 +57,5 @@ </mat-card> </div> - </div> + <button id="live_announcer-button" tabIndex="-1" (click)="announce()" class="visually-hidden">{{ 'room-page.live-announcer' | translate }}</button> +</div> diff --git a/src/app/components/moderator/room-moderator-page/room-moderator-page.component.ts b/src/app/components/moderator/room-moderator-page/room-moderator-page.component.ts index b123e904f..7515c835c 100644 --- a/src/app/components/moderator/room-moderator-page/room-moderator-page.component.ts +++ b/src/app/components/moderator/room-moderator-page/room-moderator-page.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, AfterContentInit, Renderer2 } from '@angular/core'; import { Room } from '../../../models/room'; import { RoomPageComponent } from '../../shared/room-page/room-page.component'; import { Location } from '@angular/common'; @@ -10,13 +10,15 @@ import { WsCommentServiceService } from '../../../services/websockets/ws-comment import { CommentService } from '../../../services/http/comment.service'; import { Message } from '@stomp/stompjs'; import { NotificationService } from '../../../services/util/notification.service'; +import { LiveAnnouncer } from '@angular/cdk/a11y'; +import { EventService } from '../../../services/util/event.service'; @Component({ selector: 'app-room-moderator-page', templateUrl: './room-moderator-page.component.html', styleUrls: ['./room-moderator-page.component.scss'] }) -export class RoomModeratorPageComponent extends RoomPageComponent implements OnInit { +export class RoomModeratorPageComponent extends RoomPageComponent implements OnInit, AfterContentInit { room: Room; isLoading = true; @@ -24,7 +26,6 @@ export class RoomModeratorPageComponent extends RoomPageComponent implements OnI moderatorCommentCounter: number; viewModuleCount = 1; - constructor(protected location: Location, protected roomService: RoomService, protected route: ActivatedRoute, @@ -32,7 +33,10 @@ export class RoomModeratorPageComponent extends RoomPageComponent implements OnI protected langService: LanguageService, protected wsCommentService: WsCommentServiceService, protected commentService: CommentService, - protected notification: NotificationService) { + protected notification: NotificationService, + private liveAnnouncer: LiveAnnouncer, + private _r: Renderer2, + public eventService: EventService) { super(roomService, route, location, wsCommentService, commentService); langService.langEmitter.subscribe(lang => translateService.use(lang)); } @@ -83,6 +87,12 @@ export class RoomModeratorPageComponent extends RoomPageComponent implements OnI }); } + ngAfterContentInit(): void { + setTimeout( () => { + document.getElementById('live_announcer-button').focus(); + }, 700); + } + ngOnInit() { window.scroll(0, 0); this.route.params.subscribe(params => { @@ -107,4 +117,9 @@ export class RoomModeratorPageComponent extends RoomPageComponent implements OnI this.notification.show(msg, '', { duration: 2000 }); }); } + + public announce() { + this.liveAnnouncer.clear(); + this.liveAnnouncer.announce('', 'assertive'); + } } diff --git a/src/app/components/participant/room-participant-page/room-participant-page.component.html b/src/app/components/participant/room-participant-page/room-participant-page.component.html index a34bbfaca..1fb712bf0 100644 --- a/src/app/components/participant/room-participant-page/room-participant-page.component.html +++ b/src/app/components/participant/room-participant-page/room-participant-page.component.html @@ -48,6 +48,7 @@ </mat-card> </div> + <button id="live_announcer-button" tabIndex="-1" (click)="announce()" class="visually-hidden">{{ 'room-page.live-announcer' | translate }}</button> </div> <!--Hidden Div's for a11y-Descriptions--> diff --git a/src/app/components/participant/room-participant-page/room-participant-page.component.ts b/src/app/components/participant/room-participant-page/room-participant-page.component.ts index 71705d561..78912bb65 100644 --- a/src/app/components/participant/room-participant-page/room-participant-page.component.ts +++ b/src/app/components/participant/room-participant-page/room-participant-page.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, OnDestroy, Renderer2 } from '@angular/core'; +import { Component, OnInit, OnDestroy, Renderer2, AfterContentInit } from '@angular/core'; import { Room } from '../../../models/room'; import { User } from '../../../models/user'; import { UserRole } from '../../../models/user-roles.enum'; @@ -21,7 +21,7 @@ import { KeyboardKey } from '../../../utils/keyboard/keys'; templateUrl: './room-participant-page.component.html', styleUrls: ['./room-participant-page.component.scss'] }) -export class RoomParticipantPageComponent extends RoomPageComponent implements OnInit, OnDestroy { +export class RoomParticipantPageComponent extends RoomPageComponent implements OnInit, OnDestroy, AfterContentInit { room: Room; isLoading = true; @@ -45,14 +45,18 @@ export class RoomParticipantPageComponent extends RoomPageComponent implements O langService.langEmitter.subscribe(lang => translateService.use(lang)); } + ngAfterContentInit(): void { + setTimeout( () => { + document.getElementById('live_announcer-button').focus(); + }, 700); + } + ngOnInit() { window.scroll(0, 0); this.route.params.subscribe(params => { this.initializeRoom(params['roomId']); }); this.translateService.use(localStorage.getItem('currentLang')); - this.announce(); - this.listenerFn = this._r.listen(document, 'keyup', (event) => { if (KeyboardUtils.isKeyEvent(event, KeyboardKey.Digit1) === true && this.eventService.focusOnInput === false) { document.getElementById('question_answer-button').focus(); @@ -76,7 +80,6 @@ export class RoomParticipantPageComponent extends RoomPageComponent implements O } public announce() { - // this.liveAnnouncer.announce('Willkommen auf dieser Seite' + document.getElementById('announcer_text').textContent, 'assertive'); this.liveAnnouncer.clear(); this.liveAnnouncer.announce('Du befindest dich in der Sitzung mit dem von dir eingegebenen Sitzungs-Code. ' + 'Drücke die Taste 1 um eine Frage zu stellen, die Taste 2 für das Sitzungs-Menü, ' + diff --git a/src/app/components/shared/comment-page/comment-page.component.html b/src/app/components/shared/comment-page/comment-page.component.html index 6f6989296..091077689 100644 --- a/src/app/components/shared/comment-page/comment-page.component.html +++ b/src/app/components/shared/comment-page/comment-page.component.html @@ -1,6 +1,7 @@ <div fxLayout="column" fxLayoutAlign="center" fxLayoutGap="20px"> <div fxLayout="row" fxLayoutAlign="center"> <app-comment-list [user]="user" [roomId]="roomId" comments></app-comment-list> + <button id="live_announcer-button" tabIndex="-1" (click)="announce()" class="visually-hidden">{{ 'comment-page.live-announcer' | translate }}</button> </div> </div> diff --git a/src/app/components/shared/comment-page/comment-page.component.ts b/src/app/components/shared/comment-page/comment-page.component.ts index 4a12619d9..d9bb46b0e 100644 --- a/src/app/components/shared/comment-page/comment-page.component.ts +++ b/src/app/components/shared/comment-page/comment-page.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, OnDestroy, Renderer2 } from '@angular/core'; +import { Component, OnInit, OnDestroy, Renderer2, AfterContentInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { User } from '../../../models/user'; import { NotificationService } from '../../../services/util/notification.service'; @@ -14,7 +14,7 @@ import { Room } from '../../../models/room'; templateUrl: './comment-page.component.html', styleUrls: ['./comment-page.component.scss'] }) -export class CommentPageComponent implements OnInit, OnDestroy { +export class CommentPageComponent implements OnInit, OnDestroy, AfterContentInit { roomId: string; room: Room; user: User; @@ -28,10 +28,14 @@ export class CommentPageComponent implements OnInit, OnDestroy { private liveAnnouncer: LiveAnnouncer, private _r: Renderer2) { } + ngAfterContentInit(): void { + setTimeout( () => { + document.getElementById('live_announcer-button').focus(); + }, 500); + } ngOnInit(): void { this.roomId = localStorage.getItem('roomId'); this.user = this.authenticationService.getUser(); - this.announce(); this.listenerFn = this._r.listen(document, 'keyup', (event) => { if (KeyboardUtils.isKeyEvent(event, KeyboardKey.Digit1) === true && this.eventService.focusOnInput === false) { if (document.getElementById('add_comment-button')) { diff --git a/src/assets/i18n/creator/de.json b/src/assets/i18n/creator/de.json index bf4e816db..b2bc08d4b 100644 --- a/src/assets/i18n/creator/de.json +++ b/src/assets/i18n/creator/de.json @@ -61,6 +61,8 @@ "error-title": "Bitte gib einen Titel ein.", "export": "Exportieren", "export-description": "Exportieren", + "live-announcer": "Du befindest dich jetzt auf der Fragen-Seite. Um Informationen zu Tastenkombinationen zu erhalten drücke jetzt die Enter-Taste oder rufe die Ansage zu einem späteren Zeitpunkt mit der Escape-Taste auf.", + "live-announcer-moderation": "Du befindest dich jetzt auf der Moderations-Seite. Um Informationen zu Tastenkombinationen zu erhalten drücke jetzt die Enter-Taste oder rufe die Ansage zu einem späteren Zeitpunkt mit der Escape-Taste auf.", "mark-correct": "Frage bejahen", "mark-favorite": "Als Kandidat für einen Bonus markieren", "mark-not-correct": "Frage nicht bejahen", @@ -158,7 +160,7 @@ "email-error": "E-Mail Adresse ist ungültig.", "export-comments": "Fragen exportieren", "general": "Sitzung", - "live-announcer": "Du befindest dich in der von dir erstellten Sitzung. Um Informationen zu Tastenkombinationen zu erhalten drücke jetzt die Enter-Taste oder rufe die Ansage zu einem späteren Zeitpunkt mit der Escape-Taste auf.", + "live-announcer": "Du befindest dich jetzt in der Sitzung. Um Informationen zu Tastenkombinationen zu erhalten drücke jetzt die Enter-Taste oder rufe die Ansage zu einem späteren Zeitpunkt mit der Escape-Taste auf.", "live-feedback": "Live Feedback", "moderating-stream": "Moderation", "moderator-added": "Moderator wurde hinzugefügt.", diff --git a/src/assets/i18n/creator/en.json b/src/assets/i18n/creator/en.json index 7c50db68d..1318ed43e 100644 --- a/src/assets/i18n/creator/en.json +++ b/src/assets/i18n/creator/en.json @@ -62,6 +62,8 @@ "error-title": "Please enter a title.", "export": "Export", "export-description": "Export", + "live-announcer": "You are now on the questions page. To get information about key combinations press the Enter key or call the announcement later with the Escape key.", + "live-announcer-moderation": "You are now on the moderation page. To get information about key combinations press the Enter key or call the announcement later with the Escape key.", "mark-correct": "Mark as correct", "mark-favorite": "Mark as bonus question", "mark-not-correct": "Mark not as correct", @@ -159,7 +161,7 @@ "email-error": "E-Mail is invalid.", "export-comments": "Export questions", "general": "Session", - "live-announcer": "You're in the session you created. To get information about key combinations press the Enter key or call the announcement later with the Escape key.", + "live-announcer": "You're in the session now. To get information about key combinations press the Enter key or call the announcement later with the Escape key.", "live-feedback": "Live feedback", "moderating-stream": "Moderation", "moderator-added": "Moderator was added.", diff --git a/src/assets/i18n/home/de.json b/src/assets/i18n/home/de.json index 209cb5a25..6bf7166ae 100644 --- a/src/assets/i18n/home/de.json +++ b/src/assets/i18n/home/de.json @@ -82,6 +82,7 @@ "created-2": "' wurde erstellt.", "exactly-8": "Der Sitzungs-Code ist eine Kombination aus genau 8 Ziffern.", "live-announcer": "Willkommen auf der Seite fragpunktjetzt. Um Informationen zu Tastenkombinationen zu erhalten drücke jetzt die Enter-Taste oder rufe die Ansage zu einem späteren Zeitpunkt mit der Escape-Taste auf.", + "live-announcer-user": "Du befindest dich jetzt auf der Benutzer-Seite. Um Informationen zu Tastenkombinationen zu erhalten drücke jetzt die Enter-Taste oder rufe die Ansage zu einem späteren Zeitpunkt mit der Escape-Taste auf.", "install": "Installieren", "no-empty-name": "Bitte gib einen Namen für die Sitzung ein.", "no-room-found": "Es wurde keine Sitzung mit diesem Code gefunden.", diff --git a/src/assets/i18n/home/en.json b/src/assets/i18n/home/en.json index 5aaa64fcf..23061d43e 100644 --- a/src/assets/i18n/home/en.json +++ b/src/assets/i18n/home/en.json @@ -83,6 +83,7 @@ "created-2": "' successfully created", "exactly-8": "A session ID has exactly 8 digits.", "live-announcer": "Welcome to fragpunktjetzt. To get information about key combinations press the Enter key or call the announcement later with the Escape key.", + "live-announcer-user": "You are now on the user page. To get information about key combinations press the Enter key or call the announcement later with the Escape key.", "install": "Install", "no-empty-name": "Please enter a name.", "no-room-found": "No session found with this key", diff --git a/src/assets/i18n/participant/de.json b/src/assets/i18n/participant/de.json index 4306a30c3..f9ac08f72 100644 --- a/src/assets/i18n/participant/de.json +++ b/src/assets/i18n/participant/de.json @@ -58,6 +58,7 @@ "error-both-fields": "Bitte fülle alle Felder aus.", "error-comment": "Bitte gib deine Frage ein.", "error-title": "Bitte gib einen Titel ein.", + "live-announcer": "Du befindest dich jetzt auf der Fragen-Seite. Um Informationen zu Tastenkombinationen zu erhalten drücke jetzt die Enter-Taste oder rufe die Ansage zu einem späteren Zeitpunkt mit der Escape-Taste auf.", "mark-not-correct": "Dozent hat die Frage bejaht.", "mark-not-favorite": "Bonus-Frage: Dozent hält die Frage für besonders interessant.", "mark-not-wrong": "Dozent hat die Frage verneint", @@ -85,6 +86,7 @@ "description": "Beschreibung der Sitzung", "give-feedback": "Feedback geben", "learn": "Lernen", + "live-announcer": "Du befindest dich jetzt in der Sitzung. Um Informationen zu Tastenkombinationen zu erhalten drücke jetzt die Enter-Taste oder rufe die Ansage zu einem späteren Zeitpunkt mit der Escape-Taste auf.", "live-feedback": "Live Feedback", "session-id": "Code" }, diff --git a/src/assets/i18n/participant/en.json b/src/assets/i18n/participant/en.json index 079ea15c7..acc3ee0ce 100644 --- a/src/assets/i18n/participant/en.json +++ b/src/assets/i18n/participant/en.json @@ -58,6 +58,7 @@ "error-both-fields": "Please fill in all fields.", "error-comment": "Please enter a question.", "error-title": "Please enter a title.", + "live-announcer": "You are now on the questions page. To get information about key combinations press the Enter key or call the announcement later with the Escape key.", "mark-not-correct": "Marked as correct by the professor", "mark-not-favorite": "Bonus question: Your professor intends to give a bonus for that question.", "mark-not-wrong": "Marked as wrong by the professor", @@ -85,6 +86,7 @@ "description": "Description", "give-feedback": "Give feedback", "learn": "Learn", + "live-announcer": "You're in the session now. To get information about key combinations press the Enter key or call the announcement later with the Escape key.", "live-feedback": "Live feedback", "session-id": "Key" }, -- GitLab