Skip to content

Commit c1fa52e

Browse files
committed
118220: Store messages with ID so clears can be targeted
1 parent 35d29c8 commit c1fa52e

2 files changed

Lines changed: 57 additions & 16 deletions

File tree

src/app/shared/live-region/live-region.service.spec.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import { LiveRegionService } from './live-region.service';
22
import { fakeAsync, tick, flush } from '@angular/core/testing';
3+
import { UUIDService } from '../../core/shared/uuid.service';
34

45
describe('liveRegionService', () => {
56
let service: LiveRegionService;
67

7-
88
beforeEach(() => {
9-
service = new LiveRegionService();
9+
service = new LiveRegionService(
10+
new UUIDService(),
11+
);
1012
});
1113

1214
describe('addMessage', () => {
@@ -85,6 +87,34 @@ describe('liveRegionService', () => {
8587
expect(results[3]).toEqual([]);
8688
}));
8789

90+
it('should not pop messages added after clearing within timeOut period', fakeAsync(() => {
91+
const results: string[][] = [];
92+
93+
service.getMessages$().subscribe((messages) => {
94+
results.push(messages);
95+
});
96+
97+
expect(results.length).toEqual(1);
98+
expect(results[0]).toEqual([]);
99+
100+
service.addMessage('Message One');
101+
tick(10000);
102+
service.clear();
103+
tick(15000);
104+
service.addMessage('Message Two');
105+
106+
// Message Two should not be cleared after 5 more seconds
107+
tick(5000);
108+
109+
expect(results.length).toEqual(4);
110+
expect(results[3]).toEqual(['Message Two']);
111+
112+
// But should be cleared 30 seconds after it was added
113+
tick(25000);
114+
expect(results.length).toEqual(5);
115+
expect(results[4]).toEqual([]);
116+
}));
117+
88118
it('should respect configured timeOut', fakeAsync(() => {
89119
const results: string[][] = [];
90120

src/app/shared/live-region/live-region.service.ts

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,30 @@
11
import { Injectable } from '@angular/core';
22
import { BehaviorSubject } from 'rxjs';
33
import { environment } from '../../../environments/environment';
4+
import { UUIDService } from '../../core/shared/uuid.service';
45

56
@Injectable({
67
providedIn: 'root',
78
})
89
export class LiveRegionService {
910

11+
constructor(
12+
protected uuidService: UUIDService,
13+
) {
14+
}
15+
1016
/**
1117
* The duration after which the messages disappear in milliseconds
1218
* @protected
1319
*/
1420
protected messageTimeOutDurationMs: number = environment.liveRegion.messageTimeOutDurationMs;
1521

1622
/**
17-
* Array containing the messages that should be shown in the live region
23+
* Array containing the messages that should be shown in the live region,
24+
* together with a uuid, so they can be uniquely identified
1825
* @protected
1926
*/
20-
protected messages: string[] = [];
27+
protected messages: { message: string, uuid: string }[] = [];
2128

2229
/**
2330
* BehaviorSubject emitting the array with messages every time the array updates
@@ -34,27 +41,28 @@ export class LiveRegionService {
3441
/**
3542
* Returns a copy of the array with the current live region messages
3643
*/
37-
getMessages() {
38-
return [...this.messages];
44+
getMessages(): string[] {
45+
return this.messages.map(messageObj => messageObj.message);
3946
}
4047

4148
/**
4249
* Returns the BehaviorSubject emitting the array with messages every time the array updates
4350
*/
44-
getMessages$() {
51+
getMessages$(): BehaviorSubject<string[]> {
4552
return this.messages$;
4653
}
4754

4855
/**
4956
* Adds a message to the live-region messages array
5057
* @param message
58+
* @return The uuid of the message
5159
*/
52-
addMessage(message: string) {
53-
this.messages.push(message);
60+
addMessage(message: string): string {
61+
const uuid = this.uuidService.generate();
62+
this.messages.push({ message, uuid });
63+
setTimeout(() => this.clearMessageByUUID(uuid), this.messageTimeOutDurationMs);
5464
this.emitCurrentMessages();
55-
56-
// Clear the message once the timeOut has passed
57-
setTimeout(() => this.pop(), this.messageTimeOutDurationMs);
65+
return uuid;
5866
}
5967

6068
/**
@@ -66,12 +74,15 @@ export class LiveRegionService {
6674
}
6775

6876
/**
69-
* Removes the longest living message from the array.
77+
* Removes the message with the given UUID from the messages array
78+
* @param uuid The uuid of the message to clear
7079
* @protected
7180
*/
72-
protected pop() {
73-
if (this.messages.length > 0) {
74-
this.messages.shift();
81+
clearMessageByUUID(uuid: string) {
82+
const index = this.messages.findIndex(messageObj => messageObj.uuid === uuid);
83+
84+
if (index !== -1) {
85+
this.messages.splice(index, 1);
7586
this.emitCurrentMessages();
7687
}
7788
}

0 commit comments

Comments
 (0)