Flatten threads: don't show reply button when appropriate

This CL also refactors the response interceptors to use the new
ThreadModel.

Fixed: twpowertools:160
Change-Id: I859e0fa1b8f5f4057bd66af3d167e4b21c6d12ed
diff --git a/src/xhrInterceptor/responseModifiers/flattenThread.js b/src/xhrInterceptor/responseModifiers/flattenThread.js
index b515191..2eac64d 100644
--- a/src/xhrInterceptor/responseModifiers/flattenThread.js
+++ b/src/xhrInterceptor/responseModifiers/flattenThread.js
@@ -1,6 +1,10 @@
 import {kAdditionalInfoClass} from '../../contentScripts/communityConsole/flattenThreads/flattenThreads.js';
 import GapModel from '../../models/Gap.js';
 import MessageModel from '../../models/Message.js';
+import StartupDataModel from '../../models/StartupData.js';
+import ThreadModel from '../../models/Thread.js';
+
+const currentUser = StartupDataModel.buildFromCCDOM().getCurrentUserModel();
 
 const flattenThread = {
   urlRegex: /api\/ViewThread/i,
@@ -13,9 +17,10 @@
   async interceptor(_request, response) {
     if (!response[1]?.[40]) return response;
 
+    const thread = new ThreadModel(response[1]);
+
     // Do the actual flattening
-    const originalMogs =
-        MessageModel.mapToMessageOrGapModels(response[1][40] ?? []);
+    const originalMogs = thread.getMessageOrGapModels();
     let extraMogs = [];
     originalMogs.forEach(mog => {
       if (mog instanceof GapModel) return;
@@ -56,25 +61,28 @@
       return diff > 0 ? 1 : diff < 0 ? -1 : 0;
     });
 
-    response[1][40] = mogs.map(mog => mog.toRawMessageOrGap());
+    thread.setRawCommentsAndGaps(mogs.map(mog => mog.toRawMessageOrGap()));
 
     // Set last_message to the last message after sorting
-    if (response[1]?.[17]?.[3])
-      response[1][17][3] = response[1][40].slice(-1)?.[1];
+    thread.setLastMessage(thread.getRawCommentsAndGaps().slice(-1)?.[1]);
 
     // Set num_messages to the updated value, since we've flattened the replies.
-    response[1][8] = response[1][40].length;
+    thread.setNumMessages(thread.getRawCommentsAndGaps().length);
+
+    response[1] = thread.toRawThread();
     return response;
   },
   getAdditionalInformation(message, mogs, prevReplyId, prevReplyParentId) {
     const id = message.getId();
     const parentId = message.getParentMessageId();
     const authorName = message.getAuthor()?.[1]?.[1];
+    const canComment = message.canComment(currentUser);
     if (!parentId) {
       return {
         isComment: false,
         id,
         authorName,
+        canComment,
       };
     }
 
@@ -96,8 +104,9 @@
         payload: prevMessage?.getPayload(),
         author: prevMessage?.getAuthor(),
       },
+      canComment,
     };
-  }
+  },
 };
 
 export default flattenThread;
diff --git a/src/xhrInterceptor/responseModifiers/loadMoreThread.js b/src/xhrInterceptor/responseModifiers/loadMoreThread.js
index f259fe4..2ddf37d 100644
--- a/src/xhrInterceptor/responseModifiers/loadMoreThread.js
+++ b/src/xhrInterceptor/responseModifiers/loadMoreThread.js
@@ -17,17 +17,20 @@
   async interceptor(request, response) {
     if (!response[1]?.[40]) return response;
 
-    const forumId = response[1]?.[2]?.[1]?.[3];
-    const threadId = response[1]?.[2]?.[1]?.[1];
-    if (!forumId || !threadId) {
+    const thread = new ThreadModel(response[1]);
+
+    if (!thread.getForumId() || !thread.getId()) {
       console.error(
           '[loadMoreThread] Couldn\'t find forum id and thread id for:',
           request.$TWPTRequestURL);
       return response;
     }
 
-    const mogs = MessageModel.mapToMessageOrGapModels(response[1]?.[40] ?? []);
-    response[1][40] = await this.loadGaps(forumId, threadId, mogs, 0);
+    const mogs = thread.getMessageOrGapModels();
+    thread.setRawCommentsAndGaps(
+        await this.loadGaps(thread.getForumId(), thread.getId(), mogs, 0));
+
+    response[1] = thread.toRawThread();
     return response;
   },
   loadGaps(forumId, threadId, mogs, it) {
@@ -94,7 +97,8 @@
                },
                /* authenticated = */ true, authuser)
         .then(res => {
-          return MessageModel.mapToMessageOrGapModels(res[1]?.[40] ?? []);
+          const thread = new ThreadModel(res[1]);
+          return thread.getMessageOrGapModels();
         });
   }
 };