From 8a1e9cc9e03443d02a2ca658c8756e94c0949be0 Mon Sep 17 00:00:00 2001 From: ohslyfox Date: Mon, 18 May 2026 12:55:02 -0700 Subject: [PATCH 1/2] feat: add "Maximum" passthrough quality option that dynamically resolves to the highest available bitrate --- src/controls/settings/useQualitySelector.js | 38 ++++++++++++++++----- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/controls/settings/useQualitySelector.js b/src/controls/settings/useQualitySelector.js index dd317be..e70b3cb 100644 --- a/src/controls/settings/useQualitySelector.js +++ b/src/controls/settings/useQualitySelector.js @@ -2,6 +2,7 @@ import { useState, useEffect, useCallback } from "react"; import { usePreferences } from "../usePreferences.js"; const AUTO_QUALITY = { label: "Auto", value: "auto" }; +const MAX_QUALITY = { label: "Maximum", value: "max" }; export function useQualitySelector(core) { const { savedQuality, setSavedQuality } = usePreferences(); @@ -14,17 +15,35 @@ export function useQualitySelector(core) { return; } - const option = - value === "auto" ? AUTO_QUALITY : { label: value, value: value }; - - setSelectedQuality(option); - if (value === "auto") { + setSelectedQuality(AUTO_QUALITY); core.setAutoQualityMode(true); setSavedQuality("auto"); return; } + if (value === "max") { + // "max" is a fake option, resolves to the highest bitrate + const maxQuality = qualities[0]; + if (maxQuality) { + setSelectedQuality({ + value: "max", + label: maxQuality.name, + }); + core.setAutoQualityMode(false); + core.setQuality(maxQuality); + } else { + // fallback to auto, keep saved selection as max + console.warn("[KickQuality] max quality could not be resolved"); + setSelectedQuality(AUTO_QUALITY); + core.setAutoQualityMode(true); + } + setSavedQuality("max"); + return; + } + + setSelectedQuality({ label: value, value: value }); + const targetQuality = qualities.find((quality) => quality.name === value); if (!targetQuality) { console.warn("[KickQuality] quality option missing", value); @@ -45,7 +64,9 @@ export function useQualitySelector(core) { if (arg?.key === "qualities") { if (arg.value?.length) { - setQualities(arg.value); + // defensive to ensure "max" functionality, `arg.value` should already be sorted + const sorted = [...arg.value].sort((a, b) => b.bitrate - a.bitrate); + setQualities(sorted); } return; } @@ -76,8 +97,8 @@ export function useQualitySelector(core) { return; } - if (savedQuality === "auto") { - handleQualityChange("auto"); + if (["auto", "max"].includes(savedQuality)) { + handleQualityChange(savedQuality); return; } @@ -88,6 +109,7 @@ export function useQualitySelector(core) { const qualityOptions = [ AUTO_QUALITY, + MAX_QUALITY, ...qualities.map((q) => ({ value: q.name, label: q.name })), ]; From aafd142f721f00ef0cce3b35e934aa42cc8c0ca1 Mon Sep 17 00:00:00 2001 From: ohslyfox Date: Wed, 27 May 2026 12:08:00 -0700 Subject: [PATCH 2/2] rename 'max' to 'best', reformat selected label to 'Best (quality)' --- src/controls/settings/useQualitySelector.js | 28 ++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/controls/settings/useQualitySelector.js b/src/controls/settings/useQualitySelector.js index e70b3cb..bdce571 100644 --- a/src/controls/settings/useQualitySelector.js +++ b/src/controls/settings/useQualitySelector.js @@ -2,7 +2,7 @@ import { useState, useEffect, useCallback } from "react"; import { usePreferences } from "../usePreferences.js"; const AUTO_QUALITY = { label: "Auto", value: "auto" }; -const MAX_QUALITY = { label: "Maximum", value: "max" }; +const BEST_QUALITY = { label: "Best", value: "best" }; export function useQualitySelector(core) { const { savedQuality, setSavedQuality } = usePreferences(); @@ -22,23 +22,23 @@ export function useQualitySelector(core) { return; } - if (value === "max") { - // "max" is a fake option, resolves to the highest bitrate - const maxQuality = qualities[0]; - if (maxQuality) { + if (value === "best") { + // "best" is a fake option, resolves to the highest bitrate + const bestQuality = qualities[0]; + if (bestQuality) { setSelectedQuality({ - value: "max", - label: maxQuality.name, + value: "best", + label: `${BEST_QUALITY.label} (${bestQuality.name})`, }); core.setAutoQualityMode(false); - core.setQuality(maxQuality); + core.setQuality(bestQuality); } else { - // fallback to auto, keep saved selection as max - console.warn("[KickQuality] max quality could not be resolved"); + // fallback to auto, keep saved selection as "best" + console.warn("[KickQuality] best quality could not be resolved"); setSelectedQuality(AUTO_QUALITY); core.setAutoQualityMode(true); } - setSavedQuality("max"); + setSavedQuality("best"); return; } @@ -64,7 +64,7 @@ export function useQualitySelector(core) { if (arg?.key === "qualities") { if (arg.value?.length) { - // defensive to ensure "max" functionality, `arg.value` should already be sorted + // defensive to ensure "best" functionality, `arg.value` should already be sorted const sorted = [...arg.value].sort((a, b) => b.bitrate - a.bitrate); setQualities(sorted); } @@ -97,7 +97,7 @@ export function useQualitySelector(core) { return; } - if (["auto", "max"].includes(savedQuality)) { + if (["auto", "best"].includes(savedQuality)) { handleQualityChange(savedQuality); return; } @@ -109,7 +109,7 @@ export function useQualitySelector(core) { const qualityOptions = [ AUTO_QUALITY, - MAX_QUALITY, + BEST_QUALITY, ...qualities.map((q) => ({ value: q.name, label: q.name })), ];