blob: 30bb36d866f018fbe41e48d05f1b405badcae1d5 [file] [log] [blame]
Adrià Vilanova Martínez0d92a0c2023-11-06 01:37:20 +01001import {waitFor} from 'poll-until-promise';
2
3import {shouldImplement} from '../../../../common/commonUtils.js';
4
5import BaseInfoHandler from './base.js';
6
7export default class ResponseEventBasedInfoHandler extends BaseInfoHandler {
8 constructor() {
9 super();
10
11 if (this.constructor == ResponseEventBasedInfoHandler) {
12 throw new Error('The base class cannot be instantiated.');
13 }
14
15 this.setUpDefaultInfoValue();
16 this.setUpEventHandler();
17 }
18
19 /**
20 * Should return the name of the XHR interceptor event for the API response
21 * which has the information being handled.
22 */
23 getEvent() {
24 shouldImplement('getEvent');
25 }
26
27 /**
28 * This function should return a promise which resolves to a boolean
29 * specifying whether this.info is the information related to the view that
30 * the user is currently on.
31 */
32 async isInfoCurrent(_injectionDetails) {
33 shouldImplement('isInfoCurrent');
34 }
35
36 /**
37 * Should return the options for the waitFor function which is called when
38 * checking whether the information is current or not.
39 */
40 getWaitForCurrentInfoOptions() {
41 shouldImplement('getWaitForCurrentInfoOptions');
42 }
43
44 setUpDefaultInfoValue() {
45 this.info = {
46 body: {},
47 id: -1,
48 timestamp: 0,
49 };
50 }
51
52 setUpEventHandler() {
53 window.addEventListener(this.getEvent(), e => {
54 if (e.detail.id < this.info.id) return;
55
Adrià Vilanova Martínez4b2582d2023-11-16 01:56:04 +010056 this.updateInfoWithNewValue(e);
Adrià Vilanova Martínez0d92a0c2023-11-06 01:37:20 +010057 });
58 }
59
Adrià Vilanova Martínez4b2582d2023-11-16 01:56:04 +010060 /**
61 * Updates the info value with the information obtained from an event.
62 * Can be overriden to implement more advanced logic.
63 *
64 * @param {Event} e
65 */
66 updateInfoWithNewValue(e) {
67 this.info = {
68 body: e.detail.body,
69 id: e.detail.id,
70 timestamp: Date.now(),
71 };
72 }
73
Adrià Vilanova Martínez0d92a0c2023-11-06 01:37:20 +010074 async getCurrentInfo(injectionDetails) {
75 const options = this.getWaitForCurrentInfoOptions();
76 return waitFor(
77 () => this.attemptToGetCurrentInfo(injectionDetails), options);
78 }
79
80 async attemptToGetCurrentInfo(injectionDetails) {
81 const isInfoCurrent = await this.isInfoCurrent(injectionDetails);
82 if (!isInfoCurrent) throw new Error('Didn\'t receive current information');
83
84 return this.info;
85 }
86}