feat(bulk-report-replies): add keyboard shortcut to toggle the option

Bug: twpowertools:192
Change-Id: I6a6a636c0f875f5795c5d524dfc73ded5bd51e02
diff --git a/src/contentScripts/communityConsole/threadToolbar/components/index.js b/src/contentScripts/communityConsole/threadToolbar/components/index.js
index ae28a0b..727a971 100644
--- a/src/contentScripts/communityConsole/threadToolbar/components/index.js
+++ b/src/contentScripts/communityConsole/threadToolbar/components/index.js
@@ -22,6 +22,10 @@
         'desc':
             'Option shown in the settings menu of the thread toolbar which enables the "bulk report replies" feature.',
       }),
+      supportingText: msg('(Alt+R)', {
+        'desc':
+            'Text shown below the "bulk report replies" feature, to let the user know that they can use this keyboard shortcut to toggle it.',
+      }),
       isShown: options['bulkreportreplies'] === true,
       option: 'bulkreportreplies_switch_enabled'
     },
@@ -135,6 +139,11 @@
               <span>
                 ${item.label}
               </span>
+              ${item.supportingText && html`
+                <span slot="supporting-text">
+                  ${item.supportingText}
+                </span>
+              `}
           </md-menu-item>
         `)}
       </md-menu>
diff --git a/src/entryPoints/communityConsole/contentScripts/main.ts b/src/entryPoints/communityConsole/contentScripts/main.ts
index 008b1b6..ceaf88c 100644
--- a/src/entryPoints/communityConsole/contentScripts/main.ts
+++ b/src/entryPoints/communityConsole/contentScripts/main.ts
@@ -57,6 +57,8 @@
 import BulkReportRepliesHandleBodyClassScript from '../../../features/bulkReportReplies/presentation/scripts/handleBodyClass.script';
 import { IsBulkReportRepliesFeatureEnabledServiceAdapter } from '../../../features/bulkReportReplies/services/isFeatureEnabled.service';
 import BulkReportRepliesStylesScript from '../../../features/bulkReportReplies/presentation/scripts/styles.script';
+import BulkReportRepliesKeyboardShortcutScript from '../../../features/bulkReportReplies/presentation/scripts/keyboardShortcut.script';
+import { OptionsModifierAdapter } from '../../../infrastructure/services/options/OptionsModifier.adapter';
 
 const scriptRunner = createScriptRunner();
 scriptRunner.run();
@@ -78,6 +80,7 @@
     WorkflowsImportDependency,
   );
 
+  const optionsModifier = new OptionsModifierAdapter();
   const ccInfiniteScroll = new CCInfiniteScroll();
   const flattenThreads = new FlattenThreads();
 
@@ -189,6 +192,7 @@
           optionsProvider,
           new IsBulkReportRepliesFeatureEnabledServiceAdapter(),
         ),
+        new BulkReportRepliesKeyboardShortcutScript(optionsProvider, optionsModifier),
         new BulkReportRepliesStylesScript(),
         new CCExtraInfoInjectScript(),
         new CCExtraInfoStylesScript(),
diff --git a/src/features/bulkReportReplies/presentation/scripts/keyboardShortcut.script.ts b/src/features/bulkReportReplies/presentation/scripts/keyboardShortcut.script.ts
new file mode 100644
index 0000000..6ad0b3d
--- /dev/null
+++ b/src/features/bulkReportReplies/presentation/scripts/keyboardShortcut.script.ts
@@ -0,0 +1,39 @@
+import Script from '../../../../common/architecture/scripts/Script';
+import { OptionsModifierPort } from '../../../../services/options/OptionsModifier.port';
+import { OptionsProviderPort } from '../../../../services/options/OptionsProvider';
+
+export default class BulkReportRepliesKeyboardShortcutScript extends Script {
+  page: never;
+  environment: never;
+  runPhase: never;
+
+  constructor(
+    private optionsProvider: OptionsProviderPort,
+    private optionsModifier: OptionsModifierPort,
+  ) {
+    super();
+  }
+
+  execute() {
+    document.body.addEventListener('keydown', (e) => this.handleKeyPress(e));
+  }
+
+  private handleKeyPress(e: KeyboardEvent) {
+    // Otherwise the reply dialog will be shown.
+    e.stopPropagation();
+
+    if (e.code === 'KeyR' && e.altKey && !e.repeat) {
+      this.toggleFeature();
+    }
+  }
+
+  private async toggleFeature() {
+    const isCurrentlyEnabled = await this.optionsProvider.getOptionValue(
+      'bulkreportreplies_switch_enabled',
+    );
+    await this.optionsModifier.set(
+      'bulkreportreplies_switch_enabled',
+      !isCurrentlyEnabled,
+    );
+  }
+}
diff --git a/src/infrastructure/services/options/OptionsModifier.adapter.ts b/src/infrastructure/services/options/OptionsModifier.adapter.ts
new file mode 100644
index 0000000..6f69f8b
--- /dev/null
+++ b/src/infrastructure/services/options/OptionsModifier.adapter.ts
@@ -0,0 +1,16 @@
+import {
+  OptionCodename,
+  OptionsValues,
+} from '../../../common/options/optionsPrototype';
+import { OptionsModifierPort } from '../../../services/options/OptionsModifier.port';
+
+export class OptionsModifierAdapter implements OptionsModifierPort {
+  set<O extends OptionCodename>(
+    option: O,
+    value: OptionsValues[O],
+  ): Promise<void> {
+    return new Promise((resolve) => {
+      chrome.storage.sync.set({ [option]: value }, () => resolve());
+    });
+  }
+}
diff --git a/src/lit-locales/source/ar.xlf b/src/lit-locales/source/ar.xlf
index dac395d..03b2f71 100644
--- a/src/lit-locales/source/ar.xlf
+++ b/src/lit-locales/source/ar.xlf
@@ -45,6 +45,10 @@
   <source>Bulk report replies</source>
   <note from="lit-localize">Option shown in the settings menu of the thread toolbar which enables the "bulk report replies" feature.</note>
 </trans-unit>
+<trans-unit id="sb30734baa37281be">
+  <source>(Alt+R)</source>
+  <note from="lit-localize">Text shown below the "bulk report replies" feature, to let the user know that they can use this keyboard shortcut to toggle it.</note>
+</trans-unit>
     </body>
   </file>
 </xliff>
diff --git a/src/lit-locales/source/ca.xlf b/src/lit-locales/source/ca.xlf
index b1f8e20..c7cece0 100644
--- a/src/lit-locales/source/ca.xlf
+++ b/src/lit-locales/source/ca.xlf
@@ -45,6 +45,10 @@
   <source>Bulk report replies</source>
   <note from="lit-localize">Option shown in the settings menu of the thread toolbar which enables the "bulk report replies" feature.</note>
 </trans-unit>
+<trans-unit id="sb30734baa37281be">
+  <source>(Alt+R)</source>
+  <note from="lit-localize">Text shown below the "bulk report replies" feature, to let the user know that they can use this keyboard shortcut to toggle it.</note>
+</trans-unit>
     </body>
   </file>
 </xliff>
diff --git a/src/lit-locales/source/de.xlf b/src/lit-locales/source/de.xlf
index dd32051..0f826ec 100644
--- a/src/lit-locales/source/de.xlf
+++ b/src/lit-locales/source/de.xlf
@@ -45,6 +45,10 @@
   <source>Bulk report replies</source>
   <note from="lit-localize">Option shown in the settings menu of the thread toolbar which enables the "bulk report replies" feature.</note>
 </trans-unit>
+<trans-unit id="sb30734baa37281be">
+  <source>(Alt+R)</source>
+  <note from="lit-localize">Text shown below the "bulk report replies" feature, to let the user know that they can use this keyboard shortcut to toggle it.</note>
+</trans-unit>
     </body>
   </file>
 </xliff>
diff --git a/src/lit-locales/source/es.xlf b/src/lit-locales/source/es.xlf
index 2bc52b5..8f0359e 100644
--- a/src/lit-locales/source/es.xlf
+++ b/src/lit-locales/source/es.xlf
@@ -45,6 +45,10 @@
   <source>Bulk report replies</source>
   <note from="lit-localize">Option shown in the settings menu of the thread toolbar which enables the "bulk report replies" feature.</note>
 </trans-unit>
+<trans-unit id="sb30734baa37281be">
+  <source>(Alt+R)</source>
+  <note from="lit-localize">Text shown below the "bulk report replies" feature, to let the user know that they can use this keyboard shortcut to toggle it.</note>
+</trans-unit>
     </body>
   </file>
 </xliff>
diff --git a/src/lit-locales/source/fr.xlf b/src/lit-locales/source/fr.xlf
index 02b1c83..18c6e31 100644
--- a/src/lit-locales/source/fr.xlf
+++ b/src/lit-locales/source/fr.xlf
@@ -45,6 +45,10 @@
   <source>Bulk report replies</source>
   <note from="lit-localize">Option shown in the settings menu of the thread toolbar which enables the "bulk report replies" feature.</note>
 </trans-unit>
+<trans-unit id="sb30734baa37281be">
+  <source>(Alt+R)</source>
+  <note from="lit-localize">Text shown below the "bulk report replies" feature, to let the user know that they can use this keyboard shortcut to toggle it.</note>
+</trans-unit>
     </body>
   </file>
 </xliff>
diff --git a/src/lit-locales/source/id.xlf b/src/lit-locales/source/id.xlf
index 22d1a3b..1a68b14 100644
--- a/src/lit-locales/source/id.xlf
+++ b/src/lit-locales/source/id.xlf
@@ -37,6 +37,10 @@
   <source>Bulk report replies</source>
   <note from="lit-localize">Option shown in the settings menu of the thread toolbar which enables the "bulk report replies" feature.</note>
 </trans-unit>
+<trans-unit id="sb30734baa37281be">
+  <source>(Alt+R)</source>
+  <note from="lit-localize">Text shown below the "bulk report replies" feature, to let the user know that they can use this keyboard shortcut to toggle it.</note>
+</trans-unit>
 </body>
 </file>
 </xliff>
diff --git a/src/lit-locales/source/it.xlf b/src/lit-locales/source/it.xlf
index de573c6..a87df6b 100644
--- a/src/lit-locales/source/it.xlf
+++ b/src/lit-locales/source/it.xlf
@@ -39,6 +39,10 @@
   <source>Bulk report replies</source>
   <note from="lit-localize">Option shown in the settings menu of the thread toolbar which enables the "bulk report replies" feature.</note>
 </trans-unit>
+<trans-unit id="sb30734baa37281be">
+  <source>(Alt+R)</source>
+  <note from="lit-localize">Text shown below the "bulk report replies" feature, to let the user know that they can use this keyboard shortcut to toggle it.</note>
+</trans-unit>
     </body>
   </file>
 </xliff>
diff --git a/src/lit-locales/source/ja.xlf b/src/lit-locales/source/ja.xlf
index 4e7b21a..7fdd8ea 100644
--- a/src/lit-locales/source/ja.xlf
+++ b/src/lit-locales/source/ja.xlf
@@ -45,6 +45,10 @@
   <source>Bulk report replies</source>
   <note from="lit-localize">Option shown in the settings menu of the thread toolbar which enables the "bulk report replies" feature.</note>
 </trans-unit>
+<trans-unit id="sb30734baa37281be">
+  <source>(Alt+R)</source>
+  <note from="lit-localize">Text shown below the "bulk report replies" feature, to let the user know that they can use this keyboard shortcut to toggle it.</note>
+</trans-unit>
     </body>
   </file>
 </xliff>
diff --git a/src/lit-locales/source/ko.xlf b/src/lit-locales/source/ko.xlf
index b111b65..52286a9 100644
--- a/src/lit-locales/source/ko.xlf
+++ b/src/lit-locales/source/ko.xlf
@@ -45,6 +45,10 @@
   <source>Bulk report replies</source>
   <note from="lit-localize">Option shown in the settings menu of the thread toolbar which enables the "bulk report replies" feature.</note>
 </trans-unit>
+<trans-unit id="sb30734baa37281be">
+  <source>(Alt+R)</source>
+  <note from="lit-localize">Text shown below the "bulk report replies" feature, to let the user know that they can use this keyboard shortcut to toggle it.</note>
+</trans-unit>
     </body>
   </file>
 </xliff>
diff --git a/src/lit-locales/source/pl.xlf b/src/lit-locales/source/pl.xlf
index 4c08fa9..6c172e6 100644
--- a/src/lit-locales/source/pl.xlf
+++ b/src/lit-locales/source/pl.xlf
@@ -37,6 +37,10 @@
   <source>Bulk report replies</source>
   <note from="lit-localize">Option shown in the settings menu of the thread toolbar which enables the "bulk report replies" feature.</note>
 </trans-unit>
+<trans-unit id="sb30734baa37281be">
+  <source>(Alt+R)</source>
+  <note from="lit-localize">Text shown below the "bulk report replies" feature, to let the user know that they can use this keyboard shortcut to toggle it.</note>
+</trans-unit>
 </body>
 </file>
 </xliff>
diff --git a/src/lit-locales/source/pt_BR.xlf b/src/lit-locales/source/pt_BR.xlf
index ece9aad..7158267 100644
--- a/src/lit-locales/source/pt_BR.xlf
+++ b/src/lit-locales/source/pt_BR.xlf
@@ -37,6 +37,10 @@
   <source>Bulk report replies</source>
   <note from="lit-localize">Option shown in the settings menu of the thread toolbar which enables the "bulk report replies" feature.</note>
 </trans-unit>
+<trans-unit id="sb30734baa37281be">
+  <source>(Alt+R)</source>
+  <note from="lit-localize">Text shown below the "bulk report replies" feature, to let the user know that they can use this keyboard shortcut to toggle it.</note>
+</trans-unit>
 </body>
 </file>
 </xliff>
diff --git a/src/lit-locales/source/ru.xlf b/src/lit-locales/source/ru.xlf
index db843df..e9d137c 100644
--- a/src/lit-locales/source/ru.xlf
+++ b/src/lit-locales/source/ru.xlf
@@ -45,6 +45,10 @@
   <source>Bulk report replies</source>
   <note from="lit-localize">Option shown in the settings menu of the thread toolbar which enables the "bulk report replies" feature.</note>
 </trans-unit>
+<trans-unit id="sb30734baa37281be">
+  <source>(Alt+R)</source>
+  <note from="lit-localize">Text shown below the "bulk report replies" feature, to let the user know that they can use this keyboard shortcut to toggle it.</note>
+</trans-unit>
     </body>
   </file>
 </xliff>
diff --git a/src/lit-locales/source/th.xlf b/src/lit-locales/source/th.xlf
index 0ccee42..4e15096 100644
--- a/src/lit-locales/source/th.xlf
+++ b/src/lit-locales/source/th.xlf
@@ -37,6 +37,10 @@
   <source>Bulk report replies</source>
   <note from="lit-localize">Option shown in the settings menu of the thread toolbar which enables the "bulk report replies" feature.</note>
 </trans-unit>
+<trans-unit id="sb30734baa37281be">
+  <source>(Alt+R)</source>
+  <note from="lit-localize">Text shown below the "bulk report replies" feature, to let the user know that they can use this keyboard shortcut to toggle it.</note>
+</trans-unit>
 </body>
 </file>
 </xliff>
diff --git a/src/lit-locales/source/tr.xlf b/src/lit-locales/source/tr.xlf
index 4149755..e0325a4 100644
--- a/src/lit-locales/source/tr.xlf
+++ b/src/lit-locales/source/tr.xlf
@@ -37,6 +37,10 @@
   <source>Bulk report replies</source>
   <note from="lit-localize">Option shown in the settings menu of the thread toolbar which enables the "bulk report replies" feature.</note>
 </trans-unit>
+<trans-unit id="sb30734baa37281be">
+  <source>(Alt+R)</source>
+  <note from="lit-localize">Text shown below the "bulk report replies" feature, to let the user know that they can use this keyboard shortcut to toggle it.</note>
+</trans-unit>
 </body>
 </file>
 </xliff>
diff --git a/src/lit-locales/source/vi.xlf b/src/lit-locales/source/vi.xlf
index dc42ad3..b15fa71 100644
--- a/src/lit-locales/source/vi.xlf
+++ b/src/lit-locales/source/vi.xlf
@@ -37,6 +37,10 @@
   <source>Bulk report replies</source>
   <note from="lit-localize">Option shown in the settings menu of the thread toolbar which enables the "bulk report replies" feature.</note>
 </trans-unit>
+<trans-unit id="sb30734baa37281be">
+  <source>(Alt+R)</source>
+  <note from="lit-localize">Text shown below the "bulk report replies" feature, to let the user know that they can use this keyboard shortcut to toggle it.</note>
+</trans-unit>
 </body>
 </file>
 </xliff>
diff --git a/src/services/options/OptionsModifier.port.ts b/src/services/options/OptionsModifier.port.ts
new file mode 100644
index 0000000..97c7254
--- /dev/null
+++ b/src/services/options/OptionsModifier.port.ts
@@ -0,0 +1,11 @@
+import { OptionCodename, OptionsValues } from "../../common/options/optionsPrototype";
+
+/**
+ * Modifier in the sense that it allows users to modify/save options.
+ */
+export interface OptionsModifierPort {
+  set<O extends OptionCodename>(
+    option: O,
+    value: OptionsValues[O],
+  ): Promise<void>;
+}