blob: e87f541cb340808bbe0d558a66c19b999ed6e5d5 [file] [log] [blame]
Adrià Vilanova Martínez2d9be8d2022-12-28 00:50:14 +01001import GapModel from './Gap.js';
2import MessageModel from './Message.js';
3
4export default class ThreadModel {
Adrià Vilanova Martínez5dd7a6f2023-03-04 18:32:27 +01005 constructor(data) {
6 this.data = data ?? {};
7 }
8
9 getId() {
10 return this.data[2]?.[1]?.[1] ?? null;
11 }
12
13 getForumId() {
14 return this.data[2]?.[1]?.[3] ?? null;
15 }
16
17 getRawCommentsAndGaps() {
18 return this.data[40] ?? [];
19 }
20
21 setRawCommentsAndGaps(cogs) {
22 this.data[40] = cogs;
23 }
24
25 getMessageOrGapModels() {
26 const rawMogs = this.getRawCommentsAndGaps();
27 return rawMogs.filter(mog => mog !== undefined).map(mog => {
28 if (mog[1]) return new MessageModel(mog[1], this);
29 if (mog[2]) return new GapModel(mog[2], this);
30 });
31 }
32
33 setLastMessage(message) {
34 if (!this.data[17]) this.data[17] = [];
35 this.data[17][3] = message;
36 }
37
38 setNumMessages(num) {
39 this.data[8] = num;
40 }
41
42 isLocked() {
43 // TODO: When a forum is read-only, this should also return true.
44 return this.data[2]?.[5] == true;
45 }
46
47 isSoftLocked() {
48 return this.data[2]?.[51] == true;
49 }
50
51 isAuthoredByUser() {
52 return this.data[9] == true;
53 }
54
55 toRawThread() {
56 return this.data;
57 }
58
Adrià Vilanova Martínez2d9be8d2022-12-28 00:50:14 +010059 /**
60 * The following code is based on logic written by Googlers in the TW frontend
61 * and thus is not included as part of the MIT license.
62 */
63 static mergeMessageOrGaps(a, b) {
64 if (a.length == 0 || b.length == 0)
65 return a.length > 0 ? a : b.length > 0 ? b : [];
66
67 let e = [];
68 for (let g = 0, k = 0, m = 0, q = a[g], u = b[k];
69 g < a.length && k < b.length;) {
70 if (q instanceof MessageModel && u instanceof MessageModel) {
71 if (q.getCreatedMicroseconds() === u.getCreatedMicroseconds()) {
72 u.mergeCommentOrGapViews(q);
73 }
74
75 e.push(u);
76
77 if (g === a.length - 1 || k === b.length - 1) {
78 for (; ++g < a.length;) e.push(a[g]);
79 for (; ++k < b.length;) e.push(b[k]);
80 break;
81 }
82
83 q = a[++g];
84 u = b[++k];
85 } else {
86 if (u instanceof GapModel) {
87 let z;
88 for (z = q instanceof MessageModel ? q.getCreatedMicroseconds() :
89 q.getEndTimestamp();
90 z < u.getEndTimestamp();) {
91 e.push(q);
92 m += q instanceof GapModel ? q.getCount() : 1;
93 if (g === a.length - 1) break;
94 q = a[++g];
95 z = q instanceof MessageModel ? q.getCreatedMicroseconds() :
96 q.getEndTimestamp();
97 }
98 if (q instanceof GapModel && u.getCount() - m > 0 &&
99 z >= u.getEndTimestamp()) {
100 const gm = new GapModel();
101 gm.setCount(u.getCount() - m);
102 gm.setStartMicroseconds('' + q.getStartTimestamp());
103 gm.setEndMicroseconds('' + u.getEndTimestamp());
104 gm.setParentId(u.getParentId());
105 e.push(gm);
106 m = u.getCount() - m;
107 } else {
108 m = 0;
109 }
110 if (k === b.length - 1) break;
111 u = b[++k];
112 }
113 if (q instanceof GapModel) {
114 let z;
115 for (z = u instanceof MessageModel ? u.getCreatedMicroseconds() :
116 u.getEndTimestamp();
117 z < q.getEndTimestamp();) {
118 e.push(u);
119 m += u instanceof GapModel ? u.getCount() : 1;
120 if (k === b.length - 1) break;
121 u = b[++k];
122 z = u instanceof MessageModel ? u.getCreatedMicroseconds() :
123 u.getEndTimestamp();
124 }
125 if (u instanceof GapModel && q.getCount() - m > 0 &&
126 z >= q.getEndTimestamp()) {
127 const gm = new GapModel();
128 gm.setCount(q.getCount() - m);
129 gm.setStartMicroseconds('' + u.getStartTimestamp());
130 gm.setEndMicroseconds('' + q.getEndTimestamp());
131 gm.setParentId(q.getParentId());
132 e.push(gm);
133 m = q.getCount() - m;
134 } else {
135 m = 0;
136 }
137 if (g === a.length - 1) break;
138 q = a[++g];
139 }
140 }
141 }
142 return e;
143 }
144
145 static mergeMessageOrGapsMultiarray(mogsModels) {
146 if (mogsModels.length < 1) return [];
147 let mergeResult = mogsModels[0];
148 for (let i = 1; i < mogsModels.length; ++i) {
149 mergeResult = ThreadModel.mergeMessageOrGaps(mergeResult, mogsModels[i]);
150 }
151 return mergeResult;
152 }
153}