feat: add setting to hide controller with YouTube controls, restoring a bug from before lol

This commit is contained in:
2026-03-28 18:57:48 -04:00
parent 4d34c8754d
commit cd5e4bee9f
4 changed files with 84 additions and 5 deletions
+13 -3
View File
@@ -21,9 +21,19 @@
.vsc-hidden {
display: none !important;
}
.vsc-manual {
visibility: visible !important;
opacity: 1 !important;
/* YouTube auto-hide feature: fade controller with YouTube's controls */
/* When the wrapper has ytp-autohide class, hide it (unless vsc-hidden overrides) */
.vsc-controller.ytp-autohide:not(.vsc-hidden) {
visibility: hidden;
transition: opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1);
opacity: 0;
}
/* Show it temporarily when it has vsc-show class */
.vsc-controller.ytp-autohide.vsc-show:not(.vsc-hidden) {
visibility: visible;
opacity: 1;
}
/* Original overrides removed to avoid interference with the new anchoring system.
+56 -2
View File
@@ -13,6 +13,7 @@ var tc = {
forceLastSavedSpeed: false,
audioBoolean: false,
startHidden: false,
hideWithYouTubeControls: false,
controllerLocation: "top-left",
controllerOpacity: 0.3,
keyBindings: [],
@@ -951,6 +952,7 @@ chrome.storage.sync.get(tc.settings, function (storage) {
tc.settings.audioBoolean = Boolean(storage.audioBoolean);
tc.settings.enabled = Boolean(storage.enabled);
tc.settings.startHidden = Boolean(storage.startHidden);
tc.settings.hideWithYouTubeControls = Boolean(storage.hideWithYouTubeControls);
tc.settings.controllerLocation = normalizeControllerLocation(
storage.controllerLocation
);
@@ -1189,6 +1191,10 @@ function defineVideoController() {
tc.videoController.prototype.remove = function () {
this.stopSubtitleNudge();
if (this.youTubeAutoHideObserver) {
this.youTubeAutoHideObserver.disconnect();
this.youTubeAutoHideObserver = null;
}
if (this.div) this.div.remove();
if (this.restoreSpeedTimer) clearTimeout(this.restoreSpeedTimer);
if (this.video) {
@@ -1325,6 +1331,49 @@ function defineVideoController() {
log(`Immediate nudge performed at rate ${targetRate.toFixed(2)}`, 5);
};
tc.videoController.prototype.setupYouTubeAutoHide = function (wrapper) {
if (!wrapper || !isOnYouTube()) return;
const video = this.video;
const ytPlayer = video.closest(".html5-video-player");
if (!ytPlayer) {
log("YouTube player not found for auto-hide setup", 4);
return;
}
const syncControllerVisibility = () => {
// YouTube adds ytp-autohide class to the player when controls should be hidden
// We mirror this class state to enable CSS-based hiding
// The vsc-hidden class (from V key) takes precedence via CSS specificity
if (ytPlayer.classList.contains("ytp-autohide")) {
wrapper.classList.add("ytp-autohide");
log("YouTube controls hidden, hiding controller", 5);
} else {
wrapper.classList.remove("ytp-autohide");
log("YouTube controls visible, showing controller", 5);
}
};
// Initial sync
syncControllerVisibility();
// Observe YouTube player class changes
this.youTubeAutoHideObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === "attributes" && mutation.attributeName === "class") {
syncControllerVisibility();
}
});
});
this.youTubeAutoHideObserver.observe(ytPlayer, {
attributes: true,
attributeFilter: ["class"]
});
log("YouTube auto-hide observer setup complete", 4);
};
tc.videoController.prototype.initializeControls = function () {
const doc = this.video.ownerDocument;
const speed = this.video.playbackRate.toFixed(2);
@@ -1426,6 +1475,12 @@ function defineVideoController() {
);
controller.addEventListener("click", (e) => e.stopPropagation(), false);
controller.addEventListener("mousedown", (e) => e.stopPropagation(), false);
// Setup YouTube auto-hide observer if enabled
if (tc.settings.hideWithYouTubeControls && isOnYouTube()) {
this.setupYouTubeAutoHide(wrapper);
}
var fragment = doc.createDocumentFragment();
fragment.appendChild(wrapper);
const parentEl = this.parent || this.video.parentElement;
@@ -1548,6 +1603,7 @@ function applySiteRuleOverrides() {
// Override general settings with site-specific overrides
const siteSettings = [
"startHidden",
"hideWithYouTubeControls",
"controllerLocation",
"rememberSpeed",
"forceLastSavedSpeed",
@@ -2092,10 +2148,8 @@ function runAction(action, value, e) {
case "display":
if (controller.classList.contains("vsc-hidden")) {
controller.classList.remove("vsc-hidden");
controller.classList.add("vsc-manual");
} else {
controller.classList.add("vsc-hidden");
controller.classList.remove("vsc-manual");
}
break;
case "blink":
+10
View File
@@ -140,6 +140,12 @@
<label for="startHidden">Hide controller by default</label>
<input id="startHidden" type="checkbox" />
</div>
<div class="row">
<label for="hideWithYouTubeControls">Hide with controls (YouTube)<br />
<em>Fade controller in/out with YouTube's video interface</em>
</label>
<input id="hideWithYouTubeControls" type="checkbox" />
</div>
<div class="row">
<label for="controllerLocation">Default controller location</label>
<select id="controllerLocation">
@@ -213,6 +219,10 @@
<label>Hide controller by default:</label>
<input type="checkbox" class="site-startHidden" />
</div>
<div class="site-rule-option">
<label>Hide with controls (YouTube):</label>
<input type="checkbox" class="site-hideWithYouTubeControls" />
</div>
<div class="site-rule-option">
<label>Default controller location:</label>
<select class="site-controllerLocation">
+5
View File
@@ -150,6 +150,7 @@ var tcDefaults = {
rememberSpeed: false,
audioBoolean: false,
startHidden: false,
hideWithYouTubeControls: false,
controllerLocation: "top-left",
forceLastSavedSpeed: false,
enabled: true,
@@ -575,6 +576,7 @@ function save_options() {
settings.audioBoolean = document.getElementById("audioBoolean").checked;
settings.enabled = document.getElementById("enabled").checked;
settings.startHidden = document.getElementById("startHidden").checked;
settings.hideWithYouTubeControls = document.getElementById("hideWithYouTubeControls").checked;
settings.controllerLocation = normalizeControllerLocation(
document.getElementById("controllerLocation").value
);
@@ -609,6 +611,7 @@ function save_options() {
// Handle other site settings
const siteSettings = [
{ key: "startHidden", type: "checkbox" },
{ key: "hideWithYouTubeControls", type: "checkbox" },
{ key: "controllerLocation", type: "select" },
{ key: "rememberSpeed", type: "checkbox" },
{ key: "forceLastSavedSpeed", type: "checkbox" },
@@ -830,6 +833,7 @@ function createSiteRule(rule) {
const settings = [
{ key: "startHidden", type: "checkbox" },
{ key: "hideWithYouTubeControls", type: "checkbox" },
{ key: "controllerLocation", type: "select" },
{ key: "rememberSpeed", type: "checkbox" },
{ key: "forceLastSavedSpeed", type: "checkbox" },
@@ -891,6 +895,7 @@ function restore_options() {
document.getElementById("audioBoolean").checked = storage.audioBoolean;
document.getElementById("enabled").checked = storage.enabled;
document.getElementById("startHidden").checked = storage.startHidden;
document.getElementById("hideWithYouTubeControls").checked = storage.hideWithYouTubeControls;
document.getElementById("controllerLocation").value =
normalizeControllerLocation(storage.controllerLocation);
document.getElementById("controllerOpacity").value =