diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json
index fa66894f..5ec3f3e3 100644
--- a/public/_locales/en/messages.json
+++ b/public/_locales/en/messages.json
@@ -182,15 +182,15 @@
"hideButtonsDescription": {
"message": "This hides the buttons that appear on the YouTube player to submit skip segments."
},
+ "showSkipButton": {
+ "message": "Keep Skip to Highlight Button on Player"
+ },
"showInfoButton": {
"message": "Show Info Button On YouTube Player"
},
"hideInfoButton": {
"message": "Hide Info Button On YouTube Player"
},
- "whatInfoButton": {
- "message": "This is the button that opens up a popup in the YouTube page."
- },
"autoHideInfoButton": {
"message": "Auto-hide Info Button"
},
@@ -200,9 +200,6 @@
"showDeleteButton": {
"message": "Show Delete Button On YouTube Player"
},
- "whatDeleteButton": {
- "message": "This is the button on the YouTube player that will clear all your un-submitted segments for the current video."
- },
"enableViewTracking": {
"message": "Enable Skip Count Tracking"
},
@@ -442,9 +439,6 @@
"showUploadButton": {
"message": "Show Upload Button"
},
- "whatUploadButton": {
- "message": "This button appears on the YouTube player after you have selected a timestamp and are ready to submit."
- },
"customServerAddress": {
"message": "SponsorBlock Server Address"
},
diff --git a/public/content.css b/public/content.css
index 13cab8e4..5fabc94d 100644
--- a/public/content.css
+++ b/public/content.css
@@ -75,16 +75,26 @@
vertical-align: top;
}
-#infoButton.playerButton:not(.hidden) {
- transform: translateX(0%) scale(1);
- /* opacity is from YouTube page */
- transition: transform 0.2s, opacity .1s cubic-bezier(0.4,0.0,1,1) !important;
+.autoHiding {
+ overflow: visible !important;
}
-#infoButton.playerButton.hidden {
+.autoHiding:not(.hidden) {
+ transform: translateX(0%) scale(1);
+ /* opacity is from YouTube page */
+ transition: transform 0.25s, width 0.25s, opacity .1s cubic-bezier(0.4,0.0,1,1) !important;
+}
+
+.autoHiding.hidden {
transform: translateX(100%) scale(0);
/* opacity is from YouTube page */
- transition: transform 0.2s, opacity .1s cubic-bezier(0.4,0.0,1,1) !important;
+ transition: transform 0.25s, width 0.25s, opacity .1s cubic-bezier(0.4,0.0,1,1) !important;
+
+ width: 0px !important;
+}
+
+.autoHiding.hidden.autoHideLeft {
+ transform: translateX(-100%) scale(0);
}
.playerButton.hidden {
diff --git a/public/options/options.html b/public/options/options.html
index b1a0dcb4..1fbcf1b1 100644
--- a/public/options/options.html
+++ b/public/options/options.html
@@ -287,7 +287,22 @@
__MSG_hideButtonsDescription__
+
+
+
+
+
+
+
@@ -301,14 +316,9 @@
__MSG_showInfoButton__
-
-
-
-
-
- __MSG_whatInfoButton__
+
@@ -322,13 +332,11 @@
__MSG_autoHideInfoButton__
-
-
-
-
-
-
+
+
+
+
@@ -340,14 +348,9 @@
__MSG_showDeleteButton__
-
-
-
-
-
- __MSG_whatDeleteButton__
+
@@ -361,14 +364,10 @@
__MSG_showUploadButton__
-
-
-
-
-
- __MSG_whatUploadButton__
+
+
diff --git a/src/config.ts b/src/config.ts
index 8bcdc061..5d8a58e4 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -26,6 +26,7 @@ interface SBConfig {
hideInfoButtonPlayerControls: boolean,
hideDeleteButtonPlayerControls: boolean,
hideUploadButtonPlayerControls: boolean,
+ hideSkipButtonPlayerControls: boolean,
hideDiscordLaunches: number,
hideDiscordLink: boolean,
invidiousInstances: string[],
@@ -172,6 +173,7 @@ const Config: SBObject = {
hideInfoButtonPlayerControls: false,
hideDeleteButtonPlayerControls: false,
hideUploadButtonPlayerControls: false,
+ hideSkipButtonPlayerControls: false,
hideDiscordLaunches: 0,
hideDiscordLink: false,
invidiousInstances: ["invidious.snopyta.org"],
diff --git a/src/content.ts b/src/content.ts
index 56647c99..6d1dab93 100644
--- a/src/content.ts
+++ b/src/content.ts
@@ -1307,15 +1307,8 @@ async function createButtons(): Promise {
if (Config.config.autoHideInfoButton && !onInvidious && controlsContainer
&& playerButtons["info"]?.button && !controlsWithEventListeners.includes(controlsContainer)) {
controlsWithEventListeners.push(controlsContainer);
- playerButtons["info"].button.classList.add("hidden");
-
- controlsContainer.addEventListener("mouseenter", () => {
- playerButtons["info"].button.classList.remove("hidden");
- });
-
- controlsContainer.addEventListener("mouseleave", () => {
- playerButtons["info"].button.classList.add("hidden");
- });
+
+ utils.setupAutoHideAnimation(playerButtons["info"].button, controlsContainer);
}
}
diff --git a/src/js-components/skipButtonControlBar.ts b/src/js-components/skipButtonControlBar.ts
index 1ea03724..a3e47362 100644
--- a/src/js-components/skipButtonControlBar.ts
+++ b/src/js-components/skipButtonControlBar.ts
@@ -2,6 +2,8 @@ import Config from "../config";
import { SponsorTime } from "../types";
import { getSkippingText } from "../utils/categoryUtils";
+import Utils from "../utils";
+const utils = new Utils();
export interface SkipButtonControlBarProps {
skip: (segment: SponsorTime) => void;
@@ -53,13 +55,20 @@ export class SkipButtonControlBar {
if (leftControlsContainer && !leftControlsContainer.contains(this.container)) {
leftControlsContainer.insertBefore(this.container, this.chapterText);
+
+ if (Config.config.autoHideInfoButton) {
+ utils.setupAutoHideAnimation(this.skipIcon, leftControlsContainer, false, false);
+ }
}
}
enable(segment: SponsorTime, duration?: number): void {
if (duration) this.duration = duration;
this.segment = segment;
+
this.refreshText();
+ this.textContainer?.classList?.remove("hidden");
+ utils.disableAutoHideAnimation(this.skipIcon);
this.startTimer();
}
@@ -68,7 +77,8 @@ export class SkipButtonControlBar {
if (this.segment) {
this.chapterText?.classList?.add("hidden");
this.container.classList.remove("hidden");
- this.textContainer.innerText = getSkippingText([this.segment], false) + (this.showKeybindHint ? " (" + Config.config.skipKeybind + ")" : "");
+ this.textContainer.innerText = this.getTitle();
+ this.skipIcon.setAttribute("title", this.getTitle());
}
}
@@ -84,17 +94,42 @@ export class SkipButtonControlBar {
startTimer(): void {
this.stopTimer();
- this.timeout = setTimeout(() => this.disable(), Math.max(Config.config.skipNoticeDuration, this.duration) * 1000);
+ this.timeout = setTimeout(() => this.disableText(), Math.max(Config.config.skipNoticeDuration, this.duration) * 1000);
}
disable(): void {
this.container.classList.add("hidden");
+ this.textContainer?.classList?.remove("hidden");
+
this.chapterText?.classList?.remove("hidden");
+ this.getChapterPrefix()?.classList?.remove("hidden");
}
toggleSkip(): void {
this.skip(this.segment);
- this.disable();
+ this.disableText();
+ }
+
+ disableText(): void {
+ if (Config.config.hideVideoPlayerControls || Config.config.hideSkipButtonPlayerControls) {
+ this.disable();
+ return;
+ }
+
+ this.textContainer?.classList?.add("hidden");
+ this.chapterText?.classList?.remove("hidden");
+
+ this.getChapterPrefix()?.classList?.add("hidden");
+
+ utils.enableAutoHideAnimation(this.skipIcon);
+ }
+
+ private getTitle(): string {
+ return getSkippingText([this.segment], false) + (this.showKeybindHint ? " (" + Config.config.skipKeybind + ")" : "");
+ }
+
+ private getChapterPrefix(): HTMLElement {
+ return document.querySelector(".ytp-chapter-title-prefix");
}
}
diff --git a/src/utils.ts b/src/utils.ts
index 983c1c1b..50e332ae 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -183,6 +183,34 @@ export default class Utils {
}
}
+ setupAutoHideAnimation(element: Element, container: Element, enabled = true, rightSlide = true): void {
+ if (enabled) element.classList.add("autoHiding");
+ element.classList.add("hidden");
+ element.classList.add("animationDone");
+ if (!rightSlide) element.classList.add("autoHideLeft");
+
+ container.addEventListener("mouseenter", () => {
+ element.classList.remove("animationDone");
+
+ // Wait for next event loop
+ setTimeout(() => element.classList.remove("hidden"), 10);
+ });
+
+ container.addEventListener("mouseleave", () => {
+ if (element.classList.contains("autoHiding")) {
+ element.classList.add("hidden");
+ }
+ });
+ }
+
+ enableAutoHideAnimation(element: Element): void {
+ element.classList.add("autoHiding");
+ }
+
+ disableAutoHideAnimation(element: Element): void {
+ element.classList.remove("autoHiding");
+ }
+
/**
* Merges any overlapping timestamp ranges into single segments and returns them as a new array.
*/