From 59913abe119d0b1e16fbfa52d33032cbaf2d5566 Mon Sep 17 00:00:00 2001
From: FrogTheFrog <warliukz@gmail.com>
Date: Mon, 16 Dec 2024 20:12:44 +0200
Subject: [PATCH] feat(web-ui): replace dropdown menus with checkboxes

---
 src_assets/common/assets/web/apps.html        |   8 +-
 .../assets/web/configs/tabs/Advanced.vue      |   2 +-
 .../assets/web/configs/tabs/AudioVideo.vue    |   9 +-
 .../common/assets/web/configs/tabs/Files.vue  |   2 +-
 .../assets/web/configs/tabs/General.vue       |  15 +-
 .../common/assets/web/configs/tabs/Inputs.vue | 159 +++++++-----------
 .../assets/web/configs/tabs/Network.vue       |  11 +-
 .../tabs/audiovideo/AdapterNameSelector.vue   |   2 +-
 .../tabs/audiovideo/DisplayModesSettings.vue  |  13 +-
 .../configs/tabs/encoders/AmdAmfEncoder.vue   |  31 ++--
 .../tabs/encoders/IntelQuickSyncEncoder.vue   |  10 +-
 .../tabs/encoders/NvidiaNvencEncoder.vue      |  36 ++--
 .../configs/tabs/encoders/SoftwareEncoder.vue |   2 +-
 .../assets/web/public/assets/locale/en.json   |   5 +-
 14 files changed, 118 insertions(+), 187 deletions(-)

diff --git a/src_assets/common/assets/web/apps.html b/src_assets/common/assets/web/apps.html
index e10ce0262fb..e27edb099aa 100644
--- a/src_assets/common/assets/web/apps.html
+++ b/src_assets/common/assets/web/apps.html
@@ -152,7 +152,7 @@ <h1>{{ $t('apps.applications_title') }}</h1>
                 <td>
                   <input type="text" class="form-control monospace" v-model="c.undo" />
                 </td>
-                <td v-if="platform === 'windows'">
+                <td v-if="platform === 'windows'" class="align-middle">
                   <div class="form-check">
                     <input type="checkbox" class="form-check-input" :id="'prep-cmd-admin-' + i" v-model="c.elevated"
                       true-value="true" false-value="false" />
@@ -209,21 +209,21 @@ <h1>{{ $t('apps.applications_title') }}</h1>
         </div>
         <!-- elevation -->
         <div class="mb-3 form-check" v-if="platform === 'windows'">
-          <label for="appElevation" class="form-check-label">{{ $t('_common.run_as') }}</label>
+          <label for="appElevation" class="form-check-label">{{ $t('_common.run_as') }}<div class="mt-0 form-text">{{ $t('_common.disabled_def_cbox') }}</div></label>
           <input type="checkbox" class="form-check-input" id="appElevation" v-model="editForm.elevated"
             true-value="true" false-value="false" />
           <div class="form-text">{{ $t('apps.run_as_desc') }}</div>
         </div>
         <!-- auto-detach -->
         <div class="mb-3 form-check">
-          <label for="autoDetach" class="form-check-label">{{ $t('apps.auto_detach') }}</label>
+          <label for="autoDetach" class="form-check-label">{{ $t('apps.auto_detach') }}<div class="mt-0 form-text">{{ $t('_common.enabled_def_cbox') }}</div></label>
           <input type="checkbox" class="form-check-input" id="autoDetach" v-model="editForm['auto-detach']"
             true-value="true" false-value="false" />
           <div class="form-text">{{ $t('apps.auto_detach_desc') }}</div>
         </div>
         <!-- wait for all processes -->
         <div class="mb-3 form-check">
-          <label for="waitAll" class="form-check-label">{{ $t('apps.wait_all') }}</label>
+          <label for="waitAll" class="form-check-label">{{ $t('apps.wait_all') }}<div class="mt-0 form-text">{{ $t('_common.enabled_def_cbox') }}</div></label>
           <input type="checkbox" class="form-check-input" id="waitAll" v-model="editForm['wait-all']"
             true-value="true" false-value="false" />
           <div class="form-text">{{ $t('apps.wait_all_desc') }}</div>
diff --git a/src_assets/common/assets/web/configs/tabs/Advanced.vue b/src_assets/common/assets/web/configs/tabs/Advanced.vue
index bd11adf2892..ff23e354230 100644
--- a/src_assets/common/assets/web/configs/tabs/Advanced.vue
+++ b/src_assets/common/assets/web/configs/tabs/Advanced.vue
@@ -80,7 +80,7 @@ const config = ref(props.config)
     </div>
 
     <!-- Encoder -->
-    <div class="mb-3">
+    <div>
       <label for="encoder" class="form-label">{{ $t('config.encoder') }}</label>
       <select id="encoder" class="form-select" v-model="config.encoder">
         <option value="">{{ $t('_common.autodetect') }}</option>
