blob: f8da127270ea598bf42f2ea1ca582e953b27938b [file] [log] [blame]
Adrià Vilanova Martínez2d9be8d2022-12-28 00:50:14 +01001import {CCApi} from '../../common/api.js';
2import {getAuthUser} from '../../common/communityConsoleUtils.js';
3import GapModel from '../../models/Gap.js';
4import MessageModel from '../../models/Message.js';
5import ThreadModel from '../../models/Thread.js';
6
7const authuser = getAuthUser();
8
9const loadMoreThread = {
10 urlRegex: /api\/ViewThread/i,
11 featureGated: true,
12 features: ['flattenthreads', 'flattenthreads_switch_enabled'],
13 isEnabled(options) {
14 return options['flattenthreads'] &&
15 options['flattenthreads_switch_enabled'];
16 },
17 async interceptor(request, response) {
18 if (!response[1]?.[40]) return response;
19
20 const forumId = response[1]?.[2]?.[1]?.[3];
21 const threadId = response[1]?.[2]?.[1]?.[1];
22 if (!forumId || !threadId) {
23 console.error(
24 '[loadMoreThread] Couldn\'t find forum id and thread id for:',
25 request.$TWPTRequestUrl);
26 return response;
27 }
28
29 const mogs = MessageModel.mapToMessageOrGapModels(response[1]?.[40] ?? []);
30 response[1][40] = await this.loadGaps(forumId, threadId, mogs, 0);
31 return response;
32 },
33 loadGaps(forumId, threadId, mogs, it) {
34 if (it >= 10) {
35 return Promise.reject(new Error(
36 'loadGaps has been called for more than 10 times, ' +
37 'which means we\'ve entered an infinite loop.'));
38 }
39
40 const messageOrGapPromises = [];
41 messageOrGapPromises.push(Promise.resolve(mogs));
42 for (const mog of mogs) {
43 if (mog instanceof GapModel) {
44 messageOrGapPromises.push(this.loadGap(forumId, threadId, mog));
45 }
46 if (mog instanceof MessageModel) {
47 mog.getCommentsAndGaps().forEach(cog => {
48 if (cog instanceof GapModel) {
49 messageOrGapPromises.push(this.loadGap(forumId, threadId, cog));
50 }
51 });
52 }
53 }
54
55 return Promise.all(messageOrGapPromises).then(res => {
56 // #!if !production
57 console.time('mergeMessages');
58 // #!endif
59 const mogs = ThreadModel.mergeMessageOrGapsMultiarray(res);
60 // #!if !production
61 console.timeEnd('mergeMessages');
62 // #!endif
63 if (mogs.some(mog => {
64 return mog instanceof GapModel ||
65 mog.getCommentsAndGaps().some(cog => cog instanceof GapModel);
66 })) {
67 return this.loadGaps(forumId, threadId, mogs, it + 1);
68 }
69 return mogs.map(message => message.toRawMessageOrGap());
70 });
71 },
72 loadGap(forumId, threadId, gap) {
73 return CCApi(
74 'ViewThread', {
75 1: forumId,
76 2: threadId,
77 3: {
78 // options
79 1: {
80 // pagination
81 2: gap.getCount(), // maxNum
82 7: {
83 // targetRange
84 1: gap.getStartMicroseconds(), // startMicroseconds
85 2: gap.getEndMicroseconds(), // endMicroseconds
86 3: gap.getParentId(), // parentId
87 },
88 },
89 5: true, // withUserProfile
90 10: true, // withPromotedMessages
91 },
92 },
93 /* authenticated = */ true, authuser)
94 .then(res => {
95 return MessageModel.mapToMessageOrGapModels(res[1]?.[40] ?? []);
96 });
97 }
98};
99
100export default loadMoreThread;