mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-06 11:37:02 +03:00
Merge pull request #2187 from tech234a/master
Implement support for YouTube TV (tv.youtube.com)
This commit is contained in:
Submodule maze-utils updated: de2cda1e75...601df1ea1b
Submodule public/_locales updated: 2653a15038...e2794273bd
@@ -31,6 +31,15 @@
|
||||
transition: transform .1s cubic-bezier(0,0,0.2,1);
|
||||
}
|
||||
|
||||
/* Prevent bar from covering highlights on YTTV */
|
||||
#previewbar.sponsorblock-yttv-container {
|
||||
z-index: unset;
|
||||
}
|
||||
|
||||
ytu-time-bar.ytu-storyboard {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* May 2024 hover preview */
|
||||
.YtPlayerProgressBarProgressBar #previewbar {
|
||||
transform: none;
|
||||
@@ -67,6 +76,11 @@ div:hover > #previewbar.sbNotInvidious {
|
||||
min-width: 1px;
|
||||
}
|
||||
|
||||
.previewbar-yttv {
|
||||
height: 10px;
|
||||
top: 14px;
|
||||
}
|
||||
|
||||
.previewbar.requiredSegment {
|
||||
transform: scaleY(3);
|
||||
}
|
||||
@@ -184,6 +198,16 @@ div:hover > .sponsorBlockChapterBar {
|
||||
padding-right: 3.6px;
|
||||
}
|
||||
|
||||
.sbButtonYTTV {
|
||||
padding-left: 5px !important;
|
||||
}
|
||||
|
||||
/* YTTV only */
|
||||
.ytu-player-controls > .skipButtonControlBarContainer > div {
|
||||
padding-left: 5px;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.autoHiding {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ class ChapterVoteComponent extends React.Component<ChapterVoteProps, ChapterVote
|
||||
<>
|
||||
{/* Upvote Button */}
|
||||
<button id={"sponsorTimesDownvoteButtonsContainerUpvoteChapter"}
|
||||
className={"playerButton sbPlayerUpvote ytp-button " + (!this.state.show ? "sbhidden" : "")}
|
||||
className={"playerButton sbPlayerUpvote ytp-button " + (!this.state.show ? "sbhidden " : " ") + (document.location.host === "tv.youtube.com" ? "sbButtonYTTV" : "")}
|
||||
draggable="false"
|
||||
title={chrome.i18n.getMessage("upvoteButtonInfo")}
|
||||
onClick={(e) => this.vote(e, 1)}>
|
||||
@@ -55,7 +55,7 @@ class ChapterVoteComponent extends React.Component<ChapterVoteProps, ChapterVote
|
||||
|
||||
{/* Downvote Button */}
|
||||
<button id={"sponsorTimesDownvoteButtonsContainerDownvoteChapter"}
|
||||
className={"playerButton sbPlayerDownvote ytp-button " + (!this.state.show ? "sbhidden" : "")}
|
||||
className={"playerButton sbPlayerDownvote ytp-button " + (!this.state.show ? "sbhidden " : " ") + (document.location.host === "tv.youtube.com" ? "sbButtonYTTV" : "")}
|
||||
draggable="false"
|
||||
title={chrome.i18n.getMessage("reportButtonInfo")}
|
||||
onClick={(e) => {
|
||||
|
||||
@@ -35,7 +35,7 @@ import { ChapterVote } from "./render/ChapterVote";
|
||||
import { openWarningDialog } from "./utils/warnings";
|
||||
import { isFirefoxOrSafari, waitFor } from "../maze-utils/src";
|
||||
import { getErrorMessage, getFormattedTime } from "../maze-utils/src/formating";
|
||||
import { getChannelIDInfo, getVideo, getIsAdPlaying, getIsLivePremiere, setIsAdPlaying, checkVideoIDChange, getVideoID, getYouTubeVideoID, setupVideoModule, checkIfNewVideoID, isOnInvidious, isOnMobileYouTube, getLastNonInlineVideoID, triggerVideoIDChange, triggerVideoElementChange, getIsInline, getCurrentTime, setCurrentTime, getVideoDuration, verifyCurrentTime, waitForVideo } from "../maze-utils/src/video";
|
||||
import { getChannelIDInfo, getVideo, getIsAdPlaying, getIsLivePremiere, setIsAdPlaying, checkVideoIDChange, getVideoID, getYouTubeVideoID, setupVideoModule, checkIfNewVideoID, isOnInvidious, isOnMobileYouTube, isOnYTTV, getLastNonInlineVideoID, triggerVideoIDChange, triggerVideoElementChange, getIsInline, getCurrentTime, setCurrentTime, getVideoDuration, verifyCurrentTime, waitForVideo } from "../maze-utils/src/video";
|
||||
import { Keybind, StorageChangesObject, isSafari, keybindEquals, keybindToString } from "../maze-utils/src/config";
|
||||
import { findValidElement } from "../maze-utils/src/dom"
|
||||
import { getHash, HashedValue } from "../maze-utils/src/hash";
|
||||
@@ -240,7 +240,8 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo
|
||||
break;
|
||||
case "getChannelID":
|
||||
sendResponse({
|
||||
channelID: getChannelIDInfo().id
|
||||
channelID: getChannelIDInfo().id,
|
||||
isYTTV: (document.location.host === "tv.youtube.com")
|
||||
});
|
||||
|
||||
break;
|
||||
@@ -553,6 +554,10 @@ function getPreviewBarAttachElement(): HTMLElement | null {
|
||||
}, {
|
||||
// For Vorapis v3
|
||||
selector: ".ytp-progress-bar-container > .html5-progress-bar > .ytp-progress-list"
|
||||
}, {
|
||||
// For YTTV
|
||||
selector: ".yssi-slider > div.ytu-ss-timeline-container",
|
||||
isVisibleCheck: false
|
||||
}
|
||||
];
|
||||
|
||||
@@ -578,7 +583,7 @@ function createPreviewBar(): void {
|
||||
|
||||
if (el) {
|
||||
const chapterVote = new ChapterVote(voteAsync);
|
||||
previewBar = new PreviewBar(el, isOnMobileYouTube(), isOnInvidious(), chapterVote, () => importExistingChapters(true));
|
||||
previewBar = new PreviewBar(el, isOnMobileYouTube(), isOnInvidious(), isOnYTTV(), chapterVote, () => importExistingChapters(true));
|
||||
|
||||
updatePreviewBar();
|
||||
}
|
||||
@@ -1147,7 +1152,8 @@ function setupSkipButtonControlBar() {
|
||||
forceAutoSkip: true
|
||||
}),
|
||||
selectSegment,
|
||||
onMobileYouTube: isOnMobileYouTube()
|
||||
onMobileYouTube: isOnMobileYouTube(),
|
||||
onYTTV: isOnYTTV(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1850,6 +1856,9 @@ function createButton(baseID: string, title: string, callback: () => void, image
|
||||
newButton.id = baseID + "Button";
|
||||
newButton.classList.add("playerButton");
|
||||
newButton.classList.add("ytp-button");
|
||||
if (isOnYTTV()) {
|
||||
newButton.setAttribute("style", "width: 40px; height: 40px");
|
||||
}
|
||||
newButton.setAttribute("title", chrome.i18n.getMessage(title));
|
||||
newButton.addEventListener("click", () => {
|
||||
callback();
|
||||
@@ -1924,7 +1933,7 @@ async function updateVisibilityOfPlayerControlsButton(): Promise<void> {
|
||||
updateEditButtonsOnPlayer();
|
||||
|
||||
// Don't show the info button on embeds
|
||||
if (Config.config.hideInfoButtonPlayerControls || document.URL.includes("/embed/") || isOnInvidious()
|
||||
if (Config.config.hideInfoButtonPlayerControls || document.URL.includes("/embed/") || isOnInvidious() || isOnYTTV()
|
||||
|| document.getElementById("sponsorBlockPopupContainer") != null) {
|
||||
playerButtons.info.button.style.display = "none";
|
||||
} else {
|
||||
@@ -1991,6 +2000,11 @@ function getRealCurrentTime(): number {
|
||||
}
|
||||
|
||||
function startOrEndTimingNewSegment() {
|
||||
if (isOnYTTV() && getIsLivePremiere()) {
|
||||
alert(chrome.i18n.getMessage("yttvLiveContentWarning"));
|
||||
return;
|
||||
}
|
||||
|
||||
verifyCurrentTime();
|
||||
const roundedTime = Math.round((getRealCurrentTime() + Number.EPSILON) * 1000) / 1000;
|
||||
if (!isSegmentCreationInProgress()) {
|
||||
@@ -2694,6 +2708,7 @@ function showTimeWithoutSkips(skippedDuration: number): void {
|
||||
// YouTube player time display
|
||||
const selector =
|
||||
isOnInvidious() ? ".vjs-duration" :
|
||||
isOnYTTV() ? ".ypl-full-controls .ypmcs-control .time-info-bar" :
|
||||
isOnMobileYouTube() ? ".ytwPlayerTimeDisplayContent" :
|
||||
".ytp-time-display.notranslate .ytp-time-wrapper";
|
||||
const display = document.querySelector(selector);
|
||||
|
||||
@@ -15,6 +15,7 @@ import { findValidElement } from "../../maze-utils/src/dom";
|
||||
import { addCleanupListener } from "../../maze-utils/src/cleanup";
|
||||
import { hasAutogeneratedChapters, isVisible } from "../utils/pageUtils";
|
||||
import { isVorapisInstalled } from "../utils/compatibility";
|
||||
import { isOnYTTV } from "../../maze-utils/src/video";
|
||||
|
||||
const TOOLTIP_VISIBLE_CLASS = 'sponsorCategoryTooltipVisible';
|
||||
const MIN_CHAPTER_SIZE = 0.003;
|
||||
@@ -41,6 +42,12 @@ class PreviewBar {
|
||||
categoryTooltip?: HTMLDivElement;
|
||||
categoryTooltipContainer?: HTMLElement;
|
||||
chapterTooltip?: HTMLDivElement;
|
||||
|
||||
// ScrubTooltips for YTTV only
|
||||
categoryScrubTooltip?: HTMLDivElement;
|
||||
categoryScrubTooltipContainer?: HTMLElement;
|
||||
chapterScrubTooltip?: HTMLDivElement;
|
||||
|
||||
lastSmallestSegment: Record<string, {
|
||||
index: number;
|
||||
segment: PreviewBarSegment;
|
||||
@@ -49,6 +56,7 @@ class PreviewBar {
|
||||
parent: HTMLElement;
|
||||
onMobileYouTube: boolean;
|
||||
onInvidious: boolean;
|
||||
onYTTV: boolean;
|
||||
progressBar: HTMLElement;
|
||||
|
||||
segments: PreviewBarSegment[] = [];
|
||||
@@ -70,14 +78,19 @@ class PreviewBar {
|
||||
unfilteredChapterGroups: ChapterGroup[];
|
||||
chapterGroups: ChapterGroup[];
|
||||
|
||||
constructor(parent: HTMLElement, onMobileYouTube: boolean, onInvidious: boolean, chapterVote: ChapterVote, updateExistingChapters: () => void, test=false) {
|
||||
constructor(parent: HTMLElement, onMobileYouTube: boolean, onInvidious: boolean, onYTTV: boolean, chapterVote: ChapterVote, updateExistingChapters: () => void, test=false) {
|
||||
if (test) return;
|
||||
this.container = document.createElement('ul');
|
||||
this.container.id = 'previewbar';
|
||||
|
||||
if (onYTTV) {
|
||||
this.container.classList.add("sponsorblock-yttv-container");
|
||||
}
|
||||
|
||||
this.parent = parent;
|
||||
this.onMobileYouTube = onMobileYouTube;
|
||||
this.onInvidious = onInvidious;
|
||||
this.onYTTV = onYTTV;
|
||||
this.chapterVote = chapterVote;
|
||||
this.updateExistingChapters = updateExistingChapters;
|
||||
|
||||
@@ -97,26 +110,49 @@ class PreviewBar {
|
||||
|
||||
// Create label placeholder
|
||||
this.categoryTooltip = document.createElement("div");
|
||||
this.categoryTooltip.className = "ytp-tooltip-title sponsorCategoryTooltip";
|
||||
if (isOnYTTV()) {
|
||||
this.categoryTooltip.className = "sponsorCategoryTooltip";
|
||||
} else {
|
||||
this.categoryTooltip.className = "ytp-tooltip-title sponsorCategoryTooltip";
|
||||
}
|
||||
this.chapterTooltip = document.createElement("div");
|
||||
this.chapterTooltip.className = "ytp-tooltip-title sponsorCategoryTooltip";
|
||||
if (isOnYTTV()) {
|
||||
this.chapterTooltip.className = "sponsorCategoryTooltip";
|
||||
} else {
|
||||
this.chapterTooltip.className = "ytp-tooltip-title sponsorCategoryTooltip";
|
||||
}
|
||||
|
||||
// global chaper tooltip or duration tooltip
|
||||
// YT, Vorapis, unknown
|
||||
const tooltipTextWrapper = document.querySelector(".ytp-tooltip-text-wrapper, .ytp-progress-tooltip-text-container") ?? document.querySelector("#progress-bar-container.ytk-player > #hover-time-info");
|
||||
const originalTooltip = tooltipTextWrapper.querySelector(".ytp-tooltip-title:not(.sponsorCategoryTooltip), .ytp-progress-tooltip-text:not(.sponsorCategoryTooltip)") as HTMLElement;
|
||||
if (isOnYTTV()) {
|
||||
this.categoryScrubTooltip = document.createElement("div");
|
||||
this.categoryScrubTooltip.className = "sponsorCategoryTooltip";
|
||||
this.chapterScrubTooltip = document.createElement("div");
|
||||
this.chapterScrubTooltip.className = "sponsorCategoryTooltip";
|
||||
}
|
||||
|
||||
// global chapter tooltip or duration tooltip
|
||||
// YT, Vorapis, unknown, YTTV
|
||||
const tooltipTextWrapper = document.querySelector(".ytp-tooltip-text-wrapper, .ytp-progress-tooltip-text-container, .yssi-slider .ys-seek-details .time-info-bar") ?? document.querySelector("#progress-bar-container.ytk-player > #hover-time-info");
|
||||
const originalTooltip = tooltipTextWrapper.querySelector(".ytp-tooltip-title:not(.sponsorCategoryTooltip), .ytp-progress-tooltip-text:not(.sponsorCategoryTooltip), .current-time:not(.sponsorCategoryTooltip)") as HTMLElement;
|
||||
if (!tooltipTextWrapper || !tooltipTextWrapper.parentElement) return;
|
||||
|
||||
// Grab the tooltip from the text wrapper as the tooltip doesn't have its classes on init
|
||||
this.categoryTooltipContainer = tooltipTextWrapper.parentElement;
|
||||
// YT, Vorapis
|
||||
const titleTooltip = tooltipTextWrapper.querySelector(".ytp-tooltip-title, .ytp-progress-tooltip-text") as HTMLElement;
|
||||
// YT, Vorapis, YTTV
|
||||
const titleTooltip = tooltipTextWrapper.querySelector(".ytp-tooltip-title, .ytp-progress-tooltip-text, .current-time") as HTMLElement;
|
||||
if (!this.categoryTooltipContainer || !titleTooltip) return;
|
||||
|
||||
tooltipTextWrapper.insertBefore(this.categoryTooltip, titleTooltip.nextSibling);
|
||||
tooltipTextWrapper.insertBefore(this.chapterTooltip, titleTooltip.nextSibling);
|
||||
|
||||
const seekBar = document.querySelector(".ytp-progress-bar-container");
|
||||
if (isOnYTTV()) {
|
||||
const scrubTooltipTextWrapper = document.querySelector(".yssi-slider .ysl-filmstrip-lens .time-info-bar")
|
||||
if (!this.categoryTooltipContainer) return;
|
||||
|
||||
scrubTooltipTextWrapper.appendChild(this.categoryScrubTooltip);
|
||||
scrubTooltipTextWrapper.appendChild(this.chapterScrubTooltip);
|
||||
}
|
||||
|
||||
const seekBar = (document.querySelector(".ytp-progress-bar-container, .ypcs-scrub-slider-slot.ytu-player-controls"));
|
||||
if (!seekBar) return;
|
||||
|
||||
let mouseOnSeekBar = false;
|
||||
@@ -163,6 +199,12 @@ class PreviewBar {
|
||||
this.categoryTooltipContainer.classList.remove(TOOLTIP_VISIBLE_CLASS);
|
||||
originalTooltip.style.removeProperty("display");
|
||||
}
|
||||
if (this.onYTTV) {
|
||||
this.setTooltipTitle(mainSegment, this.categoryTooltip);
|
||||
this.setTooltipTitle(secondarySegment, this.chapterTooltip);
|
||||
this.setTooltipTitle(mainSegment, this.categoryScrubTooltip);
|
||||
this.setTooltipTitle(secondarySegment, this.chapterScrubTooltip);
|
||||
}
|
||||
} else {
|
||||
this.categoryTooltipContainer.classList.add(TOOLTIP_VISIBLE_CLASS);
|
||||
if (mainSegment !== null && secondarySegment !== null) {
|
||||
@@ -174,6 +216,10 @@ class PreviewBar {
|
||||
|
||||
this.setTooltipTitle(mainSegment, this.categoryTooltip);
|
||||
this.setTooltipTitle(secondarySegment, this.chapterTooltip);
|
||||
if (this.onYTTV) {
|
||||
this.setTooltipTitle(mainSegment, this.categoryScrubTooltip);
|
||||
this.setTooltipTitle(secondarySegment, this.chapterScrubTooltip);
|
||||
}
|
||||
|
||||
if (isVorapisInstalled()) {
|
||||
const tooltipParent = tooltipTextWrapper.parentElement!;
|
||||
@@ -226,7 +272,12 @@ class PreviewBar {
|
||||
}
|
||||
|
||||
// On the seek bar
|
||||
this.parent.prepend(this.container);
|
||||
if (this.onYTTV) {
|
||||
// order of sibling elements matters on YTTV
|
||||
this.parent.insertBefore(this.container, this.parent.firstChild.nextSibling.nextSibling);
|
||||
} else {
|
||||
this.parent.prepend(this.container);
|
||||
}
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
@@ -362,6 +413,10 @@ class PreviewBar {
|
||||
bar.style.marginRight = `${this.chapterMargin}px`;
|
||||
}
|
||||
|
||||
if (this.onYTTV) {
|
||||
bar.classList.add("previewbar-yttv");
|
||||
}
|
||||
|
||||
return bar;
|
||||
}
|
||||
|
||||
@@ -868,8 +923,10 @@ class PreviewBar {
|
||||
})[0];
|
||||
|
||||
const chapterButton = this.getChapterButton(chaptersContainer);
|
||||
chapterButton.classList.remove("ytp-chapter-container-disabled");
|
||||
chapterButton.disabled = false;
|
||||
if (chapterButton) {
|
||||
chapterButton.classList.remove("ytp-chapter-container-disabled");
|
||||
chapterButton.disabled = false;
|
||||
}
|
||||
|
||||
const chapterTitle = chaptersContainer.querySelector(".ytp-chapter-title-content") as HTMLDivElement;
|
||||
chapterTitle.style.display = "none";
|
||||
@@ -878,6 +935,9 @@ class PreviewBar {
|
||||
const elem = document.createElement("div");
|
||||
chapterTitle.parentElement.insertBefore(elem, chapterTitle);
|
||||
elem.classList.add("sponsorChapterText");
|
||||
if (document.location.host === "tv.youtube.com") {
|
||||
elem.style.lineHeight = "initial";
|
||||
}
|
||||
return elem;
|
||||
})()) as HTMLDivElement;
|
||||
chapterCustomText.innerText = chosenSegment.description || shortCategoryName(chosenSegment.category);
|
||||
@@ -890,7 +950,15 @@ class PreviewBar {
|
||||
|
||||
if (chosenSegment.source === SponsorSourceType.Server) {
|
||||
const chapterVoteContainer = this.chapterVote.getContainer();
|
||||
if (!chapterButton.contains(chapterVoteContainer)) {
|
||||
if (document.location.host === "tv.youtube.com") {
|
||||
if (!chaptersContainer.contains(chapterVoteContainer)) {
|
||||
const oldVoteContainers = document.querySelectorAll("#chapterVote");
|
||||
if (oldVoteContainers.length > 0) {
|
||||
oldVoteContainers.forEach((oldVoteContainer) => oldVoteContainer.remove());
|
||||
}
|
||||
chaptersContainer.appendChild(chapterVoteContainer);
|
||||
}
|
||||
} else if (!chapterButton.contains(chapterVoteContainer)) {
|
||||
const oldVoteContainers = document.querySelectorAll("#chapterVote");
|
||||
if (oldVoteContainers.length > 0) {
|
||||
oldVoteContainers.forEach((oldVoteContainer) => oldVoteContainer.remove());
|
||||
@@ -929,6 +997,18 @@ class PreviewBar {
|
||||
}
|
||||
|
||||
private getChaptersContainer(): HTMLElement {
|
||||
if (document.location.host === "tv.youtube.com") {
|
||||
if (!document.querySelector(".ytp-chapter-container")) {
|
||||
const dest = document.querySelector(".ypcs-control-buttons-left");
|
||||
if (!dest) return null;
|
||||
const sbChapterContainer = document.createElement("div");
|
||||
sbChapterContainer.className = "ytp-chapter-container";
|
||||
const sbChapterTitleContent = document.createElement("div");
|
||||
sbChapterTitleContent.className = "ytp-chapter-title-content";
|
||||
sbChapterContainer.appendChild(sbChapterTitleContent);
|
||||
dest.appendChild(sbChapterContainer);
|
||||
}
|
||||
}
|
||||
return document.querySelector(".ytp-chapter-container") as HTMLElement;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ export interface SkipButtonControlBarProps {
|
||||
skip: (segment: SponsorTime) => void;
|
||||
selectSegment: (UUID: SegmentUUID) => void;
|
||||
onMobileYouTube: boolean;
|
||||
onYTTV: boolean;
|
||||
}
|
||||
|
||||
export class SkipButtonControlBar {
|
||||
@@ -21,6 +22,7 @@ export class SkipButtonControlBar {
|
||||
|
||||
showKeybindHint = true;
|
||||
onMobileYouTube: boolean;
|
||||
onYTTV: boolean;
|
||||
|
||||
enabled = false;
|
||||
|
||||
@@ -40,6 +42,7 @@ export class SkipButtonControlBar {
|
||||
constructor(props: SkipButtonControlBarProps) {
|
||||
this.skip = props.skip;
|
||||
this.onMobileYouTube = props.onMobileYouTube;
|
||||
this.onYTTV = props.onYTTV;
|
||||
|
||||
this.container = document.createElement("div");
|
||||
this.container.classList.add("skipButtonControlBarContainer");
|
||||
@@ -50,6 +53,10 @@ export class SkipButtonControlBar {
|
||||
this.skipIcon.src = chrome.runtime.getURL("icons/skipIcon.svg");
|
||||
this.skipIcon.classList.add("ytp-button");
|
||||
this.skipIcon.id = "sbSkipIconControlBarImage";
|
||||
if (this.onYTTV) {
|
||||
this.skipIcon.style.width = "24px";
|
||||
this.skipIcon.style.height = "24px";
|
||||
}
|
||||
|
||||
this.textContainer = document.createElement("div");
|
||||
|
||||
@@ -84,7 +91,7 @@ export class SkipButtonControlBar {
|
||||
this.chapterText = document.querySelector(".ytp-chapter-container");
|
||||
|
||||
if (mountingContainer && !mountingContainer.contains(this.container)) {
|
||||
if (this.onMobileYouTube) {
|
||||
if (this.onMobileYouTube || this.onYTTV) {
|
||||
mountingContainer.appendChild(this.container);
|
||||
} else {
|
||||
mountingContainer.insertBefore(this.container, this.chapterText);
|
||||
@@ -101,8 +108,10 @@ export class SkipButtonControlBar {
|
||||
}
|
||||
|
||||
private getMountingContainer(): HTMLElement {
|
||||
if (!this.onMobileYouTube) {
|
||||
if (!this.onMobileYouTube && !this.onYTTV) {
|
||||
return document.querySelector(".ytp-left-controls");
|
||||
} else if (this.onYTTV) {
|
||||
return document.querySelector(".ypcs-control-buttons-left");
|
||||
} else {
|
||||
return document.getElementById("player-container-id");
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@ interface GetVideoIdResponse {
|
||||
|
||||
export interface GetChannelIDResponse {
|
||||
channelID: string;
|
||||
isYTTV: boolean;
|
||||
}
|
||||
|
||||
export interface SponsorStartResponse {
|
||||
|
||||
@@ -930,7 +930,11 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
|
||||
//get the channel url
|
||||
const response = await sendTabMessageAsync({ message: 'getChannelID' }) as GetChannelIDResponse;
|
||||
if (!response.channelID) {
|
||||
alert(chrome.i18n.getMessage("channelDataNotFound") + " https://github.com/ajayyy/SponsorBlock/issues/753");
|
||||
if (response.isYTTV) {
|
||||
alert(chrome.i18n.getMessage("yttvNoChannelWhitelist"));
|
||||
} else {
|
||||
alert(chrome.i18n.getMessage("channelDataNotFound") + " https://github.com/ajayyy/SponsorBlock/issues/753");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@ export class ChapterVote {
|
||||
this.container.id = "chapterVote";
|
||||
this.container.style.height = "100%";
|
||||
|
||||
if (document.location.host === "tv.youtube.com") {
|
||||
this.container.style.lineHeight = "initial";
|
||||
}
|
||||
|
||||
this.root = createRoot(this.container);
|
||||
this.root.render(<ChapterVoteComponent ref={this.ref} vote={vote} />);
|
||||
}
|
||||
|
||||
@@ -249,6 +249,7 @@ export default class Utils {
|
||||
".main-video-section > .video-container", // Cloudtube
|
||||
".shaka-video-container", // Piped
|
||||
"#player-container.ytk-player", // YT Kids
|
||||
"#id-tv-container" // YTTV
|
||||
];
|
||||
|
||||
let referenceNode = findValidElementFromSelector(selectors)
|
||||
|
||||
@@ -13,7 +13,9 @@ export function getControls(): HTMLElement {
|
||||
// Piped shaka player
|
||||
".shaka-bottom-controls",
|
||||
// Vorapis v3
|
||||
".html5-player-chrome"
|
||||
".html5-player-chrome",
|
||||
// tv.youtube.com
|
||||
".ypcs-control-buttons-right"
|
||||
];
|
||||
|
||||
for (const controlsSelector of controlsSelectors) {
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
/**
|
||||
* @jest-environment jsdom
|
||||
*/
|
||||
|
||||
import PreviewBar, { PreviewBarSegment } from "../src/js-components/previewBar";
|
||||
|
||||
describe("createChapterRenderGroups", () => {
|
||||
let previewBar: PreviewBar;
|
||||
beforeEach(() => {
|
||||
previewBar = new PreviewBar(null, null, null, null, null, true);
|
||||
previewBar = new PreviewBar(null, null, null, null, null, null, true);
|
||||
})
|
||||
|
||||
it("Two unrelated times", () => {
|
||||
|
||||
Reference in New Issue
Block a user