mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-08 20:47:11 +03:00
Move some generic functions to a new package
This commit is contained in:
32
package-lock.json
generated
32
package-lock.json
generated
@@ -27,6 +27,7 @@
|
|||||||
],
|
],
|
||||||
"license": "LGPL-3.0-or-later",
|
"license": "LGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@ajayyy/maze-utils": "^1.0.3",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0"
|
"react-dom": "^18.2.0"
|
||||||
},
|
},
|
||||||
@@ -65,6 +66,32 @@
|
|||||||
"node": ">=16"
|
"node": ">=16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@ajayyy/maze-utils": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ajayyy/maze-utils/-/maze-utils-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-sdQyU/2VAmJ9FiyUIdjE8FbO5b5IofN9vK/7lkZiUw91V+NZi7aSG/LSYMqmQ3OuTYRE5PLN9Jyknuo2ZnljjA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://sponsor.ajay.app/donate"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ajayyy-org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/ajayyy"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://paypal.me/ajayyy"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@ampproject/remapping": {
|
"node_modules/@ampproject/remapping": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
|
||||||
@@ -13336,6 +13363,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@ajayyy/maze-utils": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ajayyy/maze-utils/-/maze-utils-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-sdQyU/2VAmJ9FiyUIdjE8FbO5b5IofN9vK/7lkZiUw91V+NZi7aSG/LSYMqmQ3OuTYRE5PLN9Jyknuo2ZnljjA=="
|
||||||
|
},
|
||||||
"@ampproject/remapping": {
|
"@ampproject/remapping": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
"main": "background.js",
|
"main": "background.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0"
|
"react-dom": "^18.2.0",
|
||||||
|
"@ajayyy/maze-utils": "^1.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/chrome": "^0.0.199",
|
"@types/chrome": "^0.0.199",
|
||||||
|
|||||||
@@ -6,10 +6,9 @@ import Utils from "../utils";
|
|||||||
import SubmissionNoticeComponent from "./SubmissionNoticeComponent";
|
import SubmissionNoticeComponent from "./SubmissionNoticeComponent";
|
||||||
import { RectangleTooltip } from "../render/RectangleTooltip";
|
import { RectangleTooltip } from "../render/RectangleTooltip";
|
||||||
import SelectorComponent, { SelectorOption } from "./SelectorComponent";
|
import SelectorComponent, { SelectorOption } from "./SelectorComponent";
|
||||||
import { GenericUtils } from "../utils/genericUtils";
|
|
||||||
import { noRefreshFetchingChaptersAllowed } from "../utils/licenseKey";
|
import { noRefreshFetchingChaptersAllowed } from "../utils/licenseKey";
|
||||||
import { DEFAULT_CATEGORY } from "../utils/categoryUtils";
|
import { DEFAULT_CATEGORY } from "../utils/categoryUtils";
|
||||||
|
import { getFormattedTime, getFormattedTimeToSeconds } from "@ajayyy/maze-utils/lib/formating";
|
||||||
|
|
||||||
const utils = new Utils();
|
const utils = new Utils();
|
||||||
|
|
||||||
@@ -181,9 +180,9 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
|||||||
style={timeDisplayStyle}
|
style={timeDisplayStyle}
|
||||||
className="sponsorTimeDisplay"
|
className="sponsorTimeDisplay"
|
||||||
onClick={this.toggleEditTime.bind(this)}>
|
onClick={this.toggleEditTime.bind(this)}>
|
||||||
{GenericUtils.getFormattedTime(segment[0], true) +
|
{getFormattedTime(segment[0], true) +
|
||||||
((!isNaN(segment[1]) && sponsorTime.actionType !== ActionType.Poi)
|
((!isNaN(segment[1]) && sponsorTime.actionType !== ActionType.Poi)
|
||||||
? " " + chrome.i18n.getMessage("to") + " " + GenericUtils.getFormattedTime(segment[1], true) : "")}
|
? " " + chrome.i18n.getMessage("to") + " " + getFormattedTime(segment[1], true) : "")}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -308,8 +307,8 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
|||||||
const sponsorTimeEdits = this.state.sponsorTimeEdits;
|
const sponsorTimeEdits = this.state.sponsorTimeEdits;
|
||||||
|
|
||||||
// check if change is small engough to show tooltip
|
// check if change is small engough to show tooltip
|
||||||
const before = GenericUtils.getFormattedTimeToSeconds(sponsorTimeEdits[index]);
|
const before = getFormattedTimeToSeconds(sponsorTimeEdits[index]);
|
||||||
const after = GenericUtils.getFormattedTimeToSeconds(targetValue);
|
const after = getFormattedTimeToSeconds(targetValue);
|
||||||
const difference = Math.abs(before - after);
|
const difference = Math.abs(before - after);
|
||||||
if (0 < difference && difference < 0.5) this.showScrollToEditToolTip();
|
if (0 < difference && difference < 0.5) this.showScrollToEditToolTip();
|
||||||
|
|
||||||
@@ -333,7 +332,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
|||||||
}
|
}
|
||||||
|
|
||||||
const sponsorTimeEdits = this.state.sponsorTimeEdits;
|
const sponsorTimeEdits = this.state.sponsorTimeEdits;
|
||||||
let timeAsNumber = GenericUtils.getFormattedTimeToSeconds(this.state.sponsorTimeEdits[index]);
|
let timeAsNumber = getFormattedTimeToSeconds(this.state.sponsorTimeEdits[index]);
|
||||||
if (timeAsNumber !== null && e.deltaY != 0) {
|
if (timeAsNumber !== null && e.deltaY != 0) {
|
||||||
if (e.deltaY < 0) {
|
if (e.deltaY < 0) {
|
||||||
timeAsNumber += step;
|
timeAsNumber += step;
|
||||||
@@ -343,7 +342,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
|||||||
timeAsNumber = 0;
|
timeAsNumber = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sponsorTimeEdits[index] = GenericUtils.getFormattedTime(timeAsNumber, true);
|
sponsorTimeEdits[index] = getFormattedTime(timeAsNumber, true);
|
||||||
if (sponsorTime.actionType === ActionType.Poi) sponsorTimeEdits[1] = sponsorTimeEdits[0];
|
if (sponsorTime.actionType === ActionType.Poi) sponsorTimeEdits[1] = sponsorTimeEdits[0];
|
||||||
|
|
||||||
this.setState({sponsorTimeEdits});
|
this.setState({sponsorTimeEdits});
|
||||||
@@ -575,8 +574,8 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
|||||||
|
|
||||||
/** Returns an array in the sponsorTimeEdits form (formatted time string) from a normal seconds sponsor time */
|
/** Returns an array in the sponsorTimeEdits form (formatted time string) from a normal seconds sponsor time */
|
||||||
getFormattedSponsorTimesEdits(sponsorTime: SponsorTime): [string, string] {
|
getFormattedSponsorTimesEdits(sponsorTime: SponsorTime): [string, string] {
|
||||||
return [GenericUtils.getFormattedTime(sponsorTime.segment[0], true),
|
return [getFormattedTime(sponsorTime.segment[0], true),
|
||||||
GenericUtils.getFormattedTime(sponsorTime.segment[1], true)];
|
getFormattedTime(sponsorTime.segment[1], true)];
|
||||||
}
|
}
|
||||||
|
|
||||||
saveEditTimes(): void {
|
saveEditTimes(): void {
|
||||||
@@ -584,8 +583,8 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
|||||||
const category = this.categoryOptionRef.current.value as Category
|
const category = this.categoryOptionRef.current.value as Category
|
||||||
|
|
||||||
if (this.state.editing) {
|
if (this.state.editing) {
|
||||||
const startTime = GenericUtils.getFormattedTimeToSeconds(this.state.sponsorTimeEdits[0]);
|
const startTime = getFormattedTimeToSeconds(this.state.sponsorTimeEdits[0]);
|
||||||
const endTime = GenericUtils.getFormattedTimeToSeconds(this.state.sponsorTimeEdits[1]);
|
const endTime = getFormattedTimeToSeconds(this.state.sponsorTimeEdits[1]);
|
||||||
|
|
||||||
// Change segment time only if the format was correct
|
// Change segment time only if the format was correct
|
||||||
if (startTime !== null && endTime !== null) {
|
if (startTime !== null && endTime !== null) {
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ import { ChapterVote } from "./render/ChapterVote";
|
|||||||
import { openWarningDialog } from "./utils/warnings";
|
import { openWarningDialog } from "./utils/warnings";
|
||||||
import { Tooltip } from "./render/Tooltip";
|
import { Tooltip } from "./render/Tooltip";
|
||||||
import { noRefreshFetchingChaptersAllowed } from "./utils/licenseKey";
|
import { noRefreshFetchingChaptersAllowed } from "./utils/licenseKey";
|
||||||
|
import { waitFor } from "@ajayyy/maze-utils";
|
||||||
|
import { getFormattedTime } from "@ajayyy/maze-utils/lib/formating";
|
||||||
|
|
||||||
const utils = new Utils();
|
const utils = new Utils();
|
||||||
|
|
||||||
@@ -1203,7 +1205,7 @@ async function sponsorsLookup(keepOldSubmissions = true) {
|
|||||||
|
|
||||||
function importExistingChapters(wait: boolean) {
|
function importExistingChapters(wait: boolean) {
|
||||||
if (!existingChaptersImported) {
|
if (!existingChaptersImported) {
|
||||||
GenericUtils.wait(() => video?.duration && getExistingChapters(sponsorVideoID, video.duration),
|
waitFor(() => video?.duration && getExistingChapters(sponsorVideoID, video.duration),
|
||||||
wait ? 5000 : 0, 100, (c) => c?.length > 0).then((chapters) => {
|
wait ? 5000 : 0, 100, (c) => c?.length > 0).then((chapters) => {
|
||||||
if (!existingChaptersImported && chapters?.length > 0) {
|
if (!existingChaptersImported && chapters?.length > 0) {
|
||||||
sponsorTimes = (sponsorTimes ?? []).concat(...chapters).sort((a, b) => a.segment[0] - b.segment[0]);
|
sponsorTimes = (sponsorTimes ?? []).concat(...chapters).sort((a, b) => a.segment[0] - b.segment[0]);
|
||||||
@@ -2364,7 +2366,7 @@ function getSegmentsMessage(sponsorTimes: SponsorTime[]): string {
|
|||||||
|
|
||||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||||
for (let s = 0; s < sponsorTimes[i].segment.length; s++) {
|
for (let s = 0; s < sponsorTimes[i].segment.length; s++) {
|
||||||
let timeMessage = GenericUtils.getFormattedTime(sponsorTimes[i].segment[s]);
|
let timeMessage = getFormattedTime(sponsorTimes[i].segment[s]);
|
||||||
//if this is an end time
|
//if this is an end time
|
||||||
if (s == 1) {
|
if (s == 1) {
|
||||||
timeMessage = " " + chrome.i18n.getMessage("to") + " " + timeMessage;
|
timeMessage = " " + chrome.i18n.getMessage("to") + " " + timeMessage;
|
||||||
@@ -2592,7 +2594,7 @@ function showTimeWithoutSkips(skippedDuration: number): void {
|
|||||||
display.appendChild(duration);
|
display.appendChild(duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
const durationAfterSkips = GenericUtils.getFormattedTime(video?.duration - skippedDuration);
|
const durationAfterSkips = getFormattedTime(video?.duration - skippedDuration);
|
||||||
|
|
||||||
duration.innerText = (durationAfterSkips == null || skippedDuration <= 0) ? "" : " (" + durationAfterSkips + ")";
|
duration.innerText = (durationAfterSkips == null || skippedDuration <= 0) ? "" : " (" + durationAfterSkips + ")";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ import Config from "./config";
|
|||||||
import { showDonationLink } from "./utils/configUtils";
|
import { showDonationLink } from "./utils/configUtils";
|
||||||
|
|
||||||
import { localizeHtmlPage } from "./utils/pageUtils";
|
import { localizeHtmlPage } from "./utils/pageUtils";
|
||||||
import { GenericUtils } from "./utils/genericUtils";
|
import { waitFor } from "@ajayyy/maze-utils";
|
||||||
|
|
||||||
window.addEventListener('DOMContentLoaded', init);
|
window.addEventListener('DOMContentLoaded', init);
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
localizeHtmlPage();
|
localizeHtmlPage();
|
||||||
|
|
||||||
await GenericUtils.wait(() => Config.config !== null);
|
await waitFor(() => Config.config !== null);
|
||||||
|
|
||||||
if (!Config.config.darkMode) {
|
if (!Config.config.darkMode) {
|
||||||
document.documentElement.setAttribute("data-theme", "light");
|
document.documentElement.setAttribute("data-theme", "light");
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import { ActionType, Category, SegmentContainer, SponsorHideType, SponsorSourceT
|
|||||||
import { partition } from "../utils/arrayUtils";
|
import { partition } from "../utils/arrayUtils";
|
||||||
import { DEFAULT_CATEGORY, shortCategoryName } from "../utils/categoryUtils";
|
import { DEFAULT_CATEGORY, shortCategoryName } from "../utils/categoryUtils";
|
||||||
import { normalizeChapterName } from "../utils/exporter";
|
import { normalizeChapterName } from "../utils/exporter";
|
||||||
import { GenericUtils } from "../utils/genericUtils";
|
|
||||||
import { findValidElement } from "../utils/pageUtils";
|
import { findValidElement } from "../utils/pageUtils";
|
||||||
|
import { getFormattedTimeToSeconds } from "@ajayyy/maze-utils/lib/formating";
|
||||||
|
|
||||||
const TOOLTIP_VISIBLE_CLASS = 'sponsorCategoryTooltipVisible';
|
const TOOLTIP_VISIBLE_CLASS = 'sponsorCategoryTooltipVisible';
|
||||||
const MIN_CHAPTER_SIZE = 0.003;
|
const MIN_CHAPTER_SIZE = 0.003;
|
||||||
@@ -140,7 +140,7 @@ class PreviewBar {
|
|||||||
const tooltipText = tooltipTextElement.textContent;
|
const tooltipText = tooltipTextElement.textContent;
|
||||||
if (tooltipText === null || tooltipText.length === 0) continue;
|
if (tooltipText === null || tooltipText.length === 0) continue;
|
||||||
|
|
||||||
timeInSeconds = GenericUtils.getFormattedTimeToSeconds(tooltipText);
|
timeInSeconds = getFormattedTimeToSeconds(tooltipText);
|
||||||
|
|
||||||
if (timeInSeconds !== null) break;
|
if (timeInSeconds !== null) break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import { localizeHtmlPage } from "./utils/pageUtils";
|
|||||||
import { exportTimes } from "./utils/exporter";
|
import { exportTimes } from "./utils/exporter";
|
||||||
import GenericNotice from "./render/GenericNotice";
|
import GenericNotice from "./render/GenericNotice";
|
||||||
import { noRefreshFetchingChaptersAllowed } from "./utils/licenseKey";
|
import { noRefreshFetchingChaptersAllowed } from "./utils/licenseKey";
|
||||||
|
import { getFormattedTime } from "@ajayyy/maze-utils/lib/formating";
|
||||||
|
|
||||||
const utils = new Utils();
|
const utils = new Utils();
|
||||||
|
|
||||||
@@ -593,9 +594,9 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
|
|||||||
if (downloadedTimes[i].actionType === ActionType.Full) {
|
if (downloadedTimes[i].actionType === ActionType.Full) {
|
||||||
segmentTimeFromToNode.innerText = chrome.i18n.getMessage("full");
|
segmentTimeFromToNode.innerText = chrome.i18n.getMessage("full");
|
||||||
} else {
|
} else {
|
||||||
segmentTimeFromToNode.innerText = GenericUtils.getFormattedTime(downloadedTimes[i].segment[0], true) +
|
segmentTimeFromToNode.innerText = getFormattedTime(downloadedTimes[i].segment[0], true) +
|
||||||
(actionType !== ActionType.Poi
|
(actionType !== ActionType.Poi
|
||||||
? " " + chrome.i18n.getMessage("to") + " " + GenericUtils.getFormattedTime(downloadedTimes[i].segment[1], true)
|
? " " + chrome.i18n.getMessage("to") + " " + getFormattedTime(downloadedTimes[i].segment[1], true)
|
||||||
: "");
|
: "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,9 @@ import CategoryPillComponent, { CategoryPillState } from "../components/Category
|
|||||||
import Config from "../config";
|
import Config from "../config";
|
||||||
import { VoteResponse } from "../messageTypes";
|
import { VoteResponse } from "../messageTypes";
|
||||||
import { Category, SegmentUUID, SponsorTime } from "../types";
|
import { Category, SegmentUUID, SponsorTime } from "../types";
|
||||||
import { GenericUtils } from "../utils/genericUtils";
|
|
||||||
import { Tooltip } from "./Tooltip";
|
import { Tooltip } from "./Tooltip";
|
||||||
|
import { waitFor } from "@ajayyy/maze-utils";
|
||||||
|
import { getYouTubeTitleNode } from "@ajayyy/maze-utils/lib/elements";
|
||||||
|
|
||||||
export class CategoryPill {
|
export class CategoryPill {
|
||||||
container: HTMLElement;
|
container: HTMLElement;
|
||||||
@@ -23,9 +24,7 @@ export class CategoryPill {
|
|||||||
async attachToPage(onMobileYouTube: boolean, onInvidious: boolean,
|
async attachToPage(onMobileYouTube: boolean, onInvidious: boolean,
|
||||||
vote: (type: number, UUID: SegmentUUID, category?: Category) => Promise<VoteResponse>): Promise<void> {
|
vote: (type: number, UUID: SegmentUUID, category?: Category) => Promise<VoteResponse>): Promise<void> {
|
||||||
const referenceNode =
|
const referenceNode =
|
||||||
await GenericUtils.wait(() =>
|
await waitFor(() => getYouTubeTitleNode());
|
||||||
// New YouTube Title, YouTube, Mobile YouTube, Invidious
|
|
||||||
document.querySelector("#title h1, .ytd-video-primary-info-renderer.title, .slim-video-information-title, #player-container + .h-box > h1") as HTMLElement);
|
|
||||||
|
|
||||||
if (referenceNode && !referenceNode.contains(this.container)) {
|
if (referenceNode && !referenceNode.contains(this.container)) {
|
||||||
this.container = document.createElement('span');
|
this.container = document.createElement('span');
|
||||||
@@ -43,7 +42,7 @@ export class CategoryPill {
|
|||||||
this.root.render(<CategoryPillComponent ref={this.ref} vote={vote} />);
|
this.root.render(<CategoryPillComponent ref={this.ref} vote={vote} />);
|
||||||
|
|
||||||
if (this.unsavedState) {
|
if (this.unsavedState) {
|
||||||
GenericUtils.wait(() => this.ref.current).then(() => {
|
waitFor(() => this.ref.current).then(() => {
|
||||||
this.ref.current?.setState(this.unsavedState);
|
this.ref.current?.setState(this.unsavedState);
|
||||||
this.unsavedState = null;
|
this.unsavedState = null;
|
||||||
});
|
});
|
||||||
@@ -99,7 +98,7 @@ export class CategoryPill {
|
|||||||
if (!Config.config.categoryPillUpdate) {
|
if (!Config.config.categoryPillUpdate) {
|
||||||
Config.config.categoryPillUpdate = true;
|
Config.config.categoryPillUpdate = true;
|
||||||
|
|
||||||
const watchDiv = await GenericUtils.wait(() => document.querySelector("#info.ytd-watch-flexy") as HTMLElement);
|
const watchDiv = await waitFor(() => document.querySelector("#info.ytd-watch-flexy") as HTMLElement);
|
||||||
if (watchDiv) {
|
if (watchDiv) {
|
||||||
new Tooltip({
|
new Tooltip({
|
||||||
text: chrome.i18n.getMessage("categoryPillNewFeature"),
|
text: chrome.i18n.getMessage("categoryPillNewFeature"),
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { CategorySelection, SponsorTime, FetchResponse, BackgroundScriptContaine
|
|||||||
|
|
||||||
import * as CompileConfig from "../config.json";
|
import * as CompileConfig from "../config.json";
|
||||||
import { findValidElement, findValidElementFromSelector } from "./utils/pageUtils";
|
import { findValidElement, findValidElementFromSelector } from "./utils/pageUtils";
|
||||||
import { GenericUtils } from "./utils/genericUtils";
|
import { waitFor } from "@ajayyy/maze-utils";
|
||||||
|
|
||||||
export default class Utils {
|
export default class Utils {
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ export default class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async wait<T>(condition: () => T, timeout = 5000, check = 100): Promise<T> {
|
async wait<T>(condition: () => T, timeout = 5000, check = 100): Promise<T> {
|
||||||
return GenericUtils.wait(condition, timeout, check);
|
return waitFor(condition, timeout, check);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Uses a mutation observer to wait asynchronously */
|
/* Uses a mutation observer to wait asynchronously */
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { ActionType, Category, SegmentUUID, SponsorSourceType, SponsorTime } fro
|
|||||||
import { shortCategoryName } from "./categoryUtils";
|
import { shortCategoryName } from "./categoryUtils";
|
||||||
import { GenericUtils } from "./genericUtils";
|
import { GenericUtils } from "./genericUtils";
|
||||||
import * as CompileConfig from "../../config.json";
|
import * as CompileConfig from "../../config.json";
|
||||||
|
import { getFormattedTime, getFormattedTimeToSeconds } from "@ajayyy/maze-utils/lib/formating";
|
||||||
|
|
||||||
const inTest = typeof chrome === "undefined";
|
const inTest = typeof chrome === "undefined";
|
||||||
|
|
||||||
@@ -26,9 +27,9 @@ export function exportTimes(segments: SponsorTime[]): string {
|
|||||||
function exportTime(segment: SponsorTime): string {
|
function exportTime(segment: SponsorTime): string {
|
||||||
const name = segment.description || shortCategoryName(segment.category);
|
const name = segment.description || shortCategoryName(segment.category);
|
||||||
|
|
||||||
return `${GenericUtils.getFormattedTime(segment.segment[0], true)}${
|
return `${getFormattedTime(segment.segment[0], true)}${
|
||||||
segment.segment[1] && segment.segment[0] !== segment.segment[1]
|
segment.segment[1] && segment.segment[0] !== segment.segment[1]
|
||||||
? ` - ${GenericUtils.getFormattedTime(segment.segment[1], true)}` : ""} ${name}`;
|
? ` - ${getFormattedTime(segment.segment[1], true)}` : ""} ${name}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function importTimes(data: string, videoDuration: number): SponsorTime[] {
|
export function importTimes(data: string, videoDuration: number): SponsorTime[] {
|
||||||
@@ -37,7 +38,7 @@ export function importTimes(data: string, videoDuration: number): SponsorTime[]
|
|||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
const match = line.match(/(?:((?:\d+:)?\d+:\d+)+(?:\.\d+)?)|(?:\d+(?=s| second))/g);
|
const match = line.match(/(?:((?:\d+:)?\d+:\d+)+(?:\.\d+)?)|(?:\d+(?=s| second))/g);
|
||||||
if (match) {
|
if (match) {
|
||||||
const startTime = GenericUtils.getFormattedTimeToSeconds(match[0]);
|
const startTime = getFormattedTimeToSeconds(match[0]);
|
||||||
if (startTime !== null) {
|
if (startTime !== null) {
|
||||||
// Remove "seconds", "at", special characters, and ")" if there was a "("
|
// Remove "seconds", "at", special characters, and ")" if there was a "("
|
||||||
const specialCharsMatcher = /^(?:\s+seconds?)?[-:()\s]*|(?:\s+at)?[-:(\s]+$|(?<=^\s*\(.+)[-:()\s]*$/g
|
const specialCharsMatcher = /^(?:\s+seconds?)?[-:()\s]*|(?:\s+at)?[-:(\s]+$|(?<=^\s*\(.+)[-:()\s]*$/g
|
||||||
@@ -51,7 +52,7 @@ export function importTimes(data: string, videoDuration: number): SponsorTime[]
|
|||||||
const determinedCategory = chapterNames.find(c => c.names.includes(title))?.code as Category;
|
const determinedCategory = chapterNames.find(c => c.names.includes(title))?.code as Category;
|
||||||
|
|
||||||
const segment: SponsorTime = {
|
const segment: SponsorTime = {
|
||||||
segment: [startTime, GenericUtils.getFormattedTimeToSeconds(match[1])],
|
segment: [startTime, getFormattedTimeToSeconds(match[1])],
|
||||||
category: determinedCategory ?? ("chapter" as Category),
|
category: determinedCategory ?? ("chapter" as Category),
|
||||||
actionType: determinedCategory ? ActionType.Skip : ActionType.Chapter,
|
actionType: determinedCategory ? ActionType.Skip : ActionType.Chapter,
|
||||||
description: title,
|
description: title,
|
||||||
|
|||||||
@@ -1,70 +1,3 @@
|
|||||||
/** Function that can be used to wait for a condition before returning. */
|
|
||||||
async function wait<T>(condition: () => T, timeout = 5000, check = 100, predicate?: (obj: T) => boolean): Promise<T> {
|
|
||||||
return await new Promise((resolve, reject) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
clearInterval(interval);
|
|
||||||
reject("TIMEOUT");
|
|
||||||
}, timeout);
|
|
||||||
|
|
||||||
const intervalCheck = () => {
|
|
||||||
const result = condition();
|
|
||||||
if (predicate ? predicate(result) : result) {
|
|
||||||
resolve(result);
|
|
||||||
clearInterval(interval);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const interval = setInterval(intervalCheck, check);
|
|
||||||
|
|
||||||
//run the check once first, this speeds it up a lot
|
|
||||||
intervalCheck();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFormattedTimeToSeconds(formatted: string): number | null {
|
|
||||||
const fragments = /^(?:(?:(\d+):)?(\d+):)?(\d*(?:[.,]\d+)?)$/.exec(formatted);
|
|
||||||
|
|
||||||
if (fragments === null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const hours = fragments[1] ? parseInt(fragments[1]) : 0;
|
|
||||||
const minutes = fragments[2] ? parseInt(fragments[2] || '0') : 0;
|
|
||||||
const seconds = fragments[3] ? parseFloat(fragments[3].replace(',', '.')) : 0;
|
|
||||||
|
|
||||||
return hours * 3600 + minutes * 60 + seconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFormattedTime(seconds: number, precise?: boolean): string {
|
|
||||||
seconds = Math.max(seconds, 0);
|
|
||||||
|
|
||||||
const hours = Math.floor(seconds / 60 / 60);
|
|
||||||
const minutes = Math.floor(seconds / 60) % 60;
|
|
||||||
let minutesDisplay = String(minutes);
|
|
||||||
let secondsNum = seconds % 60;
|
|
||||||
if (!precise) {
|
|
||||||
secondsNum = Math.floor(secondsNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
let secondsDisplay = String(precise ? secondsNum.toFixed(3) : secondsNum);
|
|
||||||
|
|
||||||
if (secondsNum < 10) {
|
|
||||||
//add a zero
|
|
||||||
secondsDisplay = "0" + secondsDisplay;
|
|
||||||
}
|
|
||||||
if (hours && minutes < 10) {
|
|
||||||
//add a zero
|
|
||||||
minutesDisplay = "0" + minutesDisplay;
|
|
||||||
}
|
|
||||||
if (isNaN(hours) || isNaN(minutes)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const formatted = (hours ? hours + ":" : "") + minutesDisplay + ":" + secondsDisplay;
|
|
||||||
|
|
||||||
return formatted;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the error message in a nice string
|
* Gets the error message in a nice string
|
||||||
*
|
*
|
||||||
@@ -148,9 +81,6 @@ function generateUserID(length = 36): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const GenericUtils = {
|
export const GenericUtils = {
|
||||||
wait,
|
|
||||||
getFormattedTime,
|
|
||||||
getFormattedTimeToSeconds,
|
|
||||||
getErrorMessage,
|
getErrorMessage,
|
||||||
getLuminance,
|
getLuminance,
|
||||||
generateUserID,
|
generateUserID,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ActionType, Category, SponsorSourceType, SponsorTime, VideoID } from "../types";
|
import { ActionType, Category, SponsorSourceType, SponsorTime, VideoID } from "../types";
|
||||||
import { GenericUtils } from "./genericUtils";
|
import { getFormattedTimeToSeconds } from "@ajayyy/maze-utils/lib/formating";
|
||||||
|
|
||||||
export function getControls(): HTMLElement {
|
export function getControls(): HTMLElement {
|
||||||
const controlsSelectors = [
|
const controlsSelectors = [
|
||||||
@@ -80,7 +80,7 @@ export function getExistingChapters(currentVideoID: VideoID, duration: number):
|
|||||||
const timeElement = link.querySelector("#time") as HTMLElement;
|
const timeElement = link.querySelector("#time") as HTMLElement;
|
||||||
const description = link.querySelector("#details h4") as HTMLElement;
|
const description = link.querySelector("#details h4") as HTMLElement;
|
||||||
if (timeElement && description?.innerText?.length > 0 && link.getAttribute("href")?.includes(currentVideoID)) {
|
if (timeElement && description?.innerText?.length > 0 && link.getAttribute("href")?.includes(currentVideoID)) {
|
||||||
const time = GenericUtils.getFormattedTimeToSeconds(timeElement.innerText);
|
const time = getFormattedTimeToSeconds(timeElement.innerText);
|
||||||
if (time === null) return [];
|
if (time === null) return [];
|
||||||
|
|
||||||
if (lastSegment) {
|
if (lastSegment) {
|
||||||
|
|||||||
Reference in New Issue
Block a user