Add flattenthreads experiment
This experiment allows users to flatten the replies in threads, so they
are shown linearly in a chronological way instead of nested.
When the option is enabled, a switch is added to the thread page which
lets the user switch between flattening replies and not flattening them.
Some UI is still missing (see the design document[1]).
[1]: https://docs.google.com/document/d/1P-HanTHxaOFF_FHh0uSv0GIhG1dxWTJTGoT6VPjjvY0/edit
Bug: twpowertools:153
Change-Id: I43f94442cadc12b752700f0e8d974522be621d3e
diff --git a/src/xhrInterceptor/responseModifiers/flattenThread.js b/src/xhrInterceptor/responseModifiers/flattenThread.js
new file mode 100644
index 0000000..65eb42c
--- /dev/null
+++ b/src/xhrInterceptor/responseModifiers/flattenThread.js
@@ -0,0 +1,40 @@
+import GapModel from '../../models/Gap.js';
+import MessageModel from '../../models/Message.js';
+
+const loadMoreThread = {
+ urlRegex: /api\/ViewThread/i,
+ featureGated: true,
+ features: ['flattenthreads', 'flattenthreads_switch_enabled'],
+ isEnabled(options) {
+ return options['flattenthreads'] &&
+ options['flattenthreads_switch_enabled'];
+ },
+ async interceptor(_request, response) {
+ if (!response[1]?.[40]) return response;
+
+ const originalMogs =
+ MessageModel.mapToMessageOrGapModels(response[1][40] ?? []);
+ let extraMogs = [];
+ originalMogs.forEach(mog => {
+ if (mog instanceof GapModel) return;
+ const cogs = mog.getCommentsAndGaps();
+ extraMogs = extraMogs.concat(cogs);
+ mog.clearCommentsAndGaps();
+ });
+ const mogs = originalMogs.concat(extraMogs);
+ mogs.sort((a, b) => {
+ const c = a instanceof MessageModel ? a.getCreatedMicroseconds() :
+ a.getStartTimestamp();
+ const d = b instanceof MessageModel ? b.getCreatedMicroseconds() :
+ b.getStartTimestamp();
+ const diff = c - d;
+ return diff > 0 ? 1 : diff < 0 ? -1 : 0;
+ });
+ response[1][40] = mogs.map(mog => mog.toRawMessageOrGap());
+ // Set num_messages to the updated value, since we've flattened the replies.
+ response[1][8] = response[1][40].length;
+ return response;
+ },
+};
+
+export default loadMoreThread;