Refactor BatchLock code

This will hopefully make it a little bit clearer.

Change-Id: Ie6b7159c3821adc09cf8e07f1a70f6caf0ff9e27
diff --git a/src/contentScripts/communityConsole/batchLock.js b/src/contentScripts/communityConsole/batchLock.js
index c8aca09..3b414b5 100644
--- a/src/contentScripts/communityConsole/batchLock.js
+++ b/src/contentScripts/communityConsole/batchLock.js
@@ -1,30 +1,19 @@
-import {removeChildNodes, createExtBadge} from './utils/common.js';
+import {createExtBadge, removeChildNodes} from './utils/common.js';
 
-export function nodeIsReadToggleBtn(node) {
-  return ('tagName' in node) && node.tagName == 'MATERIAL-BUTTON' &&
-      node.getAttribute('debugid') !== null &&
-      (node.getAttribute('debugid') == 'mark-read-button' ||
-       node.getAttribute('debugid') == 'mark-unread-button') &&
-      ('parentNode' in node) && node.parentNode !== null &&
-      ('parentNode' in node.parentNode) &&
-      node.parentNode.querySelector('[debugid="batchlock"]') === null &&
-      node.parentNode.parentNode !== null &&
-      ('tagName' in node.parentNode.parentNode) &&
-      node.parentNode.parentNode.tagName == 'EC-BULK-ACTIONS';
-}
-
-export function addBatchLockBtn(readToggle) {
-  var clone = readToggle.cloneNode(true);
-  clone.setAttribute('debugid', 'batchlock');
-  clone.classList.add('TWPT-btn--with-badge');
-  clone.setAttribute('title', chrome.i18n.getMessage('inject_lockbtn'));
-  clone.querySelector('material-icon').setAttribute('icon', 'lock');
-  clone.querySelector('i.material-icon-i').textContent = 'lock';
-
-  var badge = createExtBadge();
-  clone.append(badge);
-
-  clone.addEventListener('click', function() {
+export var batchLock = {
+  nodeIsReadToggleBtn(node) {
+    return ('tagName' in node) && node.tagName == 'MATERIAL-BUTTON' &&
+        node.getAttribute('debugid') !== null &&
+        (node.getAttribute('debugid') == 'mark-read-button' ||
+         node.getAttribute('debugid') == 'mark-unread-button') &&
+        ('parentNode' in node) && node.parentNode !== null &&
+        ('parentNode' in node.parentNode) &&
+        node.parentNode.querySelector('[debugid="batchlock"]') === null &&
+        node.parentNode.parentNode !== null &&
+        ('tagName' in node.parentNode.parentNode) &&
+        node.parentNode.parentNode.tagName == 'EC-BULK-ACTIONS';
+  },
+  createDialog() {
     var modal = document.querySelector('.pane[pane-id="default-1"]');
 
     var dialog = document.createElement('material-dialog');
@@ -120,14 +109,29 @@
     modal.append(dialog);
     modal.classList.add('visible', 'modal');
     modal.style.display = 'flex';
-  });
+  },
+  addButton(readToggle) {
+    var clone = readToggle.cloneNode(true);
+    clone.setAttribute('debugid', 'batchlock');
+    clone.classList.add('TWPT-btn--with-badge');
+    clone.setAttribute('title', chrome.i18n.getMessage('inject_lockbtn'));
+    clone.querySelector('material-icon').setAttribute('icon', 'lock');
+    clone.querySelector('i.material-icon-i').textContent = 'lock';
 
-  var duplicateBtn =
-      readToggle.parentNode.querySelector('[debugid="mark-duplicate-button"]');
-  if (duplicateBtn)
-    duplicateBtn.parentNode.insertBefore(
-        clone, (duplicateBtn.nextSibling || duplicateBtn));
-  else
-    readToggle.parentNode.insertBefore(
-        clone, (readToggle.nextSibling || readToggle));
-}
+    var badge = createExtBadge();
+    clone.append(badge);
+
+    clone.addEventListener('click', () => {
+      this.createDialog();
+    });
+
+    var duplicateBtn = readToggle.parentNode.querySelector(
+        '[debugid="mark-duplicate-button"]');
+    if (duplicateBtn)
+      duplicateBtn.parentNode.insertBefore(
+          clone, (duplicateBtn.nextSibling || duplicateBtn));
+    else
+      readToggle.parentNode.insertBefore(
+          clone, (readToggle.nextSibling || readToggle));
+  }
+};
diff --git a/src/contentScripts/communityConsole/main.js b/src/contentScripts/communityConsole/main.js
index 3924af6..08e3e71 100644
--- a/src/contentScripts/communityConsole/main.js
+++ b/src/contentScripts/communityConsole/main.js
@@ -2,7 +2,7 @@
 
 import {autoRefresh} from './autoRefresh.js';
 import AvatarsHandler from './avatars.js';
