Workflows: add mark as read/unread actions

Fixed: twpowertools:147
Change-Id: I6bb2363256cfd2a0ff3aafb4df71f24561576b27
diff --git a/src/contentScripts/communityConsole/workflows/actionRunners/readState.js b/src/contentScripts/communityConsole/workflows/actionRunners/readState.js
new file mode 100644
index 0000000..73d9a4f
--- /dev/null
+++ b/src/contentScripts/communityConsole/workflows/actionRunners/readState.js
@@ -0,0 +1,21 @@
+import {CCApi} from '../../../../common/api.js';
+import {getAuthUser} from '../../../../common/communityConsoleUtils.js';
+
+export default class ReadStateRunner {
+  execute(readState, thread) {
+    // Although this should in theory be the last message ID, it seems like
+    // setting 0 marks the entire thread as read anyways.
+    const lastMessageId = readState ? '0' : '-1';
+
+    return CCApi(
+        'SetUserReadStateBulk', {
+          // bulkItem:
+          1: [{
+            1: thread.forumId,
+            2: thread.threadId,
+            3: lastMessageId,
+          }],
+        },
+        /* authenticated = */ true, getAuthUser());
+  }
+}
diff --git a/src/contentScripts/communityConsole/workflows/models/thread.js b/src/contentScripts/communityConsole/workflows/models/thread.js
index 0f54316..96f69de 100644
--- a/src/contentScripts/communityConsole/workflows/models/thread.js
+++ b/src/contentScripts/communityConsole/workflows/models/thread.js
@@ -97,6 +97,10 @@
     return this._details?.['2']?.['9'];
   }
 
+  get lastMessageId() {
+    return this._details?.['2']?.['10'];
+  }
+
   get payload() {
     return this._details?.['2']?.['13'];
   }
diff --git a/src/contentScripts/communityConsole/workflows/runner.js b/src/contentScripts/communityConsole/workflows/runner.js
index d181d46..35c291c 100644
--- a/src/contentScripts/communityConsole/workflows/runner.js
+++ b/src/contentScripts/communityConsole/workflows/runner.js
@@ -2,6 +2,7 @@
 import * as pb from '../../../workflows/proto/main_pb.js';
 
 import CRRunner from './actionRunners/replyWithCR.js';
+import ReadStateRunner from './actionRunners/readState.js';
 import Thread from './models/thread.js';
 
 export default class WorkflowRunner {
@@ -16,6 +17,7 @@
 
     // Initialize action runners:
     this._CRRunner = new CRRunner();
+    this._ReadStateRunner = new ReadStateRunner();
   }
 
   start() {
@@ -57,6 +59,12 @@
         return this._CRRunner.execute(
             this._currentAction?.getReplyWithCrAction?.(), this._currentThread);
 
+      case pb.workflows.Action.ActionCase.MARK_AS_READ_ACTION:
+        return this._ReadStateRunner.execute(true, this._currentThread);
+
+      case pb.workflows.Action.ActionCase.MARK_AS_UNREAD_ACTION:
+        return this._ReadStateRunner.execute(false, this._currentThread);
+
       default:
         return Promise.reject(new Error('This action isn\'t supported yet.'));
     }