Sv443 1 år sedan
förälder
incheckning
627ddd7058
1 ändrade filer med 236 tillägg och 103 borttagningar
  1. 236 103
      dist/BetterYTM.user.js

+ 236 - 103
dist/BetterYTM.user.js

@@ -17,7 +17,7 @@
 // @license           AGPL-3.0-only
 // @author            Sv443
 // @copyright         Sv443 (https://github.com/Sv443)
-// @icon              https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/logo/logo_48.png
+// @icon              https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/logo/logo_48.png
 // @match             https://music.youtube.com/*
 // @match             https://www.youtube.com/*
 // @run-at            document-start
@@ -46,12 +46,13 @@
 // @resource          icon-skip_to            https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/skip_to.svg
 // @resource          icon-spinner            https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/spinner.svg
 // @resource          icon-advanced_mode      https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/plus_circle_small.svg
-// @resource          img-logo                https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/logo/logo_48.png
-// @resource          img-close               https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/close.png
-// @resource          img-discord             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/external/discord.png
-// @resource          img-github              https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/external/github.png
-// @resource          img-greasyfork          https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/external/greasyfork.png
-// @resource          img-openuserjs          https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/external/openuserjs.png
+// @resource          icon-lock               https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/lock.svg
+// @resource          img-logo                https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/logo/logo_48.png
+// @resource          img-close               https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/close.png
+// @resource          img-discord             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/external/discord.png
+// @resource          img-github              https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/external/github.png
+// @resource          img-greasyfork          https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/external/greasyfork.png
+// @resource          img-openuserjs          https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/external/openuserjs.png
 // @resource          trans-de_DE             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/de_DE.json
 // @resource          trans-en_US             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/en_US.json
 // @resource          trans-en_UK             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/en_UK.json
@@ -237,7 +238,7 @@ var LogLevel;
 })(LogLevel || (LogLevel = {}));const modeRaw = "development";
 const branchRaw = "develop";
 const hostRaw = "github";