-import {addBatchLockBtn, nodeIsReadToggleBtn} from './batchLock.js';
+import {batchLock} from './batchLock.js';
 import {injectDarkModeButton, isDarkThemeOn} from './darkMode.js';
 import {applyDragAndDropFix} from './dragAndDropFix.js';
 import {injectPreviousPostsLinks} from './profileHistoryLink.js';
@@ -105,8 +105,8 @@
     }
 
     // Inject the batch lock button in the thread list
-    if (options.batchlock && nodeIsReadToggleBtn(node)) {
-      addBatchLockBtn(node);
+    if (options.batchlock && batchLock.nodeIsReadToggleBtn(node)) {
+      batchLock.addButton(node);
     }
 
     // Inject avatar links to threads in the thread list
diff --git a/src/injections/batchLock.js b/src/injections/batchLock.js
index 9a91203..6b45cdd 100644
--- a/src/injections/batchLock.js
+++ b/src/injections/batchLock.js
@@ -1,3 +1,4 @@
+import {CCApi} from '../common/api.js';
 import {parseUrl} from '../common/commonUtils.js';
 import {getAuthUser} from '../common/communityConsoleUtils.js';
 
@@ -106,9 +107,6 @@
   modal.querySelector('main').append(p, log);
 
   var authuser = getAuthUser();
-  var APIRequestUrl =
-      'https://support.google.com/s/community/api/SetThreadAttribute' +
-      (authuser == '0' ? '' : '?authuser=' + encodeURIComponent(authuser));
 
   checkboxes.forEach(checkbox => {
     var url = recursiveParentElement(checkbox, 'A').href;
@@ -117,37 +115,12 @@
       console.error('Fatal error: thread URL ' + url + ' could not be parsed.');
       return;
     }
-    fetch(APIRequestUrl, {
-      'headers': {
-        'content-type': 'text/plain; charset=utf-8',
-      },
-      'body': JSON.stringify({
-        1: thread.forum,
-        2: thread.thread,
-        3: (action == 'lock' ? 1 : 2),
-      }),
-      'method': 'POST',
-      'mode': 'cors',
-      'credentials': 'include',
-    })
-        .then(res => {
-          if (res.status == 200 || res.status == 400) {
-            return res.json().then(data => ({
-                                     status: res.status,
-                                     body: data,
-                                   }));
-          } else {
-            throw new Error('Status code ' + res.status + ' was not expected.');
-          }
-        })
-        .then(res => {
-          if (res.status == 400) {
-            throw new Error(
-                res.body[4] ||
-                ('Response status: 400. Error code: ' + res.body[2]));
-          }
-        })
-        .then(_ => {
+    CCApi('SetThreadAttribute', {
+      1: thread.forum,
+      2: thread.thread,
+      3: (action == 'lock' ? 1 : 2),
+    }, /* authenticated = */ true, authuser)
+        .then(() => {
           addLogEntry(true, action, url, thread.thread);
         })
         .catch(err => {
@@ -155,7 +128,7 @@
               'An error occurred while locking thread ' + url + ': ' + err);
           addLogEntry(false, action, url, thread.thread, err);
         })
-        .then(_ => {
+        .then(() => {
           progress.value = parseInt(progress.value) + 1;
           if (progress.value == progress.getAttribute('max'))
             enableEndButtons();
@@ -169,7 +142,7 @@
     switch (e.data.action) {
       case 'lock':
       case 'unlock':
-        console.info('Performing action ' + e.data.action);
+        console.debug('Performing action ' + e.data.action);
         lockThreads(e.data.action);
         break;