blob: 6c8fb736b70fcdc966e9531eb03e11e17cffcc90 [file] [log] [blame]
Adrià Vilanova Martínezf4afd5a2023-12-02 11:32:57 +01001import {waitFor} from 'poll-until-promise';
2
Adrià Vilanova Martínez19f6a652023-11-15 19:38:50 +01003import {parseUrl} from '../../../../common/commonUtils.js';
4import ThreadModel from '../../../../models/Thread.js';
5import {kViewThreadResponse} from '../consts.js';
6import MessageExtraInfoService from '../services/message.js';
7
8import ResponseEventBasedInfoHandler from './basedOnResponseEvent.js';
9
10const kIntervalInMs = 500;
Adrià Vilanova Martínezf4afd5a2023-12-02 11:32:57 +010011const kTimeoutInMs = 3 * 1000;
Adrià Vilanova Martínez19f6a652023-11-15 19:38:50 +010012const kCurrentInfoExpiresInMs = kTimeoutInMs * 1.5;
13
14export default class ThreadInfoHandler extends ResponseEventBasedInfoHandler {
Adrià Vilanova Martínez19f6a652023-11-15 19:38:50 +010015 getEvent() {
16 return kViewThreadResponse;
17 }
18
19 getWaitForCurrentInfoOptions() {
20 return {
21 interval: kIntervalInMs,
22 timeout: kTimeoutInMs,
23 };
24 }
25
Adrià Vilanova Martínez4b2582d2023-11-16 01:56:04 +010026 setUpDefaultInfoValue() {
27 this.info = {
28 thread: new ThreadModel(),
29 messages: [],
30 id: -1,
31 timestamp: 0,
32 };
33 }
Adrià Vilanova Martínez19f6a652023-11-15 19:38:50 +010034
Adrià Vilanova Martínez4b2582d2023-11-16 01:56:04 +010035 updateInfoWithNewValue(e) {
36 const newThread = new ThreadModel(e.detail.body?.[1]);
37 if (newThread.getId() != this.info.thread.getId()) {
38 this.info.messages = [];
39 }
40
41 const newMessages = newThread.getAllMessagesList();
42 this.updateRecordedMessages(newMessages);
43
44 this.info.thread = newThread;
45 this.info.id = e.detail.id;
46 this.info.timestamp = Date.now();
47 }
48
49 updateRecordedMessages(newMessages) {
50 const nonUpdatedMessages = this.info.messages.filter(message => {
51 return !newMessages.some(newMessage => {
52 return message.getId() == newMessage.getId();
53 });
54 });
55 this.info.messages = nonUpdatedMessages.concat(newMessages);
56 }
57
Adrià Vilanova Martínezf4afd5a2023-12-02 11:32:57 +010058 async getCurrentInfo(injectionDetails) {
59 return this
60 .getCurrentThreads(injectionDetails, /* checkRecentTimestamp = */ true)
61 .catch(() => {
62 console.debug(
63 `extraInfo: couldn't get updated thread info. Trying to ` +
64 `get the information even if it is old.`);
65 return this.getCurrentThreads(
66 injectionDetails, /* checkRecentTimestamp = */ false);
67 });
68 }
Adrià Vilanova Martínez19f6a652023-11-15 19:38:50 +010069
Adrià Vilanova Martínezf4afd5a2023-12-02 11:32:57 +010070 async getCurrentThreads(injectionDetails, checkRecentTimestamp) {
71 injectionDetails.checkRecentTimestamp = checkRecentTimestamp;
72 const options = this.getWaitForCurrentInfoOptions();
73 return waitFor(
74 () => this.attemptToGetCurrentInfo(injectionDetails), options);
75 }
76
77 async isInfoCurrent(injectionDetails) {
78 const checkRecentTimestamp = injectionDetails.checkRecentTimestamp;
Adrià Vilanova Martínez19f6a652023-11-15 19:38:50 +010079 const isMessageNode = injectionDetails.isMessageNode;
80 const messageNode = injectionDetails.messageNode;
81
Adrià Vilanova Martínezf4afd5a2023-12-02 11:32:57 +010082 return (!checkRecentTimestamp || this.isThreadCurrent()) &&
Adrià Vilanova Martínez19f6a652023-11-15 19:38:50 +010083 (!isMessageNode || this.currentThreadContainsMessage(messageNode));
84 }
85
Adrià Vilanova Martínezf4afd5a2023-12-02 11:32:57 +010086 isThreadCurrent() {
87 const currentPage = this.parseThreadUrl();
88 return Date.now() - this.info.timestamp < kCurrentInfoExpiresInMs &&
89 this.info.thread.getId() == currentPage.thread &&
90 this.info.thread.getForumId() == currentPage.forum;
91 }
92
Adrià Vilanova Martínez19f6a652023-11-15 19:38:50 +010093 parseThreadUrl() {
94 const currentPage = parseUrl(location.href);
95 if (currentPage === false)
96 throw new Error(`couldn't parse current URL: ${location.href}`);
97
98 return currentPage;
99 }
100
101 currentThreadContainsMessage(messageNode) {
102 const messageId = MessageExtraInfoService.getMessageIdFromNode(messageNode);
Adrià Vilanova Martínez4b2582d2023-11-16 01:56:04 +0100103 const message = MessageExtraInfoService.getMessageFromList(
104 messageId, this.info.messages);
Adrià Vilanova Martínez19f6a652023-11-15 19:38:50 +0100105 return message !== undefined;
106 }
107}