blob: 6c8fb736b70fcdc966e9531eb03e11e17cffcc90 [file] [log] [blame]
import {waitFor} from 'poll-until-promise';
import {parseUrl} from '../../../../common/commonUtils.js';
import ThreadModel from '../../../../models/Thread.js';
import {kViewThreadResponse} from '../consts.js';
import MessageExtraInfoService from '../services/message.js';
import ResponseEventBasedInfoHandler from './basedOnResponseEvent.js';
const kIntervalInMs = 500;
const kTimeoutInMs = 3 * 1000;
const kCurrentInfoExpiresInMs = kTimeoutInMs * 1.5;
export default class ThreadInfoHandler extends ResponseEventBasedInfoHandler {
getEvent() {
return kViewThreadResponse;
}
getWaitForCurrentInfoOptions() {
return {
interval: kIntervalInMs,
timeout: kTimeoutInMs,
};
}
setUpDefaultInfoValue() {
this.info = {
thread: new ThreadModel(),
messages: [],
id: -1,
timestamp: 0,
};
}
updateInfoWithNewValue(e) {
const newThread = new ThreadModel(e.detail.body?.[1]);
if (newThread.getId() != this.info.thread.getId()) {
this.info.messages = [];
}
const newMessages = newThread.getAllMessagesList();
this.updateRecordedMessages(newMessages);
this.info.thread = newThread;
this.info.id = e.detail.id;
this.info.timestamp = Date.now();
}
updateRecordedMessages(newMessages) {
const nonUpdatedMessages = this.info.messages.filter(message => {
return !newMessages.some(newMessage => {
return message.getId() == newMessage.getId();
});
});
this.info.messages = nonUpdatedMessages.concat(newMessages);
}
async getCurrentInfo(injectionDetails) {
return this
.getCurrentThreads(injectionDetails, /* checkRecentTimestamp = */ true)
.catch(() => {
console.debug(
`extraInfo: couldn't get updated thread info. Trying to ` +
`get the information even if it is old.`);
return this.getCurrentThreads(
injectionDetails, /* checkRecentTimestamp = */ false);
});
}
async getCurrentThreads(injectionDetails, checkRecentTimestamp) {
injectionDetails.checkRecentTimestamp = checkRecentTimestamp;
const options = this.getWaitForCurrentInfoOptions();
return waitFor(
() => this.attemptToGetCurrentInfo(injectionDetails), options);
}
async isInfoCurrent(injectionDetails) {
const checkRecentTimestamp = injectionDetails.checkRecentTimestamp;
const isMessageNode = injectionDetails.isMessageNode;
const messageNode = injectionDetails.messageNode;
return (!checkRecentTimestamp || this.isThreadCurrent()) &&
(!isMessageNode || this.currentThreadContainsMessage(messageNode));
}
isThreadCurrent() {
const currentPage = this.parseThreadUrl();
return Date.now() - this.info.timestamp < kCurrentInfoExpiresInMs &&
this.info.thread.getId() == currentPage.thread &&
this.info.thread.getForumId() == currentPage.forum;
}
parseThreadUrl() {
const currentPage = parseUrl(location.href);
if (currentPage === false)
throw new Error(`couldn't parse current URL: ${location.href}`);
return currentPage;
}
currentThreadContainsMessage(messageNode) {
const messageId = MessageExtraInfoService.getMessageIdFromNode(messageNode);
const message = MessageExtraInfoService.getMessageFromList(
messageId, this.info.messages);
return message !== undefined;
}
}