Add skip to highlight to mobile

This commit is contained in:
Ajay Ramachandran 2021-10-21 01:30:52 -04:00
parent d1e6421e5b
commit c803ae9499
4 changed files with 95 additions and 33 deletions

View file

@ -526,9 +526,27 @@ input::-webkit-inner-spin-button {
.skipButtonControlBarContainer {
cursor: pointer;
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;
}
@ -540,6 +558,10 @@ input::-webkit-inner-spin-button {
margin: auto;
}
.mobile #sbSkipIconControlBarImage {
height: 100%;
}
.sponsorBlockTooltip {
position: absolute;
background-color: rgba(28, 28, 28, 0.7);

View file

@ -17,6 +17,7 @@ import { getCategoryActionType } from "./utils/categoryUtils";
import { SkipButtonControlBar } from "./js-components/skipButtonControlBar";
import { Tooltip } from "./render/Tooltip";
import { getStartTimeFromUrl } from "./utils/urlParser";
import { getControls } from "./utils/pageUtils";
// Hack to get the CSS loaded on permission-based sites (Invidious)
utils.wait(() => Config.config !== null, 5000, 10).then(addCSS);
@ -338,6 +339,8 @@ async function videoIDChange(id) {
function handleMobileControlsMutations(): void {
updateVisibilityOfPlayerControlsButton();
skipButtonControlBar?.updateMobileControls();
if (previewBar !== null) {
if (document.body.contains(previewBar.container)) {
const progressBarBackground = document.querySelector<HTMLElement>(".progress-bar-background");
@ -652,7 +655,8 @@ function setupSkipButtonControlBar() {
skippingSegments: [segment],
openNotice: true,
forceAutoSkip: true
})
}),
onMobileYouTube
});
}
@ -1249,6 +1253,7 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u
&& skippingSegments.length === 1
&& getCategoryActionType(skippingSegments[0].category) === CategoryActionType.POI) {
skipButtonControlBar.enable(skippingSegments[0], !Config.config.highlightCategoryUpdate ? 15 : 0);
if (onMobileYouTube) skipButtonControlBar.setShowKeybindHint(false);
if (!Config.config.highlightCategoryUpdate) {
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
if (!Config.config.dontShowNotice || !autoSkip) {
const newSkipNotice = new SkipNotice(skippingSegments, autoSkip, skipNoticeContentContainer, unskipTime);
if (onMobileYouTube) newSkipNotice.setShowKeybindHint(false);
skipNotices.push(newSkipNotice);
activeSkipKeybindElement?.setShowKeybindHint(false);
@ -1356,27 +1362,6 @@ function shouldSkip(segment: SponsorTime): boolean {
(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. */
async function createButtons(): Promise<void> {
if (onMobileYouTube) return;

View file

@ -7,6 +7,7 @@ const utils = new Utils();
export interface SkipButtonControlBarProps {
skip: (segment: SponsorTime) => void;
onMobileYouTube: boolean;
}
export class SkipButtonControlBar {
@ -18,6 +19,9 @@ export class SkipButtonControlBar {
segment: SponsorTime;
showKeybindHint = true;
onMobileYouTube: boolean;
enabled = false;
timeout: NodeJS.Timeout;
duration = 0;
@ -26,10 +30,12 @@ export class SkipButtonControlBar {
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");
@ -50,21 +56,34 @@ 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 (Config.config.autoHideInfoButton) {
utils.setupAutoHideAnimation(this.skipIcon, leftControlsContainer, false, false);
if (mountingContainer && !mountingContainer.contains(this.container)) {
if (this.onMobileYouTube) {
mountingContainer.appendChild(this.container);
} else {
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 {
if (duration) this.duration = duration;
this.segment = segment;
this.enabled = true;
this.refreshText();
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);
}
disable(): void {
disable(keepActive = false): void {
this.container.classList.add("hidden");
this.textContainer?.classList?.remove("hidden");
this.chapterText?.classList?.remove("hidden");
this.getChapterPrefix()?.classList?.remove("hidden");
if (!keepActive) this.enabled = false;
}
toggleSkip(): void {
@ -110,12 +131,13 @@ export class SkipButtonControlBar {
this.disableText();
}
disableText(): void {
if (Config.config.hideVideoPlayerControls || Config.config.hideSkipButtonPlayerControls) {
this.disable();
disableText(forceNotDisable = false): void {
if (!forceNotDisable && (Config.config.hideVideoPlayerControls || Config.config.hideSkipButtonPlayerControls || this.onMobileYouTube)) {
this.disable(this.onMobileYouTube);
return;
}
this.container.classList.remove("hidden");
this.textContainer?.classList?.add("hidden");
this.chapterText?.classList?.remove("hidden");
@ -124,6 +146,19 @@ export class SkipButtonControlBar {
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 {
return getSkippingText([this.segment], false) + (this.showKeybindHint ? " (" + Config.config.skipKeybind + ")" : "");
}

20
src/utils/pageUtils.ts Normal file
View 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;
}