diff --git a/src_assets/common/assets/web/configs/tabs/AudioVideo.vue b/src_assets/common/assets/web/configs/tabs/AudioVideo.vue
index 0f18f9a14dc..b9e2019ae85 100644
--- a/src_assets/common/assets/web/configs/tabs/AudioVideo.vue
+++ b/src_assets/common/assets/web/configs/tabs/AudioVideo.vue
@@ -54,12 +54,9 @@ const config = ref(props.config)
         </div>
 
         <!-- Install Steam Audio Drivers -->
-        <div class="mb-3">
-          <label for="install_steam_audio_drivers" class="form-label">{{ $t('config.install_steam_audio_drivers') }}</label>
-          <select id="install_steam_audio_drivers" class="form-select" v-model="config.install_steam_audio_drivers">
-            <option value="disabled">{{ $t('_common.disabled') }}</option>
-            <option value="enabled">{{ $t('_common.enabled_def') }}</option>
-          </select>
+        <div class="mb-3 form-check">
+          <label for="install_steam_audio_drivers" class="form-label">{{ $t('config.install_steam_audio_drivers') }}<div class="mt-0 form-text">{{ $t('_common.enabled_def_cbox') }}</div></label>
+          <input type="checkbox" class="form-check-input" id="install_steam_audio_drivers" v-model="config.install_steam_audio_drivers" true-value="enabled" false-value="disabled" />
           <div class="form-text">{{ $t('config.install_steam_audio_drivers_desc') }}</div>
         </div>
       </template>
diff --git a/src_assets/common/assets/web/configs/tabs/Files.vue b/src_assets/common/assets/web/configs/tabs/Files.vue
index 87b8f9500e7..0cd41d92915 100644
--- a/src_assets/common/assets/web/configs/tabs/Files.vue
+++ b/src_assets/common/assets/web/configs/tabs/Files.vue
@@ -47,7 +47,7 @@ const config = ref(props.config)
     </div>
 
     <!-- State File -->
-    <div class="mb-3">
+    <div>
       <label for="file_state" class="form-label">{{ $t('config.file_state') }}</label>
       <input type="text" class="form-control" id="file_state" placeholder="sunshine_state.json"
              v-model="config.file_state" />
