Adrià Vilanova Martínez | 0d92a0c | 2023-11-06 01:37:20 +0100 | [diff] [blame] | 1 | import {waitFor} from 'poll-until-promise'; |
| 2 | |
| 3 | import {shouldImplement} from '../../../../common/commonUtils.js'; |
| 4 | |
| 5 | import BaseInfoHandler from './base.js'; |
| 6 | |
| 7 | export 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ínez | 4b2582d | 2023-11-16 01:56:04 +0100 | [diff] [blame] | 56 | this.updateInfoWithNewValue(e); |
Adrià Vilanova Martínez | 0d92a0c | 2023-11-06 01:37:20 +0100 | [diff] [blame] | 57 | }); |
| 58 | } |
| 59 | |
Adrià Vilanova Martínez | 4b2582d | 2023-11-16 01:56:04 +0100 | [diff] [blame] | 60 | /** |
| 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ínez | 0d92a0c | 2023-11-06 01:37:20 +0100 | [diff] [blame] | 74 | 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 | } |