-const buildNumberRaw = "e436a15";
+const buildNumberRaw = "8d7536a";
 /** The mode in which the script was built (production or development) */
 const mode = (modeRaw.match(/^#{{.+}}$/) ? "production" : modeRaw);
 /** The branch to use in various URLs that point to the GitHub repo */
@@ -585,6 +586,58 @@ function disableDarkReader() {
         document.head.appendChild(metaElem);
         info("Sent hint to Dark Reader to disable itself");
     }
+}
+//#MARKER lock volume
+let volumeSliderObserverActive = false;
+let sliderElem;
+function overrideVolValues() {
+    if (!sliderElem || !getFeatures().lockVolume)
+        return;
+    volumeSliderObserverActive = false;
+    setTimeout(() => {
+        const vidElem = document.querySelector(videoSelector);
+        if (vidElem)
+            vidElem.volume = getFeatures().lockVolumeLevel / 100;
+        if (!sliderElem) {
+            volumeSliderObserverActive = true;
+            return;
+        }
+        sliderElem.value = String(getFeatures().lockVolumeLevel);
+        sliderElem.setAttribute("aria-valuenow", String(getFeatures().lockVolumeLevel));
+        const knobElem = document.querySelector("#volume-slider #sliderKnobContainer #sliderKnob");
+        if (knobElem)
+            knobElem.style.left = `${getFeatures().lockVolumeLevel}%`;
+        const labelElem = document.querySelector("#bytm-vol-slider-label .label");
+        const newLabelContent = `${getFeatures().lockVolumeLevel}%`;
+        if (labelElem && labelElem.textContent !== newLabelContent)
+            labelElem.textContent = newLabelContent;
+        volumeSliderObserverActive = true;
+    }, 10);
+}
+/** Locks the volume slider at a specific level */
+function enableLockVolume() {
+    return __awaiter(this, void 0, void 0, function* () {
+        const observer = new MutationObserver((mutations) => {
+            for (const mutation of mutations) {
+                if (!volumeSliderObserverActive)
+                    return;
+                if (mutation.target.id === "sliderBar" && mutation.type === "attributes") {
+                    if (mutation.attributeName === "value" || mutation.attributeName === "aria-valuenow")
+                        overrideVolValues();
+                }
+            }
+        });
+        onSelectorOld("#volume-slider tp-yt-paper-progress#sliderBar", {
+            listener: (elem) => {
+                sliderElem = elem;
+                overrideVolValues();
+                volumeSliderObserverActive = true;
+                observer.observe(elem, {
+                    attributeFilter: ["value", "aria-valuenow"],
+                });
+            }
+        });
+    });
 }/** Ratelimit budget timeframe in seconds - should reflect what's in geniURL's docs */
 const geniUrlRatelimitTimeframe = 30;
 let canCompress$1 = true;
@@ -1909,11 +1962,14 @@ function addCfgMenu() {
         featuresCont.id = "bytm-menu-opts";
         /** Gets called whenever the feature config is changed */
         const confChanged = UserUtils.debounce((key, initialVal, newVal) => __awaiter(this, void 0, void 0, function* () {
+            var _f, _g;
             const fmt = (val) => typeof val === "object" ? JSON.stringify(val) : String(val);
             info(`Feature config changed at key '${key}', from value '${fmt(initialVal)}' to '${fmt(newVal)}'`);
             const featConf = JSON.parse(JSON.stringify(getFeatures()));
             featConf[key] = newVal;
             yield saveFeatures(featConf);
+            // @ts-ignore
+            (_g = (_f = featInfo[key]) === null || _f === void 0 ? void 0 : _f.change) === null || _g === void 0 ? void 0 : _g.call(_f, featConf);
             if (initConfig$1 !== JSON.stringify(featConf))
                 footerElem.classList.remove("hidden");
             else
@@ -2684,7 +2740,7 @@ function addImportMenu() {
                                 curFmtVer = ver;
                             }
                             catch (err) {
-                                console.error(`Error while running migration function for format version ${fmtVer}:`, err);
+                                error(`Error while running migration function for format version ${fmtVer}:`, err);
                             }
                         }
                     }
@@ -3003,7 +3059,7 @@ function initVolumeFeatures() {
     return __awaiter(this, void 0, void 0, function* () {
         // not technically an input element but behaves pretty much the same
         onSelectorOld("tp-yt-paper-slider#volume-slider", {
-            listener: (sliderElem) => {
+            listener: (sliderElem) => __awaiter(this, void 0, void 0, function* () {
                 const volSliderCont = document.createElement("div");
                 volSliderCont.id = "bytm-vol-slider-cont";
                 if (features$2.volumeSliderScrollStep !== featInfo.volumeSliderScrollStep.default) {
@@ -3030,53 +3086,67 @@ function initVolumeFeatures() {
                 if (typeof features$2.volumeSliderSize === "number")
                     setVolSliderSize();
                 if (features$2.volumeSliderLabel)
-                    addVolumeSliderLabel(sliderElem, volSliderCont);
+                    yield addVolumeSliderLabel(sliderElem, volSliderCont);
                 setVolSliderStep(sliderElem);
-            },
+            }),
         });
     });
 }
 /** Adds a percentage label to the volume slider and tooltip */
 function addVolumeSliderLabel(sliderElem, sliderContainer) {
-    const labelElem = document.createElement("div");
-    labelElem.id = "bytm-vol-slider-label";
-    labelElem.textContent = `${sliderElem.value}%`;
-    // prevent video from minimizing
-    labelElem.addEventListener("click", (e) => e.stopPropagation());
-    const getLabelText = (slider) => { var _a; return t("volume_tooltip", slider.value, (_a = features$2.volumeSliderStep) !== null && _a !== void 0 ? _a : slider.step); };
-    const labelFull = getLabelText(sliderElem);
-    sliderContainer.setAttribute("title", labelFull);
-    sliderElem.setAttribute("title", labelFull);
-    sliderElem.setAttribute("aria-valuetext", labelFull);
-    const updateLabel = () => {
+    return __awaiter(this, void 0, void 0, function* () {
+        const labelContElem = document.createElement("div");
+        labelContElem.id = "bytm-vol-slider-label";
+        const getLabel = (value) => `${getFeatures().lockVolume ? getFeatures().lockVolumeLevel : value}%`;
+        const labelElem = document.createElement("div");
+        labelElem.classList.add("label");
+        labelElem.textContent = getLabel(sliderElem.value);
+        // prevent video from minimizing
+        labelContElem.addEventListener("click", (e) => e.stopPropagation());
+        const getLabelText = (slider) => { var _a; return t("volume_tooltip", slider.value, (_a = features$2.volumeSliderStep) !== null && _a !== void 0 ? _a : slider.step); };
         const labelFull = getLabelText(sliderElem);
         sliderContainer.setAttribute("title", labelFull);
         sliderElem.setAttribute("title", labelFull);
         sliderElem.setAttribute("aria-valuetext", labelFull);
-        const labelElem2 = document.querySelector("#bytm-vol-slider-label");
-        if (labelElem2)
-            labelElem2.textContent = `${sliderElem.value}%`;
-    };
-    sliderElem.addEventListener("change", () => updateLabel());
-    onSelectorOld("#bytm-vol-slider-cont", {
-        listener: (volumeCont) => {
-            volumeCont.appendChild(labelElem);
-        },
-    });
-    let lastSliderVal = Number(sliderElem.value);
-    // show label if hovering over slider or slider is focused
-    const sliderHoverObserver = new MutationObserver(() => {
-        if (sliderElem.classList.contains("on-hover") || document.activeElement === sliderElem)
-            labelElem.classList.add("bytm-visible");
-        else if (labelElem.classList.contains("bytm-visible") || document.activeElement !== sliderElem)
-            labelElem.classList.remove("bytm-visible");
-        if (Number(sliderElem.value) !== lastSliderVal) {
-            lastSliderVal = Number(sliderElem.value);
-            updateLabel();
+        const updateLabel = () => {
+            const labelFull = getLabelText(sliderElem);
+            sliderContainer.setAttribute("title", labelFull);
+            sliderElem.setAttribute("title", labelFull);
+            sliderElem.setAttribute("aria-valuetext", labelFull);
+            const labelElem2 = document.querySelector("#bytm-vol-slider-label div.label");
+            if (labelElem2)
+                labelElem2.textContent = getLabel(sliderElem.value);
+        };
+        sliderElem.addEventListener("change", () => updateLabel());
+        let lockIconElem;
+        const lockIconHtml = yield resourceToHTMLString("icon-lock");
+        if (getFeatures().lockVolume && lockIconHtml) {
+            lockIconElem = document.createElement("span");
+            lockIconElem.title = lockIconElem.ariaLabel = t("volume_locked", getFeatures().lockVolumeLevel);
+            lockIconElem.innerHTML = lockIconHtml;
         }
-    });
-    sliderHoverObserver.observe(sliderElem, {
-        attributes: true,
+        onSelectorOld("#bytm-vol-slider-cont", {
+            listener: (volumeCont) => {
+                lockIconElem && labelContElem.appendChild(lockIconElem);
+                labelContElem.appendChild(labelElem);
+                volumeCont.appendChild(labelContElem);
+            },
+        });
+        let lastSliderVal = Number(sliderElem.value);
+        // show label if hovering over slider or slider is focused
+        const sliderHoverObserver = new MutationObserver(() => {
+            if (sliderElem.classList.contains("on-hover") || document.activeElement === sliderElem)
+                labelContElem.classList.add("bytm-visible");
+            else if (labelContElem.classList.contains("bytm-visible") || document.activeElement !== sliderElem)
+                labelContElem.classList.remove("bytm-visible");
+            if (Number(sliderElem.value) !== lastSliderVal) {
+                lastSliderVal = Number(sliderElem.value);
+                updateLabel();
+            }
+        });
+        sliderHoverObserver.observe(sliderElem, {
+            attributes: true,
+        });
     });
 }
 /** Sets the volume slider to a set size */
@@ -3824,14 +3894,14 @@ const featInfo = {
         type: "toggle",
         category: "layout",
         default: true,
-        enable: () => void "TODO",
+        enable: noopTODO,
     },
     volumeSliderLabel: {
         type: "toggle",
         category: "layout",
         default: true,
-        enable: () => void "TODO",
-        disable: () => void "TODO",
+        enable: noopTODO,
+        disable: noopTODO,
     },
     volumeSliderSize: {
         type: "number",
@@ -3841,8 +3911,8 @@ const featInfo = {
         step: 5,
         default: 150,
         unit: "px",
-        enable: () => void "TODO",
-        change: () => void "TODO",
+        enable: noopTODO,
+        change: noopTODO,
     },
     volumeSliderStep: {
         type: "slider",
@@ -3851,8 +3921,8 @@ const featInfo = {
         max: 25,
         default: 2,
         unit: "%",
-        enable: () => void "TODO",
-        change: () => void "TODO",
+        enable: noopTODO,
+        change: noopTODO,
     },
     volumeSliderScrollStep: {
         type: "slider",
@@ -3861,51 +3931,51 @@ const featInfo = {
         max: 25,
         default: 10,
         unit: "%",
-        enable: () => void "TODO",
-        change: () => void "TODO",
+        enable: noopTODO,
+        change: noopTODO,
     },
     watermarkEnabled: {
         type: "toggle",
         category: "layout",
         default: true,
-        enable: () => void "TODO",
-        disable: () => void "TODO",
+        enable: noopTODO,
+        disable: noopTODO,
     },
     removeShareTrackingParam: {
         type: "toggle",
         category: "layout",
         default: true,
-        enable: () => void "TODO",
-        disable: () => void "TODO",
+        enable: noopTODO,
+        disable: noopTODO,
     },
     fixSpacing: {
         type: "toggle",
         category: "layout",
         default: true,
-        enable: () => void "TODO",
-        disable: () => void "TODO",
+        enable: noopTODO,
+        disable: noopTODO,
     },
     scrollToActiveSongBtn: {
         type: "toggle",
         category: "layout",
         default: true,
-        enable: () => void "TODO",
-        disable: () => void "TODO",
+        enable: noopTODO,
+        disable: noopTODO,
     },
     //#SECTION song lists
     lyricsQueueButton: {
         type: "toggle",
         category: "songLists",
         default: true,
-        enable: () => void "TODO",
-        disable: () => void "TODO",
+        enable: noopTODO,
+        disable: noopTODO,
     },
     deleteFromQueueButton: {
         type: "toggle",
         category: "songLists",
         default: true,
-        enable: () => void "TODO",
-        disable: () => void "TODO",
+        enable: noopTODO,
+        disable: noopTODO,
     },
     listButtonsPlacement: {
         type: "select",
@@ -3915,15 +3985,15 @@ const featInfo = {
             { value: "everywhere", label: t("list_button_placement_everywhere") },
         ],
         default: "everywhere",
-        enable: () => void "TODO",
-        disable: () => void "TODO",
+        enable: noopTODO,
+        disable: noopTODO,
     },
     //#SECTION behavior
     disableBeforeUnloadPopup: {
         type: "toggle",
         category: "behavior",
         default: false,
-        enable: () => void "TODO",
+        enable: noopTODO,
     },
     closeToastsTimeout: {
         type: "number",
@@ -3933,15 +4003,15 @@ const featInfo = {
         step: 0.5,
         default: 0,
         unit: "s",
-        enable: () => void "TODO",
-        change: () => void "TODO",
+        enable: noopTODO,
+        change: noopTODO,
     },
     rememberSongTime: {
         type: "toggle",
         category: "behavior",
         default: true,
-        enable: () => void "TODO",
-        disable: () => void "TODO", // TODO: feasible?
+        enable: noopTODO,
+        disable: noopTODO, // TODO: feasible?
         helpText: () => tp("feature_helptext_rememberSongTime", remSongMinPlayTime, remSongMinPlayTime)
     },
     rememberSongTimeSites: {
@@ -3953,16 +4023,34 @@ const featInfo = {
             { value: "ytm", label: t("remember_song_time_sites_ytm") },
         ],
         default: "ytm",
-        enable: () => void "TODO",
-        change: () => void "TODO",
+        enable: noopTODO,
+        change: noopTODO,
+    },
+    lockVolume: {
+        type: "toggle",
+        category: "behavior",
+        default: false,
+        enable: () => noopTODO,
+        disable: () => noopTODO,
+    },
+    lockVolumeLevel: {
+        type: "slider",
+        category: "behavior",
+        min: 0,
+        max: 100,
+        step: 1,
+        default: 100,
+        unit: "%",
+        enable: noop,
+        change: () => noopTODO,
     },
     //#SECTION input
     arrowKeySupport: {
         type: "toggle",
         category: "input",
         default: true,
-        enable: () => void "TODO",
-        disable: () => void "TODO",
+        enable: noopTODO,
+        disable: noopTODO,
     },
     arrowKeySkipBy: {
         type: "number",
@@ -3971,15 +4059,15 @@ const featInfo = {
         max: 60,
         step: 0.5,
         default: 5,
-        enable: () => void "TODO",
-        change: () => void "TODO",
+        enable: noopTODO,
+        change: noopTODO,
     },
     switchBetweenSites: {
         type: "toggle",
         category: "input",
         default: true,
-        enable: () => void "TODO",
-        disable: () => void "TODO",
+        enable: noopTODO,
+        disable: noopTODO,
     },
     switchSitesHotkey: {
         type: "hotkey",
@@ -3990,30 +4078,30 @@ const featInfo = {
             ctrl: false,
             alt: false,
         },
-        enable: () => void "TODO",
-        change: () => void "TODO",
+        enable: noopTODO,
+        change: noopTODO,
     },
     anchorImprovements: {
         type: "toggle",
         category: "input",
         default: true,
-        enable: () => void "TODO",
-        disable: () => void "TODO",
+        enable: noopTODO,
+        disable: noopTODO,
     },
     numKeysSkipToTime: {
         type: "toggle",
         category: "input",
         default: true,
-        enable: () => void "TODO",
-        disable: () => void "TODO",
+        enable: noopTODO,
+        disable: noopTODO,
     },
     //#SECTION lyrics
     geniusLyrics: {
         type: "toggle",
         category: "lyrics",
         default: true,
-        enable: () => void "TODO",
-        disable: () => void "TODO",
+        enable: noopTODO,
+        disable: noopTODO,
     },
     geniUrlBase: {
         type: "text",
@@ -4042,8 +4130,8 @@ const featInfo = {
         max: 2000,
         step: 50,
         unit: (val) => tp("unit_entries", val),
-        enable: () => void "TODO",
-        change: () => void "TODO",
+        enable: noopTODO,
+        change: noopTODO,
         advanced: true,
         // TODO: to be reworked or removed in the big menu rework
         textAdornment: getAdvancedModeAdornment,
@@ -4056,8 +4144,8 @@ const featInfo = {
         max: 100,
         step: 1,
         unit: (val) => tp("unit_days", val),
-        enable: () => void "TODO",
-        change: () => void "TODO",
+        enable: noopTODO,
+        change: noopTODO,
         advanced: true,
         // TODO: to be reworked or removed in the big menu rework
         textAdornment: getAdvancedModeAdornment,
@@ -4083,7 +4171,7 @@ const featInfo = {
         category: "general",
         options: localeOptions,
         default: getPreferredLocale(),
-        enable: () => void "TODO",
+        enable: noopTODO,
         // TODO: to be reworked or removed in the big menu rework
         textAdornment: () => __awaiter(void 0, void 0, void 0, function* () { var _a; return (_a = yield resourceToHTMLString("icon-globe")) !== null && _a !== void 0 ? _a : ""; }),
     },
@@ -4091,8 +4179,8 @@ const featInfo = {
         type: "toggle",
         category: "general",
         default: true,
-        enable: () => void "TODO",
-        disable: () => void "TODO",
+        enable: noopTODO,
+        disable: noopTODO,
     },
     logLevel: {
         type: "select",
@@ -4102,14 +4190,14 @@ const featInfo = {
             { value: 1, label: t("log_level_info") },
         ],
         default: 1,
-        enable: () => void "TODO",
+        enable: noopTODO,
     },
     advancedMode: {
         type: "toggle",
         category: "general",
         default: mode === "development",
-        enable: () => void "TODO",
-        disable: () => void "TODO",
+        enable: noopTODO,
+        disable: noopTODO,
         // TODO: to be reworked or removed in the big menu rework
         textAdornment: () => getFeatures().advancedMode ? getAdvancedModeAdornment() : undefined,
     },
@@ -4119,6 +4207,10 @@ function getAdvancedModeAdornment() {
     return __awaiter(this, void 0, void 0, function* () {
         return `<span class="bytm-advanced-mode-icon" title="${t("advanced_mode")}">${(_a = yield resourceToHTMLString("icon-advanced_mode")) !== null && _a !== void 0 ? _a : ""}</span>`;
     });
+}
+function noop() {
+}
+function noopTODO() {
 }/** If this number is incremented, the features object data will be migrated to the new format */
 const formatVersion = 5;
 /** Config data format migration dictionary */
@@ -4144,7 +4236,7 @@ const migrations = {
     },
     // 4 -> 5
     5: (oldData) => {
-        return Object.assign(Object.assign({}, oldData), { geniUrlBase: getFeatureDefault("geniUrlBase"), geniUrlToken: getFeatureDefault("geniUrlToken"), lyricsCacheMaxSize: getFeatureDefault("lyricsCacheMaxSize"), lyricsCacheTTL: getFeatureDefault("lyricsCacheTTL"), clearLyricsCache: getFeatureDefault("clearLyricsCache"), advancedMode: getFeatureDefault("advancedMode") });
+        return Object.assign(Object.assign({}, oldData), { geniUrlBase: getFeatureDefault("geniUrlBase"), geniUrlToken: getFeatureDefault("geniUrlToken"), lyricsCacheMaxSize: getFeatureDefault("lyricsCacheMaxSize"), lyricsCacheTTL: getFeatureDefault("lyricsCacheTTL"), clearLyricsCache: getFeatureDefault("clearLyricsCache"), advancedMode: getFeatureDefault("advancedMode"), lockVolume: getFeatureDefault("lockVolume"), lockVolumeLevel: getFeatureDefault("lockVolumeLevel") });
     },
 };
 function getFeatureDefault(key) {
@@ -4842,11 +4934,40 @@ function onDomLoad() {
                     ftInit.push(fixSpacing());
                 if (features.scrollToActiveSongBtn)
                     ftInit.push(addScrollToActiveBtn());
+                if (features.lockVolume)
+                    ftInit.push(enableLockVolume());
                 ftInit.push(initVolumeFeatures());
             }
             if (["ytm", "yt"].includes(domain)) {
                 if (features.switchBetweenSites)
                     ftInit.push(initSiteSwitch(domain));
+                // TODO: for hot reloading features
+                // ftInit.push(new Promise((resolve) => {
+                //   for(const [k, v] of Object.entries(featInfo)) {
+                //     try {
+                //       const featVal = features[k as keyof typeof featInfo];
+                //       // @ts-ignore
+                //       if(v.enable && featVal === true) {
+                //         console.log("###> enable", k);
+                //         // @ts-ignore
+                //         v.enable(features);
+                //         console.log("###>> enable ok");
+                //       }
+                //       // @ts-ignore
+                //       else if(v.disable && featVal === false) {
+                //         console.log("###> disable", k);
+                //         // @ts-ignore
+                //         v.disable(features);
+                //         console.log("###>> disable ok");
+                //       }
+                //     }
+                //     catch(err) {
+                //       error(`Couldn't initialize feature "${k}" due to error:`, err);
+                //     }
+                //   }
+                //   console.log("###>>> done for loop");
+                //   resolve();
+                // }));
             }
             Promise.allSettled(ftInit).then(() => {
                 emitInterface("bytm:ready");
@@ -5980,14 +6101,26 @@ yt-multi-page-menu-section-renderer.ytd-multi-page-menu-renderer {
 #bytm-vol-slider-label {
   opacity: 0.000001;
   position: absolute;
-  font-size: 15px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  gap: 5px;
+  font-size: 1.4rem;
   top: 50%;
   left: 0;
-  transform: translate(calc(-50% - 10px), -50%);
+  transform: translate(calc(-50% - 35px), -50%);
   text-align: right;
   transition: opacity 0.2s ease;
 }
 
+#bytm-vol-slider-label svg {
+  padding: 4px;
+}
+
+#bytm-vol-slider-label svg path {
+  fill: #909090;
+}
+
 #bytm-vol-slider-label.bytm-visible {
   opacity: 1;
 }