Improve sort detection

Before, we relied on the startup data object to detect whether the sort
options were compatible with this feature or not, which gave a wrong
veredict if those options were changed without reloading the page.

This change detects those options much more reliably, as it now parses
the last ViewForum request body to search for those settings.

Bug: twpowertools:5, twpowertools:22
Change-Id: Ic00200f51b611197c0158f9497597af47bee9581
diff --git a/src/common/xhrInterceptors.json5 b/src/common/xhrInterceptors.json5
index 6a5a1c5..63bec85 100644
--- a/src/common/xhrInterceptors.json5
+++ b/src/common/xhrInterceptors.json5
@@ -1,6 +1,11 @@
 {
   interceptors: [
     {
+      eventName: "ViewForumRequest",
+      urlRegex: "api/ViewForum",
+      intercepts: "request",
+    },
+    {
       eventName: "ViewForumResponse",
       urlRegex: "api/ViewForum",
       intercepts: "response",
diff --git a/src/contentScripts/communityConsole/autoRefresh.js b/src/contentScripts/communityConsole/autoRefresh.js
index 41777ca..4f40fee 100644
--- a/src/contentScripts/communityConsole/autoRefresh.js
+++ b/src/contentScripts/communityConsole/autoRefresh.js
@@ -5,6 +5,7 @@
 
 var authuser = getAuthUser();
 
+const threadListRequestEvent = 'TWPT_ViewForumRequest';
 const intervalMs = 3 * 60 * 1000;  // 3 minutes
 const firstCallDelayMs = 3 * 1000;  // 3 seconds
 
@@ -15,9 +16,13 @@
     this.lastTimestamp = null;
     this.filter = null;
     this.path = null;
+    this.requestId = null;
+    this.requestOrderOptions = null;
     this.snackbar = null;
     this.interval = null;
     this.firstCallTimeout = null;
+
+    this.setUpHandlers();
   }
 
   getStartupData() {
@@ -26,11 +31,14 @@
   }
 
   isOrderedByTimestampDescending() {
-    var startup = this.getStartupData();
+    // This means we didn't intercept the request.
+    if (!this.requestOrderOptions)
+      return false;
+
     // Returns orderOptions.by == TIMESTAMP && orderOptions.desc == true
     return (
-        startup?.[1]?.[1]?.[3]?.[14]?.[1] == 1 &&
-        startup?.[1]?.[1]?.[3]?.[14]?.[2] == true);
+        this.requestOrderOptions?.[1] == 1 &&
+        this.requestOrderOptions?.[2] == true);
   }
 
   getCustomFilter(path) {
@@ -224,8 +232,25 @@
                 'Couldn\'t get last timestamp (while setting up): ', err));
   }
 
+  setUpHandlers() {
+    window.addEventListener(
+        threadListRequestEvent, e => this.handleListRequest(e));
+  }
+
+  handleListRequest(e) {
+    console.debug('autorefresh_list: handling ViewForum request');
+    if (this.requestId === null || e.detail.id > this.requestId) {
+      this.requestId = e.detail.id;
+      this.requestOrderOptions = e.detail.body?.['2']?.['2'];
+    }
+  }
+
   setUp() {
-    if (!this.isOrderedByTimestampDescending()) return;
+    if (!this.isOrderedByTimestampDescending()) {
+      console.debug(
+          'autorefresh_list: refused to start up because the order is not by timestamp descending.');
+      return;
+    }
 
     this.unregister();
 
diff --git a/src/contentScripts/communityConsole/main.js b/src/contentScripts/communityConsole/main.js
index 836fd1f..5db25fc 100644
--- a/src/contentScripts/communityConsole/main.js
+++ b/src/contentScripts/communityConsole/main.js
@@ -1,6 +1,5 @@
 import {injectScript, injectStyles, injectStylesheet} from '../../common/contentScriptsUtils.js';
 
-import AutoRefresh from './autoRefresh.js';
 import AvatarsHandler from './avatars.js';
 import {batchLock} from './batchLock.js';
 import {injectDarkModeButton, isDarkThemeOn} from './darkMode.js';
@@ -8,7 +7,7 @@
 import {injectPreviousPostsLinks} from './profileHistoryLink.js';
 import {unifiedProfilesFix} from './unifiedProfiles.js';
 
-var mutationObserver, intersectionObserver, intersectionOptions, options, avatars, autoRefresh;
+var mutationObserver, intersectionObserver, intersectionOptions, options, avatars;
 
 const watchedNodesSelectors = [
   // App container (used to set up the intersection observer and inject the dark
@@ -172,8 +171,7 @@
   if (options.threadlistavatars)
     avatars = new AvatarsHandler();
 
-  if (options.autorefreshlist)
-    autoRefresh = new AutoRefresh();
+  // autoRefresh is initialized in start.js
 
   // Before starting the mutation Observer, check whether we missed any
   // mutations by manually checking whether some watched nodes already
diff --git a/src/contentScripts/communityConsole/start.js b/src/contentScripts/communityConsole/start.js
index 782569f..93ee6ab 100644
--- a/src/contentScripts/communityConsole/start.js
+++ b/src/contentScripts/communityConsole/start.js
@@ -1,5 +1,7 @@
 import {injectScript, injectStylesheet} from '../../common/contentScriptsUtils.js';
 
+import AutoRefresh from './autoRefresh.js';
+
 const SMEI_UNIFIED_PROFILES = 9;
 
 chrome.storage.sync.get(null, function(items) {
@@ -21,6 +23,11 @@
         'data-startup', JSON.stringify(startup));
   }
 
+  // Initialized here instead of in main.js so the first |ViewForumResponse|
+  // event is received if it happens when the page loads.
+  if (items.autorefreshlist)
+    window.autoRefresh = new AutoRefresh();
+
   if (items.ccdarktheme) {
     switch (items.ccdarktheme_mode) {
       case 'switch':