mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-08 12:37:05 +03:00
Add skip to highlight to mobile
This commit is contained in:
@@ -526,9 +526,27 @@ input::-webkit-inner-spin-button {
|
|||||||
.skipButtonControlBarContainer {
|
.skipButtonControlBarContainer {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skipButtonControlBarContainer.hidden {
|
.skipButtonControlBarContainer.mobile {
|
||||||
|
bottom: 30%;
|
||||||
|
margin-left: 5px;
|
||||||
|
position: absolute;
|
||||||
|
height: 20px;
|
||||||
|
|
||||||
|
background-color: #00000030;
|
||||||
|
opacity: 0.5;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skipButtonControlBarContainer.mobile > div {
|
||||||
|
margin: auto;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skipButtonControlBarContainer.hidden, .skipButtonControlBarContainer.mobile .hidden {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -540,6 +558,10 @@ input::-webkit-inner-spin-button {
|
|||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile #sbSkipIconControlBarImage {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.sponsorBlockTooltip {
|
.sponsorBlockTooltip {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: rgba(28, 28, 28, 0.7);
|
background-color: rgba(28, 28, 28, 0.7);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { getCategoryActionType } from "./utils/categoryUtils";
|
|||||||
import { SkipButtonControlBar } from "./js-components/skipButtonControlBar";
|
import { SkipButtonControlBar } from "./js-components/skipButtonControlBar";
|
||||||
import { Tooltip } from "./render/Tooltip";
|
import { Tooltip } from "./render/Tooltip";
|
||||||
import { getStartTimeFromUrl } from "./utils/urlParser";
|
import { getStartTimeFromUrl } from "./utils/urlParser";
|
||||||
|
import { getControls } from "./utils/pageUtils";
|
||||||
|
|
||||||
// Hack to get the CSS loaded on permission-based sites (Invidious)
|
// Hack to get the CSS loaded on permission-based sites (Invidious)
|
||||||
utils.wait(() => Config.config !== null, 5000, 10).then(addCSS);
|
utils.wait(() => Config.config !== null, 5000, 10).then(addCSS);
|
||||||
@@ -338,6 +339,8 @@ async function videoIDChange(id) {
|
|||||||
function handleMobileControlsMutations(): void {
|
function handleMobileControlsMutations(): void {
|
||||||
updateVisibilityOfPlayerControlsButton();
|
updateVisibilityOfPlayerControlsButton();
|
||||||
|
|
||||||
|
skipButtonControlBar?.updateMobileControls();
|
||||||
|
|
||||||
if (previewBar !== null) {
|
if (previewBar !== null) {
|
||||||
if (document.body.contains(previewBar.container)) {
|
if (document.body.contains(previewBar.container)) {
|
||||||
const progressBarBackground = document.querySelector<HTMLElement>(".progress-bar-background");
|
const progressBarBackground = document.querySelector<HTMLElement>(".progress-bar-background");
|
||||||
@@ -652,7 +655,8 @@ function setupSkipButtonControlBar() {
|
|||||||
skippingSegments: [segment],
|
skippingSegments: [segment],
|
||||||
openNotice: true,
|
openNotice: true,
|
||||||
forceAutoSkip: true
|
forceAutoSkip: true
|
||||||
})
|
}),
|
||||||
|
onMobileYouTube
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1249,6 +1253,7 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u
|
|||||||
&& skippingSegments.length === 1
|
&& skippingSegments.length === 1
|
||||||
&& getCategoryActionType(skippingSegments[0].category) === CategoryActionType.POI) {
|
&& getCategoryActionType(skippingSegments[0].category) === CategoryActionType.POI) {
|
||||||
skipButtonControlBar.enable(skippingSegments[0], !Config.config.highlightCategoryUpdate ? 15 : 0);
|
skipButtonControlBar.enable(skippingSegments[0], !Config.config.highlightCategoryUpdate ? 15 : 0);
|
||||||
|
if (onMobileYouTube) skipButtonControlBar.setShowKeybindHint(false);
|
||||||
|
|
||||||
if (!Config.config.highlightCategoryUpdate) {
|
if (!Config.config.highlightCategoryUpdate) {
|
||||||
new Tooltip({
|
new Tooltip({
|
||||||
@@ -1269,6 +1274,7 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u
|
|||||||
//send out the message saying that a sponsor message was skipped
|
//send out the message saying that a sponsor message was skipped
|
||||||
if (!Config.config.dontShowNotice || !autoSkip) {
|
if (!Config.config.dontShowNotice || !autoSkip) {
|
||||||
const newSkipNotice = new SkipNotice(skippingSegments, autoSkip, skipNoticeContentContainer, unskipTime);
|
const newSkipNotice = new SkipNotice(skippingSegments, autoSkip, skipNoticeContentContainer, unskipTime);
|
||||||
|
if (onMobileYouTube) newSkipNotice.setShowKeybindHint(false);
|
||||||
skipNotices.push(newSkipNotice);
|
skipNotices.push(newSkipNotice);
|
||||||
|
|
||||||
activeSkipKeybindElement?.setShowKeybindHint(false);
|
activeSkipKeybindElement?.setShowKeybindHint(false);
|
||||||
@@ -1356,27 +1362,6 @@ function shouldSkip(segment: SponsorTime): boolean {
|
|||||||
(Config.config.autoSkipOnMusicVideos && sponsorTimes?.some((s) => s.category === "music_offtopic"));
|
(Config.config.autoSkipOnMusicVideos && sponsorTimes?.some((s) => s.category === "music_offtopic"));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getControls(): HTMLElement | false {
|
|
||||||
const controlsSelectors = [
|
|
||||||
// YouTube
|
|
||||||
".ytp-right-controls",
|
|
||||||
// Mobile YouTube
|
|
||||||
".player-controls-top",
|
|
||||||
// Invidious/videojs video element's controls element
|
|
||||||
".vjs-control-bar",
|
|
||||||
];
|
|
||||||
|
|
||||||
for (const controlsSelector of controlsSelectors) {
|
|
||||||
const controls = document.querySelectorAll(controlsSelector);
|
|
||||||
|
|
||||||
if (controls && controls.length > 0) {
|
|
||||||
return <HTMLElement> controls[controls.length - 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Creates any missing buttons on the YouTube player if possible. */
|
/** Creates any missing buttons on the YouTube player if possible. */
|
||||||
async function createButtons(): Promise<void> {
|
async function createButtons(): Promise<void> {
|
||||||
if (onMobileYouTube) return;
|
if (onMobileYouTube) return;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ const utils = new Utils();
|
|||||||
|
|
||||||
export interface SkipButtonControlBarProps {
|
export interface SkipButtonControlBarProps {
|
||||||
skip: (segment: SponsorTime) => void;
|
skip: (segment: SponsorTime) => void;
|
||||||
|
onMobileYouTube: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SkipButtonControlBar {
|
export class SkipButtonControlBar {
|
||||||
@@ -18,6 +19,9 @@ export class SkipButtonControlBar {
|
|||||||
segment: SponsorTime;
|
segment: SponsorTime;
|
||||||
|
|
||||||
showKeybindHint = true;
|
showKeybindHint = true;
|
||||||
|
onMobileYouTube: boolean;
|
||||||
|
|
||||||
|
enabled = false;
|
||||||
|
|
||||||
timeout: NodeJS.Timeout;
|
timeout: NodeJS.Timeout;
|
||||||
duration = 0;
|
duration = 0;
|
||||||
@@ -26,10 +30,12 @@ export class SkipButtonControlBar {
|
|||||||
|
|
||||||
constructor(props: SkipButtonControlBarProps) {
|
constructor(props: SkipButtonControlBarProps) {
|
||||||
this.skip = props.skip;
|
this.skip = props.skip;
|
||||||
|
this.onMobileYouTube = props.onMobileYouTube;
|
||||||
|
|
||||||
this.container = document.createElement("div");
|
this.container = document.createElement("div");
|
||||||
this.container.classList.add("skipButtonControlBarContainer");
|
this.container.classList.add("skipButtonControlBarContainer");
|
||||||
this.container.classList.add("hidden");
|
this.container.classList.add("hidden");
|
||||||
|
if (this.onMobileYouTube) this.container.classList.add("mobile");
|
||||||
|
|
||||||
this.skipIcon = document.createElement("img");
|
this.skipIcon = document.createElement("img");
|
||||||
this.skipIcon.src = chrome.runtime.getURL("icons/skipIcon.svg");
|
this.skipIcon.src = chrome.runtime.getURL("icons/skipIcon.svg");
|
||||||
@@ -50,21 +56,34 @@ export class SkipButtonControlBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
attachToPage(): void {
|
attachToPage(): void {
|
||||||
const leftControlsContainer = document.querySelector(".ytp-left-controls");
|
const mountingContainer = this.getMountingContainer();
|
||||||
this.chapterText = document.querySelector(".ytp-chapter-container");
|
this.chapterText = document.querySelector(".ytp-chapter-container");
|
||||||
|
|
||||||
if (leftControlsContainer && !leftControlsContainer.contains(this.container)) {
|
if (mountingContainer && !mountingContainer.contains(this.container)) {
|
||||||
leftControlsContainer.insertBefore(this.container, this.chapterText);
|
if (this.onMobileYouTube) {
|
||||||
|
mountingContainer.appendChild(this.container);
|
||||||
if (Config.config.autoHideInfoButton) {
|
} else {
|
||||||
utils.setupAutoHideAnimation(this.skipIcon, leftControlsContainer, false, false);
|
mountingContainer.insertBefore(this.container, this.chapterText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Config.config.autoHideInfoButton && !this.onMobileYouTube) {
|
||||||
|
utils.setupAutoHideAnimation(this.skipIcon, mountingContainer, false, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
enable(segment: SponsorTime, duration?: number): void {
|
||||||
if (duration) this.duration = duration;
|
if (duration) this.duration = duration;
|
||||||
this.segment = segment;
|
this.segment = segment;
|
||||||
|
this.enabled = true;
|
||||||
|
|
||||||
this.refreshText();
|
this.refreshText();
|
||||||
this.textContainer?.classList?.remove("hidden");
|
this.textContainer?.classList?.remove("hidden");
|
||||||
@@ -97,12 +116,14 @@ export class SkipButtonControlBar {
|
|||||||
this.timeout = setTimeout(() => this.disableText(), Math.max(Config.config.skipNoticeDuration, this.duration) * 1000);
|
this.timeout = setTimeout(() => this.disableText(), Math.max(Config.config.skipNoticeDuration, this.duration) * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
disable(): void {
|
disable(keepActive = false): void {
|
||||||
this.container.classList.add("hidden");
|
this.container.classList.add("hidden");
|
||||||
this.textContainer?.classList?.remove("hidden");
|
this.textContainer?.classList?.remove("hidden");
|
||||||
|
|
||||||
this.chapterText?.classList?.remove("hidden");
|
this.chapterText?.classList?.remove("hidden");
|
||||||
this.getChapterPrefix()?.classList?.remove("hidden");
|
this.getChapterPrefix()?.classList?.remove("hidden");
|
||||||
|
|
||||||
|
if (!keepActive) this.enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleSkip(): void {
|
toggleSkip(): void {
|
||||||
@@ -110,12 +131,13 @@ export class SkipButtonControlBar {
|
|||||||
this.disableText();
|
this.disableText();
|
||||||
}
|
}
|
||||||
|
|
||||||
disableText(): void {
|
disableText(forceNotDisable = false): void {
|
||||||
if (Config.config.hideVideoPlayerControls || Config.config.hideSkipButtonPlayerControls) {
|
if (!forceNotDisable && (Config.config.hideVideoPlayerControls || Config.config.hideSkipButtonPlayerControls || this.onMobileYouTube)) {
|
||||||
this.disable();
|
this.disable(this.onMobileYouTube);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.container.classList.remove("hidden");
|
||||||
this.textContainer?.classList?.add("hidden");
|
this.textContainer?.classList?.add("hidden");
|
||||||
this.chapterText?.classList?.remove("hidden");
|
this.chapterText?.classList?.remove("hidden");
|
||||||
|
|
||||||
@@ -124,6 +146,19 @@ export class SkipButtonControlBar {
|
|||||||
utils.enableAutoHideAnimation(this.skipIcon);
|
utils.enableAutoHideAnimation(this.skipIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateMobileControls(): void {
|
||||||
|
const overlay = document.getElementById("player-control-overlay");
|
||||||
|
|
||||||
|
if (overlay && this.enabled) {
|
||||||
|
if (overlay?.classList?.contains("pointer-events-off")) {
|
||||||
|
this.disable(true);
|
||||||
|
} else {
|
||||||
|
this.disableText(true);
|
||||||
|
this.skipIcon.classList.remove("hidden");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private getTitle(): string {
|
private getTitle(): string {
|
||||||
return getSkippingText([this.segment], false) + (this.showKeybindHint ? " (" + Config.config.skipKeybind + ")" : "");
|
return getSkippingText([this.segment], false) + (this.showKeybindHint ? " (" + Config.config.skipKeybind + ")" : "");
|
||||||
}
|
}
|
||||||
|
|||||||
20
src/utils/pageUtils.ts
Normal file
20
src/utils/pageUtils.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
export function getControls(): HTMLElement | false {
|
||||||
|
const controlsSelectors = [
|
||||||
|
// YouTube
|
||||||
|
".ytp-right-controls",
|
||||||
|
// Mobile YouTube
|
||||||
|
".player-controls-top",
|
||||||
|
// Invidious/videojs video element's controls element
|
||||||
|
".vjs-control-bar",
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const controlsSelector of controlsSelectors) {
|
||||||
|
const controls = document.querySelectorAll(controlsSelector);
|
||||||
|
|
||||||
|
if (controls && controls.length > 0) {
|
||||||
|
return <HTMLElement> controls[controls.length - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user