mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2024-09-20 04:53:43 +02:00
Show both categories and chapter names in hover text
This commit is contained in:
parent
e4f4a10965
commit
ab1520c560
4 changed files with 93 additions and 33 deletions
|
@ -45,23 +45,44 @@
|
|||
transform: translateY(-1em) !important;
|
||||
}
|
||||
|
||||
.ytp-tooltip.sponsorCategoryTooltipVisible.sponsorTwoTooltips {
|
||||
transform: translateY(-2em) !important;
|
||||
}
|
||||
|
||||
.ytp-big-mode .ytp-tooltip.sponsorCategoryTooltipVisible {
|
||||
transform: translateY(-2em) !important;
|
||||
}
|
||||
|
||||
.ytp-big-mode .ytp-tooltip.sponsorCategoryTooltipVisible.sponsorTwoTooltips {
|
||||
transform: translateY(-4em) !important;
|
||||
}
|
||||
|
||||
#movie_player:not(.ytp-big-mode) .ytp-tooltip.sponsorCategoryTooltipVisible > .ytp-tooltip-text-wrapper {
|
||||
transform: translateY(1em) !important;
|
||||
}
|
||||
|
||||
#movie_player:not(.ytp-big-mode) .ytp-tooltip.sponsorCategoryTooltipVisible.sponsorTwoTooltips > .ytp-tooltip-text-wrapper {
|
||||
transform: translateY(2em) !important;
|
||||
}
|
||||
|
||||
.ytp-big-mode .ytp-tooltip.sponsorCategoryTooltipVisible > .ytp-tooltip-text-wrapper {
|
||||
transform: translateY(0.5em) !important;
|
||||
}
|
||||
|
||||
.ytp-big-mode .ytp-tooltip.sponsorCategoryTooltipVisible.sponsorTwoTooltips > .ytp-tooltip-text-wrapper {
|
||||
transform: translateY(1em) !important;
|
||||
}
|
||||
|
||||
.ytp-big-mode .ytp-tooltip.sponsorCategoryTooltipVisible > .ytp-tooltip-text-wrapper > .ytp-tooltip-text {
|
||||
display: block !important;
|
||||
transform: translateY(1em) !important;
|
||||
}
|
||||
|
||||
.ytp-big-mode .ytp-tooltip.sponsorCategoryTooltipVisible.sponsorTwoTooltips > .ytp-tooltip-text-wrapper > .ytp-tooltip-text {
|
||||
display: block !important;
|
||||
transform: translateY(2em) !important;
|
||||
}
|
||||
|
||||
div:hover > .sponsorBlockChapterBar {
|
||||
z-index: 41 !important;
|
||||
}
|
||||
|
|
|
@ -970,6 +970,7 @@ function updatePreviewBar(): void {
|
|||
previewBarSegments.push({
|
||||
segment: segment.segment as [number, number],
|
||||
category: segment.category,
|
||||
actionType: segment.actionType,
|
||||
unsubmitted: false,
|
||||
showLarger: getCategoryActionType(segment.category) === CategoryActionType.POI,
|
||||
description: segment.description,
|
||||
|
@ -981,6 +982,7 @@ function updatePreviewBar(): void {
|
|||
previewBarSegments.push({
|
||||
segment: segment.segment as [number, number],
|
||||
category: segment.category,
|
||||
actionType: segment.actionType,
|
||||
unsubmitted: true,
|
||||
showLarger: getCategoryActionType(segment.category) === CategoryActionType.POI,
|
||||
description: segment.description,
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/videosegments/videosegments/commits/f1e111bdfe231947800c6efdd
|
|||
import Config from "../config";
|
||||
import { ActionType, Category, CategoryActionType, SegmentContainer, SponsorTime } from "../types";
|
||||
import Utils from "../utils";
|
||||
import { partition } from "../utils/arrayUtils";
|
||||
import { getCategoryActionType } from "../utils/categoryUtils";
|
||||
const utils = new Utils();
|
||||
|
||||
|
@ -17,6 +18,7 @@ const MIN_CHAPTER_SIZE = 0.003;
|
|||
export interface PreviewBarSegment {
|
||||
segment: [number, number];
|
||||
category: Category;
|
||||
actionType: ActionType;
|
||||
unsubmitted: boolean;
|
||||
showLarger: boolean;
|
||||
description: string;
|
||||
|
@ -29,7 +31,8 @@ interface ChapterGroup extends SegmentContainer {
|
|||
class PreviewBar {
|
||||
container: HTMLUListElement;
|
||||
categoryTooltip?: HTMLDivElement;
|
||||
tooltipContainer?: HTMLElement;
|
||||
categoryTooltipContainer?: HTMLElement;
|
||||
chapterTooltip?: HTMLDivElement;
|
||||
|
||||
parent: HTMLElement;
|
||||
onMobileYouTube: boolean;
|
||||
|
@ -64,16 +67,19 @@ class PreviewBar {
|
|||
// Create label placeholder
|
||||
this.categoryTooltip = document.createElement("div");
|
||||
this.categoryTooltip.className = "ytp-tooltip-title sponsorCategoryTooltip";
|
||||
this.chapterTooltip = document.createElement("div");
|
||||
this.chapterTooltip.className = "ytp-tooltip-title sponsorCategoryTooltip";
|
||||
|
||||
const tooltipTextWrapper = document.querySelector(".ytp-tooltip-text-wrapper");
|
||||
if (!tooltipTextWrapper || !tooltipTextWrapper.parentElement) return;
|
||||
|
||||
// Grab the tooltip from the text wrapper as the tooltip doesn't have its classes on init
|
||||
this.tooltipContainer = tooltipTextWrapper.parentElement;
|
||||
this.categoryTooltipContainer = tooltipTextWrapper.parentElement;
|
||||
const titleTooltip = tooltipTextWrapper.querySelector(".ytp-tooltip-title");
|
||||
if (!this.tooltipContainer || !titleTooltip) return;
|
||||
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 (!seekBar) return;
|
||||
|
@ -89,7 +95,7 @@ class PreviewBar {
|
|||
});
|
||||
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
if (!mouseOnSeekBar || !this.categoryTooltip || !this.tooltipContainer) return;
|
||||
if (!mouseOnSeekBar || !this.categoryTooltip || !this.categoryTooltipContainer) return;
|
||||
|
||||
// If the mutation observed is only for our tooltip text, ignore
|
||||
if (mutations.length === 1 && (mutations[0].target as HTMLElement).classList.contains("sponsorCategoryTooltip")) {
|
||||
|
@ -114,37 +120,26 @@ class PreviewBar {
|
|||
if (timeInSeconds === null) return;
|
||||
|
||||
// Find the segment at that location, using the shortest if multiple found
|
||||
let segment: PreviewBarSegment | null = null;
|
||||
let currentSegmentLength = Infinity;
|
||||
const [normalSegments, chapterSegments] = partition(this.segments, (segment) => segment.actionType !== ActionType.Chapter)
|
||||
const normalSegment = this.getSmallestSegment(timeInSeconds, normalSegments);
|
||||
const chapterSegment = this.getSmallestSegment(timeInSeconds, chapterSegments);
|
||||
|
||||
for (const seg of this.segments) {//
|
||||
const segmentLength = seg.segment[1] - seg.segment[0];
|
||||
const minSize = this.getMinimumSize(seg.showLarger);
|
||||
|
||||
const startTime = segmentLength !== 0 ? seg.segment[0] : Math.floor(seg.segment[0]);
|
||||
const endTime = segmentLength > minSize ? seg.segment[1] : Math.ceil(seg.segment[0] + minSize);
|
||||
if (startTime <= timeInSeconds && endTime >= timeInSeconds) {
|
||||
if (segmentLength < currentSegmentLength) {
|
||||
currentSegmentLength = segmentLength;
|
||||
segment = seg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (segment === null && this.tooltipContainer.classList.contains(TOOLTIP_VISIBLE_CLASS)) {
|
||||
this.tooltipContainer.classList.remove(TOOLTIP_VISIBLE_CLASS);
|
||||
} else if (segment !== null) {
|
||||
this.tooltipContainer.classList.add(TOOLTIP_VISIBLE_CLASS);
|
||||
|
||||
const name = segment.description || utils.shortCategoryName(segment.category);
|
||||
if (segment.unsubmitted) {
|
||||
this.categoryTooltip.textContent = chrome.i18n.getMessage("unsubmitted") + " " + name;
|
||||
if (normalSegment === null && chapterSegment === null) {
|
||||
this.categoryTooltipContainer.classList.remove(TOOLTIP_VISIBLE_CLASS);
|
||||
} else {
|
||||
this.categoryTooltipContainer.classList.add(TOOLTIP_VISIBLE_CLASS);
|
||||
if (noYoutubeChapters && normalSegment !== null && chapterSegment !== null) {
|
||||
this.categoryTooltipContainer.classList.add("sponsorTwoTooltips");
|
||||
} else {
|
||||
this.categoryTooltip.textContent = name;
|
||||
this.categoryTooltipContainer.classList.remove("sponsorTwoTooltips");
|
||||
}
|
||||
|
||||
// Use the class if the timestamp text uses it to prevent overlapping
|
||||
this.setTooltipTitle(normalSegment, this.categoryTooltip);
|
||||
this.setTooltipTitle(chapterSegment, this.chapterTooltip);
|
||||
|
||||
// Used to prevent overlapping
|
||||
this.categoryTooltip.classList.toggle("ytp-tooltip-text-no-title", noYoutubeChapters);
|
||||
this.chapterTooltip.classList.toggle("ytp-tooltip-text-no-title", noYoutubeChapters);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -154,6 +149,21 @@ class PreviewBar {
|
|||
});
|
||||
}
|
||||
|
||||
private setTooltipTitle(segment: PreviewBarSegment, tooltip: HTMLElement): void {
|
||||
if (segment) {
|
||||
const name = segment.description || utils.shortCategoryName(segment.category);
|
||||
if (segment.unsubmitted) {
|
||||
tooltip.textContent = chrome.i18n.getMessage("unsubmitted") + " " + name;
|
||||
} else {
|
||||
tooltip.textContent = name;
|
||||
}
|
||||
|
||||
tooltip.style.removeProperty("display");
|
||||
} else {
|
||||
tooltip.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
createElement(parent: HTMLElement): void {
|
||||
this.parent = parent;
|
||||
|
||||
|
@ -495,9 +505,9 @@ class PreviewBar {
|
|||
this.categoryTooltip = undefined;
|
||||
}
|
||||
|
||||
if (this.tooltipContainer) {
|
||||
this.tooltipContainer.classList.remove(TOOLTIP_VISIBLE_CLASS);
|
||||
this.tooltipContainer = undefined;
|
||||
if (this.categoryTooltipContainer) {
|
||||
this.categoryTooltipContainer.classList.remove(TOOLTIP_VISIBLE_CLASS);
|
||||
this.categoryTooltipContainer = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -524,6 +534,27 @@ class PreviewBar {
|
|||
getMinimumSize(showLarger = false): number {
|
||||
return this.videoDuration * (showLarger ? 0.006 : 0.003);
|
||||
}
|
||||
|
||||
private getSmallestSegment(timeInSeconds: number, segments: PreviewBarSegment[]): PreviewBarSegment | null {
|
||||
let segment: PreviewBarSegment | null = null;
|
||||
let currentSegmentLength = Infinity;
|
||||
|
||||
for (const seg of segments) { //
|
||||
const segmentLength = seg.segment[1] - seg.segment[0];
|
||||
const minSize = this.getMinimumSize(seg.showLarger);
|
||||
|
||||
const startTime = segmentLength !== 0 ? seg.segment[0] : Math.floor(seg.segment[0]);
|
||||
const endTime = segmentLength > minSize ? seg.segment[1] : Math.ceil(seg.segment[0] + minSize);
|
||||
if (startTime <= timeInSeconds && endTime >= timeInSeconds) {
|
||||
if (segmentLength < currentSegmentLength) {
|
||||
currentSegmentLength = segmentLength;
|
||||
segment = seg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return segment;
|
||||
}
|
||||
}
|
||||
|
||||
export default PreviewBar;
|
||||
|
|
6
src/utils/arrayUtils.ts
Normal file
6
src/utils/arrayUtils.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
export function partition<T>(array: T[], filter: (element: T) => boolean): [T[], T[]] {
|
||||
const pass = [], fail = [];
|
||||
array.forEach((element) => (filter(element) ? pass : fail).push(element));
|
||||
|
||||
return [pass, fail];
|
||||
}
|
Loading…
Reference in a new issue