Add experimental option to reduce whitespace

This reduces the excessive whitespace in the RCE thread page, and fixes
space issues in the thread list on mobile.

Bug: twpowertools:130
Change-Id: Ibd0c666fa7f6a9c89814e529ef7b80541143ada2
diff --git a/src/common/optionsPrototype.json5 b/src/common/optionsPrototype.json5
index 6b6e01b..0854647 100644
--- a/src/common/optionsPrototype.json5
+++ b/src/common/optionsPrototype.json5
@@ -151,6 +151,11 @@
     context: 'experiments',
     killSwitchType: 'experiment',
   },
+  'uispacing': {
+    defaultValue: false,
+    context: 'experiments',
+    killSwitchType: 'experiment',
+  },
 
   // Internal options:
   'ccdarktheme_switch_enabled': {
diff --git a/src/contentScripts/communityConsole/start.js b/src/contentScripts/communityConsole/start.js
index 1bb6a3f..02995e7 100644
--- a/src/contentScripts/communityConsole/start.js
+++ b/src/contentScripts/communityConsole/start.js
@@ -63,4 +63,9 @@
         break;
     }
   }
+
+  if (options.uispacing) {
+    injectStylesheet(chrome.runtime.getURL('css/ui_spacing/shared.css'));
+    injectStylesheet(chrome.runtime.getURL('css/ui_spacing/console.css'));
+  }
 });
diff --git a/src/contentScripts/publicThreadStart.js b/src/contentScripts/publicThreadStart.js
new file mode 100644
index 0000000..d1c4e3c
--- /dev/null
+++ b/src/contentScripts/publicThreadStart.js
@@ -0,0 +1,9 @@
+import {injectStylesheet} from '../common/contentScriptsUtils.js';
+import {isOptionEnabled} from '../common/optionsUtils.js';
+
+isOptionEnabled('uispacing').then(isUiSpacingEnabled => {
+  if (!isUiSpacingEnabled) return;
+
+  injectStylesheet(chrome.runtime.getURL('css/ui_spacing/shared.css'));
+  injectStylesheet(chrome.runtime.getURL('css/ui_spacing/twbasic.css'));
+});
diff --git a/src/static/_locales/en/messages.json b/src/static/_locales/en/messages.json
index 23e03f6..678066f 100644
--- a/src/static/_locales/en/messages.json
+++ b/src/static/_locales/en/messages.json
@@ -175,6 +175,10 @@
     "message": "Turn on the nested replies feature in the Community Console.",
     "description": "Feature checkbox in the options page"
   },
