aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/js-components/skipButtonControlBar.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/js-components/skipButtonControlBar.ts')
-rw-r--r--src/js-components/skipButtonControlBar.ts96
1 files changed, 91 insertions, 5 deletions
diff --git a/src/js-components/skipButtonControlBar.ts b/src/js-components/skipButtonControlBar.ts
index a3e47362..6f898d7f 100644
--- a/src/js-components/skipButtonControlBar.ts
+++ b/src/js-components/skipButtonControlBar.ts
@@ -7,6 +7,7 @@ const utils = new Utils();
export interface SkipButtonControlBarProps {
skip: (segment: SponsorTime) => void;
+ onMobileYouTube: boolean;
}
export class SkipButtonControlBar {
@@ -18,18 +19,31 @@ export class SkipButtonControlBar {
segment: SponsorTime;
showKeybindHint = true;
+ onMobileYouTube: boolean;
+
+ enabled = false;
timeout: NodeJS.Timeout;
duration = 0;
skip: (segment: SponsorTime) => void;
+ // Used if on mobile page
+ hideButton: () => void;
+ showButton: () => void;
+
+ // Used by mobile only for swiping away
+ left = 0;
+ swipeStart = 0;
+
constructor(props: SkipButtonControlBarProps) {
this.skip = props.skip;
+ this.onMobileYouTube = props.onMobileYouTube;
this.container = document.createElement("div");
this.container.classList.add("skipButtonControlBarContainer");
this.container.classList.add("hidden");
+ if (this.onMobileYouTube) this.container.classList.add("mobile");
this.skipIcon = document.createElement("img");
this.skipIcon.src = chrome.runtime.getURL("icons/skipIcon.svg");
@@ -43,6 +57,11 @@ export class SkipButtonControlBar {
this.container.addEventListener("click", () => this.toggleSkip());
this.container.addEventListener("mouseenter", () => this.stopTimer());
this.container.addEventListener("mouseleave", () => this.startTimer());
+ if (this.onMobileYouTube) {
+ this.container.addEventListener("touchstart", (e) => this.handleTouchStart(e));
+ this.container.addEventListener("touchmove", (e) => this.handleTouchMove(e));
+ this.container.addEventListener("touchend", () => this.handleTouchEnd());
+ }
}
getElement(): HTMLElement {
@@ -50,21 +69,38 @@ export class SkipButtonControlBar {
}
attachToPage(): void {
- const leftControlsContainer = document.querySelector(".ytp-left-controls");
+ const mountingContainer = this.getMountingContainer();
this.chapterText = document.querySelector(".ytp-chapter-container");
- if (leftControlsContainer && !leftControlsContainer.contains(this.container)) {
- leftControlsContainer.insertBefore(this.container, this.chapterText);
+ if (mountingContainer && !mountingContainer.contains(this.container)) {
+ if (this.onMobileYouTube) {
+ mountingContainer.appendChild(this.container);
+ } else {
+ mountingContainer.insertBefore(this.container, this.chapterText);
+ }
- if (Config.config.autoHideInfoButton) {
- utils.setupAutoHideAnimation(this.skipIcon, leftControlsContainer, false, false);
+ if (Config.config.autoHideInfoButton && !this.onMobileYouTube) {
+ utils.setupAutoHideAnimation(this.skipIcon, mountingContainer, false, false);
+ } else {
+ const { hide, show } = utils.setupCustomHideAnimation(this.skipIcon, mountingContainer, false, false);
+ this.hideButton = hide;
+ this.showButton = show;
}
}
}
+ private getMountingContainer(): HTMLElement {
+ if (!this.onMobileYouTube) {
+ return document.querySelector(".ytp-left-controls");
+ } else {
+ return document.getElementById("player-container-id");
+ }
+ }
+
enable(segment: SponsorTime, duration?: number): void {
if (duration) this.duration = duration;
this.segment = segment;
+ this.enabled = true;
this.refreshText();
this.textContainer?.classList?.remove("hidden");
@@ -103,6 +139,8 @@ export class SkipButtonControlBar {
this.chapterText?.classList?.remove("hidden");
this.getChapterPrefix()?.classList?.remove("hidden");
+
+ this.enabled = false;
}
toggleSkip(): void {
@@ -116,12 +154,28 @@ export class SkipButtonControlBar {
return;
}
+ this.container.classList.add("textDisabled");
this.textContainer?.classList?.add("hidden");
this.chapterText?.classList?.remove("hidden");
this.getChapterPrefix()?.classList?.add("hidden");
utils.enableAutoHideAnimation(this.skipIcon);
+ if (this.onMobileYouTube) {
+ this.hideButton();
+ }
+ }
+
+ updateMobileControls(): void {
+ const overlay = document.getElementById("player-control-overlay");
+
+ if (overlay && this.enabled) {
+ if (overlay?.classList?.contains("pointer-events-off")) {
+ this.hideButton();
+ } else {
+ this.showButton();
+ }
+ }
}
private getTitle(): string {
@@ -131,5 +185,37 @@ export class SkipButtonControlBar {
private getChapterPrefix(): HTMLElement {
return document.querySelector(".ytp-chapter-title-prefix");
}
+
+ // Swiping away on mobile
+ private handleTouchStart(event: TouchEvent): void {
+ this.swipeStart = event.touches[0].clientX;
+ }
+
+ // Swiping away on mobile
+ private handleTouchMove(event: TouchEvent): void {
+ const distanceMoved = this.swipeStart - event.touches[0].clientX;
+ this.left = Math.min(-distanceMoved, 0);
+
+ this.updateLeftStyle();
+ }
+
+ // Swiping away on mobile
+ private handleTouchEnd(): void {
+ if (this.left < -this.container.offsetWidth / 2) {
+ this.disableText();
+
+ // Don't let animation play
+ this.skipIcon.style.display = "none";
+ setTimeout(() => this.skipIcon.style.removeProperty("display"), 200);
+ }
+
+ this.left = 0;
+ this.updateLeftStyle();
+ }
+
+ // Swiping away on mobile
+ private updateLeftStyle() {
+ this.container.style.left = this.left + "px";
+ }
}