diff --git a/src_assets/common/assets/web/configs/tabs/General.vue b/src_assets/common/assets/web/configs/tabs/General.vue
index 5349a3c46ef..c1eaf6eccd3 100644
--- a/src_assets/common/assets/web/configs/tabs/General.vue
+++ b/src_assets/common/assets/web/configs/tabs/General.vue
@@ -96,11 +96,11 @@ function removeCmd(index) {
           <td>
             <input type="text" class="form-control monospace" v-model="c.undo" />
           </td>
-          <td v-if="platform === 'windows'">
+          <td v-if="platform === 'windows'" class="align-middle">
             <div class="form-check">
               <input type="checkbox" class="form-check-input" :id="'prep-cmd-admin-' + i" v-model="c.elevated"
                      true-value="true" false-value="false" />
-              <label :for="'prep-cmd-admin-' + i" class="form-check-label">{{ $t('config.elevated') }}</label>
+              <label :for="'prep-cmd-admin-' + i" class="form-check-label">{{ $t('_common.elevated') }}</label>
             </div>
           </td>
           <td>
@@ -120,13 +120,10 @@ function removeCmd(index) {
     </div>
 
     <!-- Notify Pre-Releases -->
-    <div class="mb-3">
-        <label for="notify_pre_releases" class="form-label">{{ $t('config.notify_pre_releases') }}</label>
-        <select id="notify_pre_releases" class="form-select" v-model="config.notify_pre_releases">
-            <option value="disabled">{{ $t('_common.disabled') }}</option>
-            <option value="enabled">{{ $t('_common.enabled') }}</option>
-        </select>
-        <div class="form-text">{{ $t('config.notify_pre_releases_desc') }}</div>
+    <div class="form-check">
+      <label for="notify_pre_releases" class="form-label">{{ $t('config.notify_pre_releases') }}<div class="mt-0 form-text">{{ $t('_common.disabled_def_cbox') }}</div></label>
+      <input type="checkbox" class="form-check-input" id="notify_pre_releases" v-model="config.notify_pre_releases" true-value="enabled" false-value="disabled" />
+      <div class="form-text">{{ $t('config.notify_pre_releases_desc') }}</div>
     </div>
   </div>
 </template>
diff --git a/src_assets/common/assets/web/configs/tabs/Inputs.vue b/src_assets/common/assets/web/configs/tabs/Inputs.vue
index a2f0c249dfc..dd80deae41f 100644
--- a/src_assets/common/assets/web/configs/tabs/Inputs.vue
+++ b/src_assets/common/assets/web/configs/tabs/Inputs.vue
@@ -13,12 +13,9 @@ const config = ref(props.config)
 <template>
   <div id="input" class="config-page">
     <!-- Enable Gamepad Input -->
-    <div class="mb-3">
-      <label for="controller" class="form-label">{{ $t('config.controller') }}</label>
-      <select id="controller" class="form-select" v-model="config.controller">
-        <option value="disabled">{{ $t('_common.disabled') }}</option>
-        <option value="enabled">{{ $t('_common.enabled') }}</option>
-      </select>
+    <div class="mb-3 form-check">
+      <label for="controller" class="form-label">{{ $t('config.controller') }}<div class="mt-0 form-text">{{ $t('_common.enabled_def_cbox') }}</div></label>
+      <input type="checkbox" class="form-check-input" id="controller" v-model="config.controller" true-value="enabled" false-value="disabled" />
       <div class="form-text">{{ $t('config.controller_desc') }}</div>
     </div>
 
@@ -44,63 +41,50 @@ const config = ref(props.config)
       <div class="form-text">{{ $t('config.gamepad_desc') }}</div>
     </div>
 
-    <div class="accordion" v-if="config.gamepad === 'ds4'">
-      <div class="accordion-item">
-        <h2 class="accordion-header">
-          <button class="accordion-button" type="button" data-bs-toggle="collapse"
-                  data-bs-target="#panelsStayOpen-collapseOne">
-            {{ $t('config.gamepad_ds4_manual') }}
-          </button>
-        </h2>
-        <div id="panelsStayOpen-collapseOne" class="accordion-collapse collapse show"
-             aria-labelledby="panelsStayOpen-headingOne">
-          <div class="accordion-body">
-            <div>
-              <label for="ds4_back_as_touchpad_click" class="form-label">{{ $t('config.ds4_back_as_touchpad_click') }}</label>
-              <select id="ds4_back_as_touchpad_click" class="form-select"
-                      v-model="config.ds4_back_as_touchpad_click">
-                <option value="disabled">{{ $t('_common.disabled') }}</option>
-                <option value="enabled">{{ $t('_common.enabled_def') }}</option>
-              </select>
-              <div class="form-text">{{ $t('config.ds4_back_as_touchpad_click_desc') }}</div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-    <div class="accordion" v-if="config.controller === 'enabled' && config.gamepad === 'auto' && platform === 'windows'">
-      <div class="accordion-item">
-        <h2 class="accordion-header">
-          <button class="accordion-button" type="button" data-bs-toggle="collapse"
-                  data-bs-target="#panelsStayOpen-collapseOne">
-            {{ $t('config.gamepad_auto') }}
-          </button>
-        </h2>
-        <div id="panelsStayOpen-collapseOne" class="accordion-collapse collapse show"
-             aria-labelledby="panelsStayOpen-headingOne">
-          <div class="accordion-body">
-            <div>
-              <label for="motion_as_ds4" class="form-label">{{ $t('config.motion_as_ds4') }}</label>
-              <select id="motion_as_ds4" class="form-select"
-                      v-model="config.motion_as_ds4">
-                <option value="disabled">{{ $t('_common.disabled') }}</option>
-                <option value="enabled">{{ $t('_common.enabled_def') }}</option>
-              </select>
-              <div class="form-text">{{ $t('config.motion_as_ds4_desc') }}</div>
-            </div>
-            <div>
-              <label for="touchpad_as_ds4" class="form-label">{{ $t('config.touchpad_as_ds4') }}</label>
-              <select id="touchpad_as_ds4" class="form-select"
-                      v-model="config.touchpad_as_ds4">
-                <option value="disabled">{{ $t('_common.disabled') }}</option>
-                <option value="enabled">{{ $t('_common.enabled_def') }}</option>
-              </select>
-              <div class="form-text">{{ $t('config.touchpad_as_ds4_desc') }}</div>
+    <!-- Additional options based on gamepad type -->
+    <template v-if="config.controller === 'enabled'">
+      <template v-if="config.gamepad === 'ds4' || (config.gamepad === 'auto' && platform === 'windows')">
+        <div class="mb-3 accordion">
+          <div class="accordion-item">
+            <h2 class="accordion-header">
+              <button class="accordion-button" type="button" data-bs-toggle="collapse"
+                      data-bs-target="#panelsStayOpen-collapseOne">
+                {{ $t(config.gamepad === 'ds4' ? 'config.gamepad_ds4_manual' : 'config.gamepad_auto') }}
+              </button>
+            </h2>
+            <div id="panelsStayOpen-collapseOne" class="accordion-collapse collapse show"
+                 aria-labelledby="panelsStayOpen-headingOne">
+              <div class="accordion-body">
+                <!-- Auto options (Windows only) -->
+                <template v-if="config.gamepad === 'auto'">
+                  <!-- DS4 motion -->
+                  <div class="mb-3 form-check">
+                    <label for="motion_as_ds4" class="form-label">{{ $t('config.motion_as_ds4') }}<div class="mt-0 form-text">{{ $t('_common.enabled_def_cbox') }}</div></label>
+                    <input type="checkbox" class="form-check-input" id="motion_as_ds4" v-model="config.motion_as_ds4" true-value="enabled" false-value="disabled" />
+                    <div class="form-text">{{ $t('config.motion_as_ds4_desc') }}</div>
+                  </div>
+                  <!-- DS4 touchpad -->
+                  <div class="form-check">
+                    <label for="touchpad_as_ds4" class="form-label">{{ $t('config.touchpad_as_ds4') }}<div class="mt-0 form-text">{{ $t('_common.enabled_def_cbox') }}</div></label>
+                    <input type="checkbox" class="form-check-input" id="touchpad_as_ds4" v-model="config.touchpad_as_ds4" true-value="enabled" false-value="disabled" />
+                    <div class="form-text">{{ $t('config.touchpad_as_ds4_desc') }}</div>
+                  </div>
+                </template>
+                <!-- DS4 options (all platforms) -->
+                <template v-if="config.gamepad === 'ds4'">
+                  <!-- DS4 back button as touchpad click -->
+                  <div class="form-check">
+                    <label for="ds4_back_as_touchpad_click" class="form-label">{{ $t('config.ds4_back_as_touchpad_click') }}<div class="mt-0 form-text">{{ $t('_common.enabled_def_cbox') }}</div></label>
+                    <input type="checkbox" class="form-check-input" id="ds4_back_as_touchpad_click" v-model="config.ds4_back_as_touchpad_click" true-value="enabled" false-value="disabled" />
+                    <div class="form-text">{{ $t('config.ds4_back_as_touchpad_click_desc') }}</div>
+                  </div>
+                </template>
+              </div>
             </div>
           </div>
         </div>
-      </div>
-    </div>
+      </template>
+    </template>
 
     <!-- Home/Guide Button Emulation Timeout -->
     <div class="mb-3" v-if="config.controller === 'enabled'">
@@ -112,12 +96,9 @@ const config = ref(props.config)
 
     <!-- Enable Keyboard Input -->
     <hr>
-    <div class="mb-3">
-      <label for="keyboard" class="form-label">{{ $t('config.keyboard') }}</label>
-      <select id="keyboard" class="form-select" v-model="config.keyboard">
-        <option value="disabled">{{ $t('_common.disabled') }}</option>
-        <option value="enabled">{{ $t('_common.enabled_def') }}</option>
-      </select>
+    <div class="mb-3 form-check">
+      <label for="keyboard" class="form-label">{{ $t('config.keyboard') }}<div class="mt-0 form-text">{{ $t('_common.enabled_def_cbox') }}</div></label>
+      <input type="checkbox" class="form-check-input" id="keyboard" v-model="config.keyboard" true-value="enabled" false-value="disabled" />
       <div class="form-text">{{ $t('config.keyboard_desc') }}</div>
     </div>
 
@@ -138,56 +119,40 @@ const config = ref(props.config)
     </div>
 
     <!-- Always send scancodes -->
-    <div class="mb-3" v-if="config.keyboard === 'enabled' && platform === 'windows'">
-      <label for="always_send_scancodes" class="form-label">{{ $t('config.always_send_scancodes') }}</label>
-      <select id="always_send_scancodes" class="form-select" v-model="config.always_send_scancodes">
-        <option value="disabled">{{ $t('_common.disabled') }}</option>
-        <option value="enabled">{{ $t('_common.enabled_def') }}</option>
-      </select>
+    <div class="mb-3 form-check" v-if="config.keyboard === 'enabled' && platform === 'windows'">
+      <label for="always_send_scancodes" class="form-label">{{ $t('config.always_send_scancodes') }}<div class="mt-0 form-text">{{ $t('_common.enabled_def_cbox') }}</div></label>
+      <input type="checkbox" class="form-check-input" id="always_send_scancodes" v-model="config.always_send_scancodes" true-value="enabled" false-value="disabled" />
       <div class="form-text">{{ $t('config.always_send_scancodes_desc') }}</div>
     </div>
 
     <!-- Mapping Key AltRight to Key Windows -->
-    <div class="mb-3" v-if="config.keyboard === 'enabled'">
-      <label for="key_rightalt_to_key_win" class="form-label">{{ $t('config.key_rightalt_to_key_win') }}</label>
-      <select id="key_rightalt_to_key_win" class="form-select" v-model="config.key_rightalt_to_key_win">
-        <option value="disabled">{{ $t('_common.disabled') }}</option>
-        <option value="enabled">{{ $t('_common.enabled_def') }}</option>
-      </select>
+    <div class="mb-3 form-check" v-if="config.keyboard === 'enabled'">
+      <label for="key_rightalt_to_key_win" class="form-label">{{ $t('config.key_rightalt_to_key_win') }}<div class="mt-0 form-text">{{ $t('_common.disabled_def_cbox') }}</div></label>
+      <input type="checkbox" class="form-check-input" id="key_rightalt_to_key_win" v-model="config.key_rightalt_to_key_win" true-value="enabled" false-value="disabled" />
       <div class="form-text">{{ $t('config.key_rightalt_to_key_win_desc') }}</div>
     </div>
 
     <!-- Enable Mouse Input -->
     <hr>
-    <div class="mb-3">
-      <label for="mouse" class="form-label">{{ $t('config.mouse') }}</label>
-      <select id="mouse" class="form-select" v-model="config.mouse">
-        <option value="disabled">{{ $t('_common.disabled') }}</option>
-        <option value="enabled">{{ $t('_common.enabled_def') }}</option>
-      </select>
+    <div class="mb-3 form-check">
+      <label for="mouse" class="form-label">{{ $t('config.mouse') }}<div class="mt-0 form-text">{{ $t('_common.enabled_def_cbox') }}</div></label>
+      <input type="checkbox" class="form-check-input" id="mouse" v-model="config.mouse" true-value="enabled" false-value="disabled" />
       <div class="form-text">{{ $t('config.mouse_desc') }}</div>
     </div>
 
     <!-- High resolution scrolling support -->
-    <div class="mb-3" v-if="config.mouse === 'enabled'">
-      <label for="high_resolution_scrolling" class="form-label">{{ $t('config.high_resolution_scrolling') }}</label>
-      <select id="high_resolution_scrolling" class="form-select" v-model="config.high_resolution_scrolling">
-        <option value="disabled">{{ $t('_common.disabled') }}</option>
-        <option value="enabled">{{ $t('_common.enabled_def') }}</option>
-      </select>
+    <div class="mb-3 form-check" v-if="config.mouse === 'enabled'">
+      <label for="high_resolution_scrolling" class="form-label">{{ $t('config.high_resolution_scrolling') }}<div class="mt-0 form-text">{{ $t('_common.enabled_def_cbox') }}</div></label>
+      <input type="checkbox" class="form-check-input" id="high_resolution_scrolling" v-model="config.high_resolution_scrolling" true-value="enabled" false-value="disabled" />
       <div class="form-text">{{ $t('config.high_resolution_scrolling_desc') }}</div>
     </div>
 
     <!-- Native pen/touch support -->
-    <div class="mb-3" v-if="config.mouse === 'enabled'">
-      <label for="native_pen_touch" class="form-label">{{ $t('config.native_pen_touch') }}</label>
-      <select id="native_pen_touch" class="form-select" v-model="config.native_pen_touch">
-        <option value="disabled">{{ $t('_common.disabled') }}</option>
-        <option value="enabled">{{ $t('_common.enabled_def') }}</option>
-      </select>
+    <div class="form-check" v-if="config.mouse === 'enabled'">
+      <label for="native_pen_touch" class="form-label">{{ $t('config.native_pen_touch') }}<div class="mt-0 form-text">{{ $t('_common.enabled_def_cbox') }}</div></label>
+      <input type="checkbox" class="form-check-input" id="native_pen_touch" v-model="config.native_pen_touch" true-value="enabled" false-value="disabled" />
       <div class="form-text">{{ $t('config.native_pen_touch_desc') }}</div>
     </div>
-
   </div>
 </template>
 
diff --git a/src_assets/common/assets/web/configs/tabs/Network.vue b/src_assets/common/assets/web/configs/tabs/Network.vue
index b32074a599c..48834a90e51 100644
--- a/src_assets/common/assets/web/configs/tabs/Network.vue
+++ b/src_assets/common/assets/web/configs/tabs/Network.vue
@@ -15,12 +15,9 @@ const effectivePort = computed(() => +config.value?.port ?? defaultMoonlightPort
 <template>
   <div id="network" class="config-page">
     <!-- UPnP -->
-    <div class="mb-3">
-      <label for="upnp" class="form-label">{{ $t('config.upnp') }}</label>
-      <select id="upnp" class="form-select" v-model="config.upnp">
-        <option value="disabled">{{ $t('_common.disabled_def') }}</option>
-        <option value="enabled">{{ $t('_common.enabled') }}</option>
-      </select>
+    <div class="mb-3 form-check">
+      <label for="upnp" class="form-label">{{ $t('config.upnp') }}<div class="mt-0 form-text">{{ $t('_common.disabled_def_cbox') }}</div></label>
+      <input type="checkbox" class="form-check-input" id="upnp" v-model="config.upnp" true-value="enabled" false-value="disabled" />
       <div class="form-text">{{ $t('config.upnp_desc') }}</div>
     </div>
 
@@ -147,7 +144,7 @@ const effectivePort = computed(() => +config.value?.port ?? defaultMoonlightPort
     </div>
 
     <!-- Ping Timeout -->
-    <div class="mb-3">
+    <div>
       <label for="ping_timeout" class="form-label">{{ $t('config.ping_timeout') }}</label>
       <input type="text" class="form-control" id="ping_timeout" placeholder="10000" v-model="config.ping_timeout" />
       <div class="form-text">{{ $t('config.ping_timeout_desc') }}</div>
diff --git a/src_assets/common/assets/web/configs/tabs/audiovideo/AdapterNameSelector.vue b/src_assets/common/assets/web/configs/tabs/audiovideo/AdapterNameSelector.vue
index 8fa94ce8b05..59b2a12a911 100644
--- a/src_assets/common/assets/web/configs/tabs/audiovideo/AdapterNameSelector.vue
+++ b/src_assets/common/assets/web/configs/tabs/audiovideo/AdapterNameSelector.vue
@@ -20,7 +20,7 @@ const config = ref(props.config)
     <div class="form-text">
       <PlatformLayout :platform="platform">
         <template #windows>
-          {{ $t('config.adapter_name_desc_win') }}<br>
+          {{ $t('config.adapter_name_desc_windows') }}<br>
           <pre>tools\dxgi-info.exe</pre>
         </template>
         <template #linux>
diff --git a/src_assets/common/assets/web/configs/tabs/audiovideo/DisplayModesSettings.vue b/src_assets/common/assets/web/configs/tabs/audiovideo/DisplayModesSettings.vue
index b901e1ca4a3..d893d08bf01 100644
--- a/src_assets/common/assets/web/configs/tabs/audiovideo/DisplayModesSettings.vue
+++ b/src_assets/common/assets/web/configs/tabs/audiovideo/DisplayModesSettings.vue
@@ -16,14 +16,11 @@ const fpsIn = ref("")
 </script>
 
 <template>
-  <div class="mb-3">
-    <!--min_fps_factor-->
-    <div class="mb-3">
-      <label for="qp" class="form-label">{{ $t('config.min_fps_factor') }}</label>
-      <input type="number" min="1" max="3" class="form-control" id="min_fps_factor" placeholder="1" v-model="config.min_fps_factor" />
-      <div class="form-text">{{ $t('config.min_fps_factor_desc') }}</div>
-    </div>
-
+  <!--min_fps_factor-->
+  <div>
+    <label for="qp" class="form-label">{{ $t('config.min_fps_factor') }}</label>
+    <input type="number" min="1" max="3" class="form-control" id="min_fps_factor" placeholder="1" v-model="config.min_fps_factor" />
+    <div class="form-text">{{ $t('config.min_fps_factor_desc') }}</div>
   </div>
 </template>
 
diff --git a/src_assets/common/assets/web/configs/tabs/encoders/AmdAmfEncoder.vue b/src_assets/common/assets/web/configs/tabs/encoders/AmdAmfEncoder.vue
index 209df9a76fd..524426f5934 100644
--- a/src_assets/common/assets/web/configs/tabs/encoders/AmdAmfEncoder.vue
+++ b/src_assets/common/assets/web/configs/tabs/encoders/AmdAmfEncoder.vue
@@ -25,7 +25,7 @@ const config = ref(props.config)
     </div>
 
     <!-- AMD Rate Control group options -->
-    <div class="accordion">
+    <div class="mb-3 accordion">
       <div class="accordion-item">
         <h2 class="accordion-header">
           <button class="accordion-button" type="button" data-bs-toggle="collapse"
@@ -49,12 +49,9 @@ const config = ref(props.config)
             </div>
 
             <!-- AMF HRD Enforcement -->
-            <div class="mb-3">
-              <label for="amd_enforce_hrd" class="form-label">{{ $t('config.amd_enforce_hrd') }}</label>
-              <select id="amd_enforce_hrd" class="form-select" v-model="config.amd_enforce_hrd">
-                <option value="enabled">{{ $t('_common.enabled') }}</option>
-                <option value="disabled">{{ $t('_common.disabled_def') }}</option>
-              </select>
+            <div class="form-check">
+              <label for="amd_enforce_hrd" class="form-label">{{ $t('config.amd_enforce_hrd') }}<div class="mt-0 form-text">{{ $t('_common.disabled_def_cbox') }}</div></label>
+              <input type="checkbox" class="form-check-input" id="amd_enforce_hrd" v-model="config.amd_enforce_hrd" true-value="enabled" false-value="disabled" />
               <div class="form-text">{{ $t('config.amd_enforce_hrd_desc') }}</div>
             </div>
           </div>
@@ -86,27 +83,21 @@ const config = ref(props.config)
             </div>
 
             <!-- AMD Preanalysis -->
-            <div class="mb-3">
-              <label for="amd_preanalysis" class="form-label">{{ $t('config.amd_preanalysis') }}</label>
-              <select id="amd_preanalysis" class="form-select" v-model="config.amd_preanalysis">
-                <option value="disabled">{{ $t('_common.disabled_def') }}</option>
-                <option value="enabled">{{ $t('_common.enabled') }}</option>
-              </select>
+            <div class="mb-3 form-check">
+              <label for="amd_preanalysis" class="form-label">{{ $t('config.amd_preanalysis') }}<div class="mt-0 form-text">{{ $t('_common.disabled_def_cbox') }}</div></label>
+              <input type="checkbox" class="form-check-input" id="amd_preanalysis" v-model="config.amd_preanalysis" true-value="enabled" false-value="disabled" />
               <div class="form-text">{{ $t('config.amd_preanalysis_desc') }}</div>
             </div>
 
             <!-- AMD VBAQ -->
-            <div class="mb-3">
-              <label for="amd_vbaq" class="form-label">{{ $t('config.amd_vbaq') }}</label>
-              <select id="amd_vbaq" class="form-select" v-model="config.amd_vbaq">
-                <option value="disabled">{{ $t('_common.disabled') }}</option>
-                <option value="enabled">{{ $t('_common.enabled_def') }}</option>
-              </select>
+            <div class="mb-3 form-check">
+              <label for="amd_vbaq" class="form-label">{{ $t('config.amd_vbaq') }}<div class="mt-0 form-text">{{ $t('_common.enabled_def_cbox') }}</div></label>
+              <input type="checkbox" class="form-check-input" id="amd_vbaq" v-model="config.amd_vbaq" true-value="enabled" false-value="disabled" />
               <div class="form-text">{{ $t('config.amd_vbaq_desc') }}</div>
             </div>
 
             <!-- AMF Coder (H264) -->
-            <div class="mb-3">
+            <div>
               <label for="amd_coder" class="form-label">{{ $t('config.amd_coder') }}</label>
               <select id="amd_coder" class="form-select" v-model="config.amd_coder">
                 <option value="auto">{{ $t('config.ffmpeg_auto') }}</option>
diff --git a/src_assets/common/assets/web/configs/tabs/encoders/IntelQuickSyncEncoder.vue b/src_assets/common/assets/web/configs/tabs/encoders/IntelQuickSyncEncoder.vue
index 6b88b8b79bc..440b65f81ab 100644
--- a/src_assets/common/assets/web/configs/tabs/encoders/IntelQuickSyncEncoder.vue
+++ b/src_assets/common/assets/web/configs/tabs/encoders/IntelQuickSyncEncoder.vue
@@ -36,15 +36,11 @@ const config = ref(props.config)
     </div>
 
     <!-- Allow Slow HEVC Encoding -->
-    <div class="mb-3">
-      <label for="qsv_slow_hevc" class="form-label">{{ $t('config.qsv_slow_hevc') }}</label>
-      <select id="qsv_slow_hevc" class="form-select" v-model="config.qsv_slow_hevc">
-        <option value="disabled">{{ $t('_common.disabled_def') }}</option>
-        <option value="enabled">{{ $t('_common.enabled') }}</option>
-      </select>
+    <div class="form-check">
+      <label for="qsv_slow_hevc" class="form-label">{{ $t('config.qsv_slow_hevc') }}<div class="mt-0 form-text">{{ $t('_common.disabled_def_cbox') }}</div></label>
+      <input type="checkbox" class="form-check-input" id="qsv_slow_hevc" v-model="config.qsv_slow_hevc" true-value="enabled" false-value="disabled" />
       <div class="form-text">{{ $t('config.qsv_slow_hevc_desc') }}</div>
     </div>
-
   </div>
 </template>
 
diff --git a/src_assets/common/assets/web/configs/tabs/encoders/NvidiaNvencEncoder.vue b/src_assets/common/assets/web/configs/tabs/encoders/NvidiaNvencEncoder.vue
index aa6ad003ac2..254cc31b532 100644
--- a/src_assets/common/assets/web/configs/tabs/encoders/NvidiaNvencEncoder.vue
+++ b/src_assets/common/assets/web/configs/tabs/encoders/NvidiaNvencEncoder.vue
@@ -72,12 +72,9 @@ const config = ref(props.config)
              aria-labelledby="panelsStayOpen-headingOne">
           <div class="accordion-body">
             <!-- NVENC Realtime HAGS priority -->
-            <div class="mb-3" v-if="platform === 'windows'">
-              <label for="nvenc_realtime_hags" class="form-label">{{ $t('config.nvenc_realtime_hags') }}</label>
-              <select id="nvenc_realtime_hags" class="form-select" v-model="config.nvenc_realtime_hags">
-                <option value="disabled">{{ $t('_common.disabled') }}</option>
-                <option value="enabled">{{ $t('_common.enabled_def') }}</option>
-              </select>
+            <div class="mb-3 form-check" v-if="platform === 'windows'">
+              <label for="nvenc_realtime_hags" class="form-label">{{ $t('config.nvenc_realtime_hags') }}<div class="mt-0 form-text">{{ $t('_common.enabled_def_cbox') }}</div></label>
+              <input type="checkbox" class="form-check-input" id="nvenc_realtime_hags" v-model="config.nvenc_realtime_hags" true-value="enabled" false-value="disabled" />
               <div class="form-text">
                 {{ $t('config.nvenc_realtime_hags_desc') }}<br>
                 <br>
@@ -86,32 +83,23 @@ const config = ref(props.config)
             </div>
 
             <!-- Prefer lower encoding latency over power savings -->
-            <div class="mb-3" v-if="platform === 'windows'">
-              <label for="nvenc_latency_over_power" class="form-label">{{ $t('config.nvenc_latency_over_power') }}</label>
-              <select id="nvenc_latency_over_power" class="form-select" v-model="config.nvenc_latency_over_power">
-                <option value="disabled">{{ $t('_common.disabled') }}</option>
-                <option value="enabled">{{ $t('_common.enabled_def') }}</option>
-              </select>
+            <div class="mb-3 form-check" v-if="platform === 'windows'">
+              <label for="nvenc_latency_over_power" class="form-label">{{ $t('config.nvenc_latency_over_power') }}<div class="mt-0 form-text">{{ $t('_common.enabled_def_cbox') }}</div></label>
+              <input type="checkbox" class="form-check-input" id="nvenc_latency_over_power" v-model="config.nvenc_latency_over_power" true-value="enabled" false-value="disabled" />
               <div class="form-text">{{ $t('config.nvenc_latency_over_power_desc') }}</div>
             </div>
 
             <!-- Present OpenGL/Vulkan on top of DXGI -->
-            <div class="mb-3" v-if="platform === 'windows'">
-              <label for="nvenc_opengl_vulkan_on_dxgi" class="form-label">{{ $t('config.nvenc_opengl_vulkan_on_dxgi') }}</label>
-              <select id="nvenc_opengl_vulkan_on_dxgi" class="form-select" v-model="config.nvenc_opengl_vulkan_on_dxgi">
-                <option value="disabled">{{ $t('_common.disabled') }}</option>
-                <option value="enabled">{{ $t('_common.enabled_def') }}</option>
-              </select>
+            <div class="mb-3 form-check" v-if="platform === 'windows'">
+              <label for="nvenc_opengl_vulkan_on_dxgi" class="form-label">{{ $t('config.nvenc_opengl_vulkan_on_dxgi') }}<div class="mt-0 form-text">{{ $t('_common.enabled_def_cbox') }}</div></label>
+              <input type="checkbox" class="form-check-input" id="nvenc_opengl_vulkan_on_dxgi" v-model="config.nvenc_opengl_vulkan_on_dxgi" true-value="enabled" false-value="disabled" />
               <div class="form-text">{{ $t('config.nvenc_opengl_vulkan_on_dxgi_desc') }}</div>
             </div>
 
             <!-- NVENC H264 CAVLC -->
-            <div>
-              <label for="nvenc_h264_cavlc" class="form-label">{{ $t('config.nvenc_h264_cavlc') }}</label>
-              <select id="nvenc_h264_cavlc" class="form-select" v-model="config.nvenc_h264_cavlc">
-                <option value="disabled">{{ $t('_common.disabled_def') }}</option>
-                <option value="enabled">{{ $t('_common.enabled') }}</option>
-              </select>
+            <div class="form-check">
+              <label for="nvenc_h264_cavlc" class="form-label">{{ $t('config.nvenc_h264_cavlc') }}<div class="mt-0 form-text">{{ $t('_common.disabled_def_cbox') }}</div></label>
+              <input type="checkbox" class="form-check-input" id="nvenc_h264_cavlc" v-model="config.nvenc_h264_cavlc" true-value="enabled" false-value="disabled" />
               <div class="form-text">{{ $t('config.nvenc_h264_cavlc_desc') }}</div>
             </div>
           </div>
diff --git a/src_assets/common/assets/web/configs/tabs/encoders/SoftwareEncoder.vue b/src_assets/common/assets/web/configs/tabs/encoders/SoftwareEncoder.vue
index d9e7c5dba54..e6319d4a76e 100644
--- a/src_assets/common/assets/web/configs/tabs/encoders/SoftwareEncoder.vue
+++ b/src_assets/common/assets/web/configs/tabs/encoders/SoftwareEncoder.vue
@@ -27,7 +27,7 @@ const config = ref(props.config)
       <div class="form-text">{{ $t('config.sw_preset_desc') }}</div>
     </div>
 
-    <div class="mb-3">
+    <div>
       <label for="sw_tune" class="form-label">{{ $t('config.sw_tune') }}</label>
       <select id="sw_tune" class="form-select" v-model="config.sw_tune">
         <option value="film">{{ $t('config.sw_tune_film') }}</option>
diff --git a/src_assets/common/assets/web/public/assets/locale/en.json b/src_assets/common/assets/web/public/assets/locale/en.json
index b277c8af306..d3d9356f423 100644
--- a/src_assets/common/assets/web/public/assets/locale/en.json
+++ b/src_assets/common/assets/web/public/assets/locale/en.json
@@ -7,11 +7,13 @@
     "cancel": "Cancel",
     "disabled": "Disabled",
     "disabled_def": "Disabled (default)",
+    "disabled_def_cbox": "Default: unchecked",
     "dismiss": "Dismiss",
     "do_cmd": "Do Command",
     "elevated": "Elevated",
     "enabled": "Enabled",
     "enabled_def": "Enabled (default)",
+    "enabled_def_cbox": "Default: checked",
     "error": "Error!",
     "note": "Note:",
     "password": "Password",
@@ -168,6 +170,7 @@
     "gamepad_auto": "Automatic selection options",
     "gamepad_desc": "Choose which type of gamepad to emulate on the host",
     "gamepad_ds4": "DS4 (PS4)",
+    "gamepad_ds4_manual": "DS4 selection options",
     "gamepad_ds5": "DS5 (PS5)",
     "gamepad_switch": "Nintendo Pro (Switch)",
     "gamepad_manual": "Manual DS4 options",
@@ -189,7 +192,7 @@
     "key_repeat_delay_desc": "Control how fast keys will repeat themselves. The initial delay in milliseconds before repeating keys.",
     "key_repeat_frequency": "Key Repeat Frequency",
     "key_repeat_frequency_desc": "How often keys repeat every second. This configurable option supports decimals.",
-    "key_rightalt_to_key_windows": "Map Right Alt key to Windows key",
+    "key_rightalt_to_key_win": "Map Right Alt key to Windows key",
     "key_rightalt_to_key_win_desc": "It may be possible that you cannot send the Windows Key from Moonlight directly. In those cases it may be useful to make Sunshine think the Right Alt key is the Windows key",
     "keyboard": "Enable Keyboard Input",
     "keyboard_desc": "Allows guests to control the host system with the keyboard",