aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorAjay <[email protected]>2024-01-21 20:35:00 -0500
committerAjay <[email protected]>2024-01-21 20:35:00 -0500
commit1f96e3b1174b27cc75c7bdd79e5f1c9116e9b108 (patch)
tree7ee2a1573b23a430fdcaf04022a6bfc17eeeba53 /src
parentb3b5d46e4eb34fd087f9bf4f674e7f83a4ba4061 (diff)
downloadSponsorBlock-1f96e3b1174b27cc75c7bdd79e5f1c9116e9b108.tar.gz
SponsorBlock-1f96e3b1174b27cc75c7bdd79e5f1c9116e9b108.zip
Improve precision of hover preview
Also fixes issue with YouTube "most-replayed" messing it up
Diffstat (limited to 'src')
-rw-r--r--src/js-components/previewBar.ts72
1 files changed, 30 insertions, 42 deletions
diff --git a/src/js-components/previewBar.ts b/src/js-components/previewBar.ts
index a2522f08..ff498a28 100644
--- a/src/js-components/previewBar.ts
+++ b/src/js-components/previewBar.ts
@@ -11,7 +11,6 @@ import { ActionType, Category, SegmentContainer, SponsorHideType, SponsorSourceT
import { partition } from "../utils/arrayUtils";
import { DEFAULT_CATEGORY, shortCategoryName } from "../utils/categoryUtils";
import { normalizeChapterName } from "../utils/exporter";
-import { getFormattedTimeToSeconds } from "../../maze-utils/src/formating";
import { findValidElement } from "../../maze-utils/src/dom";
import { addCleanupListener } from "../../maze-utils/src/cleanup";
@@ -125,34 +124,11 @@ class PreviewBar {
mouseOnSeekBar = false;
});
- const observer = new MutationObserver((mutations) => {
+ seekBar.addEventListener("mousemove", (e: MouseEvent) => {
if (!mouseOnSeekBar || !this.categoryTooltip || !this.categoryTooltipContainer) return;
- // Only care about mutations to time tooltip
- if (!mutations.some((mutation) => (mutation.target as HTMLElement).classList.contains("ytp-tooltip-text"))) {
- return;
- }
-
- const tooltipTextElements = tooltipTextWrapper.querySelectorAll(".ytp-tooltip-text");
- let timeInSeconds: number | null = null;
- let noYoutubeChapters = false;
-
- for (const tooltipTextElement of tooltipTextElements) {
- if (tooltipTextElement.classList.contains('ytp-tooltip-text-no-title')) noYoutubeChapters = true;
-
- const tooltipText = tooltipTextElement.textContent;
- if (tooltipText === null || tooltipText.length === 0) continue;
-
- timeInSeconds = getFormattedTimeToSeconds(tooltipText);
-
- if (timeInSeconds !== null) break;
- }
-
- if (timeInSeconds === null) {
- originalTooltip.style.removeProperty("display");
-
- return;
- }
+ let noYoutubeChapters = !!tooltipTextWrapper.querySelector(".ytp-tooltip-text.ytp-tooltip-text-no-title");
+ const timeInSeconds = this.decimalToTime((e.clientX - seekBar.getBoundingClientRect().x) / seekBar.clientWidth);
// Find the segment at that location, using the shortest if multiple found
const [normalSegments, chapterSegments] =
@@ -198,15 +174,6 @@ class PreviewBar {
this.chapterTooltip.style.textAlign = titleTooltip.style.textAlign;
}
});
-
- observer.observe(tooltipTextWrapper, {
- childList: true,
- subtree: true,
- });
-
- addCleanupListener(() => {
- observer.disconnect();
- });
}
private setTooltipTitle(segment: PreviewBarSegment, tooltip: HTMLElement): void {
@@ -920,6 +887,17 @@ class PreviewBar {
}
timeToDecimal(time: number): number {
+ return this.decimalTimeConverter(time, true);
+ }
+
+ decimalToTime(decimal: number): number {
+ return this.decimalTimeConverter(decimal, false);
+ }
+
+ /**
+ * Decimal to time or time to decimal
+ */
+ decimalTimeConverter(value: number, isTime: boolean): number {
if (this.originalChapterBarBlocks?.length > 1 && this.existingChapters.length === this.originalChapterBarBlocks?.length) {
// Parent element to still work when display: none
const totalPixels = this.originalChapterBar.parentElement.clientWidth;
@@ -929,8 +907,9 @@ class PreviewBar {
const chapterElement = this.originalChapterBarBlocks[i];
const widthPixels = parseFloat(chapterElement.style.width.replace("px", ""));
- if (time >= this.existingChapters[i].segment[1]) {
- const marginPixels = chapterElement.style.marginRight ? parseFloat(chapterElement.style.marginRight.replace("px", "")) : 0;
+ const marginPixels = chapterElement.style.marginRight ? parseFloat(chapterElement.style.marginRight.replace("px", "")) : 0;
+ if ((isTime && value >= this.existingChapters[i].segment[1])
+ || (!isTime && value >= (pixelOffset + widthPixels + marginPixels) / totalPixels)) {
pixelOffset += widthPixels + marginPixels;
lastCheckedChapter = i;
} else {
@@ -944,13 +923,22 @@ class PreviewBar {
const latestWidth = parseFloat(this.originalChapterBarBlocks[lastCheckedChapter + 1].style.width.replace("px", ""));
const latestChapterDuration = latestChapter.segment[1] - latestChapter.segment[0];
- const percentageInCurrentChapter = (time - latestChapter.segment[0]) / latestChapterDuration;
- const sizeOfCurrentChapter = latestWidth / totalPixels;
- return Math.min(1, ((pixelOffset / totalPixels) + (percentageInCurrentChapter * sizeOfCurrentChapter)));
+ if (isTime) {
+ const percentageInCurrentChapter = (value - latestChapter.segment[0]) / latestChapterDuration;
+ const sizeOfCurrentChapter = latestWidth / totalPixels;
+ return Math.min(1, ((pixelOffset / totalPixels) + (percentageInCurrentChapter * sizeOfCurrentChapter)));
+ } else {
+ const percentageInCurrentChapter = (value * totalPixels - pixelOffset) / latestWidth;
+ return Math.max(0, latestChapter.segment[0] + (percentageInCurrentChapter * latestChapterDuration));
+ }
}
}
- return Math.min(1, time / this.videoDuration);
+ if (isTime) {
+ return Math.min(1, value / this.videoDuration);
+ } else {
+ return Math.max(0, value * this.videoDuration);
+ }
}
/*