+  "options_uispacing": {
+    "message": "Reduce the whitespace in the Community Console and TW.",
+    "description": "Feature checkbox in the options page"
+  },
   "options_save": {
     "message": "Save",
     "description": "Button in the options page to save the settings"
diff --git a/src/static/css/ui_spacing/console.css b/src/static/css/ui_spacing/console.css
new file mode 100644
index 0000000..daa400e
--- /dev/null
+++ b/src/static/css/ui_spacing/console.css
@@ -0,0 +1,116 @@
+@media (max-width: 700px) {
+  /*
+   * == THREAD LIST VIEW ==
+   **/
+
+  /* Hide work state label when thread row is collapsed */
+  ec-thread-summary .thread-summary:not(.expanded) .issue-tracking-work-state {
+    display: none!important;
+  }
+}
+
+@media (max-width: 599px) {
+  /*
+   * == THREAD LIST VIEW ==
+   **/
+
+  /* Squeeze all elements in each row */
+  ec-thread-summary .issue-tracking-work-state {
+    display: none!important;
+  }
+
+  ec-thread-summary .title,
+      ec-thread-summary ec-second-summary-line .properties,
+      ec-thread-summary ec-second-summary-line ec-relative-time {
+    margin-inline-start: 0!important;
+    margin-inline-end: 8px!important;
+  }
+
+  ec-thread-summary ec-thread-counts,
+      ec-thread-summary ec-second-summary-line .icons {
+    width: auto!important;
+  }
+
+  ec-thread-list ec-bulk-actions {
+    padding-inline-start: 4px!important;
+    padding-inline-end: 0!important;
+  }
+
+  ec-thread-summary .panel {
+    padding-inline: 4px!important;
+  }
+
+  ec-thread-summary .panel > .main-header > .header.header {
+    padding-inline: 0!important;
+  }
+
+  body:not(.TWPT-threadlistavatars-enabled) ec-thread-summary div.header div.header-content {
+    width: calc(100% - 68px)!important;
+  }
+
+  body.TWPT-threadlistavatars-enabled ec-thread-summary div.header div.header-content {
+    width: calc(100% - 134px)!important;
+  }
+
+  .TWPT-avatars {
+    min-width: 62px!important;
+    margin-inline-start: 4px!important;
+  }
+
+  .TWPT-avatars .TWPT-avatar:first-child {
+    margin-inline-start: 2px!important;
+  }
+
+  .TWPT-avatars .TWPT-avatar,
+      .TWPT-avatars .TWPT-avatar-private-placeholder {
+    height: 22px!important;
+    width: 22px!important;
+  }
+
+  ec-thread-summary .header.header .checkbox {
+    min-width: 32px!important;
+  }
+
+  ec-thread-summary .header.header .checkbox material-checkbox {
+    margin: 8px 4px!important;
+  }
+
+  ec-thread-summary .header.header .star-button {
+    margin-inline-start: 0!important;
+    margin-inline-end: 4px!important;
+  }
+
+  ec-thread-summary .header.header .star-button .content {
+    padding: 8px 4px!important;
+  }
+
+  ec-thread-summary .action .expand-container {
+    padding-inline: 0!important;
+  }
+
+  ec-thread-summary .action .expand-container .expand-button {
+    width: 32px;
+  }
+
+  ec-thread-summary .action .expand-container .expand-button > .content {
+    padding: 8px 4px!important;
+  }
+
+  ec-thread-summary .thread-summary.expanded .main.main .content-wrapper {
+    margin: 0 12px 16px!important;
+  }
+
+  ec-thread-summary .thread-summary.expanded .main.main .content-wrapper > .content > .content {
+    padding-inline: 56px 30px!important;
+    padding-block: 0!important;
+  }
+}
+
+@media (min-width: 37.5rem) {
+  /*
+   * == THREAD VIEW ==
+   **/
+  .scTailwindThreadQuestionQuestioncardcontent {
+    padding: 2rem 3rem 1.5rem 3rem!important;
+  }
+}
diff --git a/src/static/css/ui_spacing/shared.css b/src/static/css/ui_spacing/shared.css
new file mode 100644
index 0000000..19be735
--- /dev/null
+++ b/src/static/css/ui_spacing/shared.css
@@ -0,0 +1,52 @@
+.scTailwindThreadQuestionQuestioncardtitle-container {
+  gap: 0 1rem!important;
+  margin: 1rem 0!important;
+}
+
+.scTailwindThreadQuestionQuestioncardcontent {
+  padding: 1.5rem 1rem 1rem 1rem!important;
+}
+
+.scTailwindThreadQuestionQuestioncardsub-content {
+  padding: 0 1rem 1rem!important;
+}
+
+.scTailwindThreadMessageMessagecardcontent,
+    .scTailwindThreadMessageMessagecardnested-reply {
+  padding: 1rem!important;
+}
+
+.scTailwindThreadMessagegapmore-nested-replies {
+  padding: 0.25rem 1rem!important;
+}
+
+sc-tailwind-thread-post-header {
+  margin-bottom: 0!important;
+}
+
+.scTailwindThreadMessageMessagelistmessage-card {
+  padding-bottom: 0.75rem!important;
+}
+
+h3.scTailwindThreadMessageMessagelistheading {
+  margin: 1rem 0!important;
+}
+
+.scTailwindThreadMorebuttonroot {
+  margin: 0 0 0.75rem 0!important;
+}
+
+@media (min-width: 37.5rem) {
+  .scTailwindThreadMessageMessagecardcontent,
+      .scTailwindThreadMessageMessagecardnested-reply {
+    padding: 1rem 3rem!important;
+  }
+
+  .scTailwindThreadMessagegapmore-nested-replies {
+    padding: 0.25rem 3rem!important;
+  }
+
+  .scTailwindThreadQuestionQuestioncardsub-content {
+    padding: 0 3rem 1rem!important;
+  }
+}
diff --git a/src/static/css/ui_spacing/twbasic.css b/src/static/css/ui_spacing/twbasic.css
new file mode 100644
index 0000000..f0ddb75
--- /dev/null
+++ b/src/static/css/ui_spacing/twbasic.css
@@ -0,0 +1,9 @@
+.page {
+  margin: 0!important;
+}
+
+@media (min-width: 37.5rem) {
+  .scTailwindThreadQuestionQuestioncardcontent {
+    padding: 2rem 3rem!important;
+  }
+}
diff --git a/src/static/options/experiments.html b/src/static/options/experiments.html
index 615d5ec..5eddef5 100644
--- a/src/static/options/experiments.html
+++ b/src/static/options/experiments.html
@@ -16,6 +16,7 @@
         <div class="option"><input type="checkbox" id="workflows"> <label for="workflows" data-i18n="workflows"></label> <button id="manage-workflows" data-i18n="workflows_manage"></button></div>
         <div class="option"><input type="checkbox" id="extrainfo"> <label for="extrainfo" data-i18n="extrainfo"></label></div>
         <div class="option"><input type="checkbox" id="nestedreplies"> <label for="nestedreplies" data-i18n="nestedreplies"></label></div>
+        <div class="option"><input type="checkbox" id="uispacing"> <label for="uispacing" data-i18n="uispacing"></label></div>
         <div class="actions"><button id="save" data-i18n="save"></button></div>
       </form>
       <div id="save-indicator"></div>
diff --git a/templates/manifest.gjson b/templates/manifest.gjson
index e1fa94f..d649b71 100644
--- a/templates/manifest.gjson
+++ b/templates/manifest.gjson
@@ -33,6 +33,12 @@
     {
       "matches": ["https://support.google.com/*/thread/*"],
       "exclude_matches": ["https://support.google.com/s/community*", "https://support.google.com/*/thread/new*"],
+      "js": ["publicThreadStart.bundle.js"],
+      "run_at": "document_start"
+    },
+    {
+      "matches": ["https://support.google.com/*/thread/*"],
+      "exclude_matches": ["https://support.google.com/s/community*", "https://support.google.com/*/thread/new*"],
       "js": ["publicThread.bundle.js", "mdcStyles.bundle.js"],
       "run_at": "document_end"
     },
@@ -89,11 +95,15 @@
         "css/image_max_height.css",
         "css/extrainfo.css",
         "css/extrainfo_perforumstats.css",
+        "css/ui_spacing/shared.css",
+        "css/ui_spacing/console.css",
+        "css/ui_spacing/twbasic.css",
 
         "communityConsoleMain.bundle.js.map",
         "communityConsoleStart.bundle.js.map",
         "publicForum.bundle.js.map",
         "publicThread.bundle.js.map",
+        "publicThreadStart.bundle.js.map",
         "profile.bundle.js.map",
         "profileIndicator.bundle.js.map",
         "profileIndicatorInject.bundle.js.map",
diff --git a/webpack.config.js b/webpack.config.js
index bceb4c0..3591c97 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -42,6 +42,7 @@
     communityConsoleStart: './src/contentScripts/communityConsole/start.js',
     publicForum: './src/contentScripts/publicForum.js',
     publicThread: './src/contentScripts/publicThread.js',
+    publicThreadStart: './src/contentScripts/publicThreadStart.js',
     publicProfile: './src/contentScripts/publicProfile.js',
     publicProfileStart: './src/contentScripts/publicProfileStart.js',
     profileIndicator: './src/contentScripts/profileIndicator.js',