|
@@ -17,7 +17,7 @@
|
|
|
// @license AGPL-3.0-only
|
|
|
// @author Sv443
|
|
|
// @copyright Sv443 (https://github.com/Sv443)
|
|
|
-// @icon https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/images/logo/logo_dev_48.png
|
|
|
+// @icon http://localhost:8710/assets/images/logo/logo_dev_48.png?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
// @match https://music.youtube.com/*
|
|
|
// @match https://www.youtube.com/*
|
|
|
// @run-at document-start
|
|
@@ -33,52 +33,52 @@
|
|
|
// @grant GM.openInTab
|
|
|
// @grant unsafeWindow
|
|
|
// @noframes
|
|
|
-// @resource css-above_queue_btns https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/style/aboveQueueBtns.css
|
|
|
-// @resource css-anchor_improvements https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/style/anchorImprovements.css
|
|
|
-// @resource css-auto_like https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/style/autoLike.css
|
|
|
-// @resource css-bundle https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/dist/BetterYTM.css
|
|
|
-// @resource css-fix_hdr https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/style/fixHDR.css
|
|
|
-// @resource css-fix_spacing https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/style/fixSpacing.css
|
|
|
-// @resource css-show_votes https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/style/showVotes.css
|
|
|
-// @resource css-vol_slider_size https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/style/volSliderSize.css
|
|
|
-// @resource doc-changelog https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/changelog.md
|
|
|
-// @resource icon-advanced_mode https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/plus_circle_small.svg
|
|
|
-// @resource icon-arrow_down https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/arrow_down.svg
|
|
|
-// @resource icon-auto_like https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/auto_like.svg
|
|
|
-// @resource icon-auto_like_enabled https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/auto_like_enabled.svg
|
|
|
-// @resource icon-clear_list https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/clear_list.svg
|
|
|
-// @resource icon-copy https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/copy.svg
|
|
|
-// @resource icon-delete https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/delete.svg
|
|
|
-// @resource icon-edit https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/edit.svg
|
|
|
-// @resource icon-error https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/error.svg
|
|
|
-// @resource icon-experimental https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/beaker_small.svg
|
|
|
-// @resource icon-globe https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/globe.svg
|
|
|
-// @resource icon-globe_small https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/globe_small.svg
|
|
|
-// @resource icon-help https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/help.svg
|
|
|
-// @resource icon-image https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/image.svg
|
|
|
-// @resource icon-image_filled https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/image_filled.svg
|
|
|
-// @resource icon-link https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/link.svg
|
|
|
-// @resource icon-lyrics https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/lyrics.svg
|
|
|
-// @resource icon-reload https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/refresh.svg
|
|
|
-// @resource icon-skip_to https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/skip_to.svg
|
|
|
-// @resource icon-spinner https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/spinner.svg
|
|
|
-// @resource icon-upload https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/icons/upload.svg
|
|
|
-// @resource img-close https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/images/close.png
|
|
|
-// @resource img-discord https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/images/external/discord.png
|
|
|
-// @resource img-github https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/images/external/github.png
|
|
|
-// @resource img-greasyfork https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/images/external/greasyfork.png
|
|
|
-// @resource img-logo https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/images/logo/logo_48.png
|
|
|
-// @resource img-logo_dev https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/images/logo/logo_dev_48.png
|
|
|
-// @resource img-openuserjs https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/images/external/openuserjs.png
|
|
|
-// @resource trans-de_DE https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/translations/de_DE.json
|
|
|
-// @resource trans-en_UK https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/translations/en_UK.json
|
|
|
-// @resource trans-en_US https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/translations/en_US.json
|
|
|
-// @resource trans-es_ES https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/translations/es_ES.json
|
|
|
-// @resource trans-fr_FR https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/translations/fr_FR.json
|
|
|
-// @resource trans-hi_IN https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/translations/hi_IN.json
|
|
|
-// @resource trans-ja_JA https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/translations/ja_JA.json
|
|
|
-// @resource trans-pt_BR https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/translations/pt_BR.json
|
|
|
-// @resource trans-zh_CN https://raw.githubusercontent.com/Sv443/BetterYTM/d1ceac6a/assets/translations/zh_CN.json
|
|
|
+// @resource css-above_queue_btns http://localhost:8710/assets/style/aboveQueueBtns.css?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource css-anchor_improvements http://localhost:8710/assets/style/anchorImprovements.css?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource css-auto_like http://localhost:8710/assets/style/autoLike.css?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource css-bundle http://localhost:8710/dist/BetterYTM.css?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource css-fix_hdr http://localhost:8710/assets/style/fixHDR.css?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource css-fix_spacing http://localhost:8710/assets/style/fixSpacing.css?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource css-show_votes http://localhost:8710/assets/style/showVotes.css?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource css-vol_slider_size http://localhost:8710/assets/style/volSliderSize.css?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource doc-changelog http://localhost:8710/changelog.md?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-advanced_mode http://localhost:8710/assets/icons/plus_circle_small.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-arrow_down http://localhost:8710/assets/icons/arrow_down.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-auto_like http://localhost:8710/assets/icons/auto_like.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-auto_like_enabled http://localhost:8710/assets/icons/auto_like_enabled.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-clear_list http://localhost:8710/assets/icons/clear_list.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-copy http://localhost:8710/assets/icons/copy.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-delete http://localhost:8710/assets/icons/delete.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-edit http://localhost:8710/assets/icons/edit.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-error http://localhost:8710/assets/icons/error.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-experimental http://localhost:8710/assets/icons/beaker_small.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-globe http://localhost:8710/assets/icons/globe.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-globe_small http://localhost:8710/assets/icons/globe_small.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-help http://localhost:8710/assets/icons/help.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-image http://localhost:8710/assets/icons/image.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-image_filled http://localhost:8710/assets/icons/image_filled.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-link http://localhost:8710/assets/icons/link.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-lyrics http://localhost:8710/assets/icons/lyrics.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-reload http://localhost:8710/assets/icons/refresh.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-skip_to http://localhost:8710/assets/icons/skip_to.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-spinner http://localhost:8710/assets/icons/spinner.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource icon-upload http://localhost:8710/assets/icons/upload.svg?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource img-close http://localhost:8710/assets/images/close.png?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource img-discord http://localhost:8710/assets/images/external/discord.png?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource img-github http://localhost:8710/assets/images/external/github.png?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource img-greasyfork http://localhost:8710/assets/images/external/greasyfork.png?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource img-logo http://localhost:8710/assets/images/logo/logo_48.png?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource img-logo_dev http://localhost:8710/assets/images/logo/logo_dev_48.png?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource img-openuserjs http://localhost:8710/assets/images/external/openuserjs.png?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource trans-de_DE http://localhost:8710/assets/translations/de_DE.json?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource trans-en_UK http://localhost:8710/assets/translations/en_UK.json?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource trans-en_US http://localhost:8710/assets/translations/en_US.json?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource trans-es_ES http://localhost:8710/assets/translations/es_ES.json?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource trans-fr_FR http://localhost:8710/assets/translations/fr_FR.json?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource trans-hi_IN http://localhost:8710/assets/translations/hi_IN.json?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource trans-ja_JA http://localhost:8710/assets/translations/ja_JA.json?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource trans-pt_BR http://localhost:8710/assets/translations/pt_BR.json?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
+// @resource trans-zh_CN http://localhost:8710/assets/translations/zh_CN.json?b=d30bf402-9e02-4ef1-b318-84add1de5d91
|
|
|
// @require https://cdn.jsdelivr.net/npm/@sv443-network/[email protected]/dist/index.global.js
|
|
|
// @require https://cdn.jsdelivr.net/npm/[email protected]/lib/marked.umd.js
|
|
|
// @require https://cdn.jsdelivr.net/npm/[email protected]/lib/umd/index.js
|
|
@@ -129,7 +129,7 @@ var PluginIntent;
|
|
|
const modeRaw = "development";
|
|
|
const branchRaw = "develop";
|
|
|
const hostRaw = "github";
|
|
|
-const buildNumberRaw = "d1ceac6a";
|
|
|
+const buildNumberRaw = "5659067a";
|
|
|
/** The mode in which the script was built (production or development) */
|
|
|
const mode = (modeRaw.match(/^#{{.+}}$/) ? "production" : modeRaw);
|
|
|
/** The branch to use in various URLs that point to the GitHub repo */
|
|
@@ -376,8 +376,13 @@ class BytmDialog extends UserUtils.NanoEmitter {
|
|
|
bgElem.style.visibility = "hidden";
|
|
|
bgElem.style.display = "none";
|
|
|
bgElem.inert = true;
|
|
|
- bgElem.appendChild(await this.getDialogContent());
|
|
|
- document.body.appendChild(bgElem);
|
|
|
+ try {
|
|
|
+ bgElem.appendChild(await this.getDialogContent());
|
|
|
+ document.body.appendChild(bgElem);
|
|
|
+ }
|
|
|
+ catch (e) {
|
|
|
+ return error("Failed to render dialog content:", e);
|
|
|
+ }
|
|
|
this.attachListeners(bgElem);
|
|
|
this.events.emit("render");
|
|
|
return bgElem;
|
|
@@ -553,7 +558,8 @@ class BytmDialog extends UserUtils.NanoEmitter {
|
|
|
else {
|
|
|
// insert element to pad the header height
|
|
|
const padEl = document.createElement("div");
|
|
|
- padEl.classList.add("bytm-dialog-header-pad", this.options.small ? "small" : "");
|
|
|
+ padEl.classList.add("bytm-dialog-header-pad");
|
|
|
+ this.options.small && padEl.classList.add("small");
|
|
|
headerWrapperEl.appendChild(padEl);
|
|
|
}
|
|
|
if (this.options.closeBtnEnabled) {
|
|
@@ -1200,20 +1206,16 @@ async function createLongBtn(_a) {
|
|
|
}
|
|
|
/** Renders the dialog body elements from a markdown string using what's set in `this.opts.body` */
|
|
|
async renderBody() {
|
|
|
- const panesCont = document.createElement("div");
|
|
|
- panesCont.classList.add("bytm-exim-dialog-panes-cont");
|
|
|
- const markdownPane = document.createElement("div");
|
|
|
- markdownPane.classList.add("bytm-exim-dialog-pane");
|
|
|
- markdownPane.classList.add("bytm-exim-dialog-markdown-pane");
|
|
|
+ const bodyEl = document.createElement("div");
|
|
|
+ bodyEl.classList.add("bytm-md-dialog-body");
|
|
|
const mdCont = typeof this.opts.body === "string"
|
|
|
? this.opts.body
|
|
|
: await this.opts.body();
|
|
|
const markdownEl = document.createElement("div");
|
|
|
markdownEl.classList.add("bytm-exim-dialog-markdown");
|
|
|
markdownEl.innerHTML = await MarkdownDialog.parseMd(mdCont);
|
|
|
- markdownPane.appendChild(markdownEl);
|
|
|
- panesCont.appendChild(markdownPane);
|
|
|
- return panesCont;
|
|
|
+ bodyEl.appendChild(markdownEl);
|
|
|
+ return bodyEl;
|
|
|
}
|
|
|
}/** Max amount of seconds a toast can be shown for */
|
|
|
const maxToastDuration = 30000;
|
|
@@ -1258,6 +1260,7 @@ async function showIconToast(_a) {
|
|
|
position,
|
|
|
element: toastWrapper,
|
|
|
title: "message" in rest ? rest.message : rest.title,
|
|
|
+ onClick: rest.onClick,
|
|
|
});
|
|
|
}
|
|
|
/** Shows a toast message or element in the specified position (top right corner by default) and uses the default timeout from the config option `toastDuration` */
|
|
@@ -1268,18 +1271,22 @@ async function showToast(arg) {
|
|
|
duration: getFeature("toastDuration") * 1000,
|
|
|
}
|
|
|
: arg;
|
|
|
- const { duration: durationMs = getFeature("toastDuration") * 1000, position = "tr" } = props, rest = __rest(props, ["duration", "position"]);
|
|
|
+ const { duration: durationMs = getFeature("toastDuration") * 1000, onClick, position = "tr" } = props, rest = __rest(props, ["duration", "onClick", "position"]);
|
|
|
if (durationMs <= 0)
|
|
|
return info("Toast duration is <= 0, so it won't be shown");
|
|
|
const toastEl = document.querySelector("#bytm-toast");
|
|
|
if (toastEl)
|
|
|
await closeToast();
|
|
|
const toastElem = document.createElement("div");
|
|
|
+ onClick && toastElem.classList.add("clickable");
|
|
|
toastElem.id = "bytm-toast";
|
|
|
toastElem.role = "alert";
|
|
|
toastElem.ariaLive = "polite";
|
|
|
toastElem.ariaAtomic = "true";
|
|
|
- toastElem.addEventListener("click", async () => await closeToast(), { once: true });
|
|
|
+ toastElem.addEventListener("click", async (e) => {
|
|
|
+ onClick === null || onClick === void 0 ? void 0 : onClick(e);
|
|
|
+ await closeToast();
|
|
|
+ }, { once: true });
|
|
|
if ("message" in rest)
|
|
|
toastElem.title = toastElem.ariaLabel = toastElem.textContent = rest.message;
|
|
|
else {
|
|
@@ -3802,6 +3809,7 @@ async function restVidRestoreTime() {
|
|
|
let vidElem;
|
|
|
const doRestoreTime = async () => {
|
|
|
var _a;
|
|
|
+ dbg("Restoring time to", entry.songTime);
|
|
|
if (!vidElem)
|
|
|
vidElem = await waitVideoElementReady();
|
|
|
const vidRestoreTime = entry.songTime - ((_a = getFeature("rememberSongTimeReduction")) !== null && _a !== void 0 ? _a : 0);
|
|
@@ -3827,10 +3835,11 @@ async function restVidStartUpdateLoop() {
|
|
|
if (songTime === lastSongTime)
|
|
|
return;
|
|
|
lastSongTime = songTime;
|
|
|
+ dbg("># looped, different songTime:", songTime);
|
|
|
const watchID = getWatchId();
|
|
|
if (!watchID)
|
|
|
return;
|
|
|
- const paused = (_c = (_b = document.querySelector(getVideoSelector())) === null || _b === void 0 ? void 0 : _b.paused) !== null && _c !== void 0 ? _c : false;
|
|
|
+ const paused = (_c = (_b = getVideoElement()) === null || _b === void 0 ? void 0 : _b.paused) !== null && _c !== void 0 ? _c : false;
|
|
|
// don't immediately update to reduce race conditions and only update if the video is playing
|
|
|
// also it just sounds better if the song starts at the beginning if only a couple seconds have passed
|
|
|
if (songTime > getFeature("rememberSongTimeMinPlayTime") && !paused) {
|
|
@@ -3842,7 +3851,7 @@ async function restVidStartUpdateLoop() {
|
|
|
await restVidSetEntry(entry);
|
|
|
}
|
|
|
// if the song is rewound to the beginning, update the entry accordingly
|
|
|
- else {
|
|
|
+ else if (!paused) {
|
|
|
const entry = remVidsCache.find(entry => entry.watchID === watchID);
|
|
|
if (entry && songTime <= entry.songTime)
|
|
|
await restVidSetEntry(Object.assign(Object.assign({}, entry), { songTime, updateTimestamp: Date.now() }));
|
|
@@ -3867,6 +3876,7 @@ async function restVidSetEntry(data) {
|
|
|
}
|
|
|
/** Deletes an entry */
|
|
|
async function restVidDeleteEntry(watchID) {
|
|
|
+ dbg("Deleting entry with watchID", watchID);
|
|
|
remVidsCache = [...remVidsCache.filter(entry => entry.watchID !== watchID)];
|
|
|
await GM.setValue("bytm-rem-songs", JSON.stringify(remVidsCache));
|
|
|
}
|
|
@@ -3877,10 +3887,10 @@ function disableDarkReader() {
|
|
|
return;
|
|
|
const metaElem = document.createElement("meta");
|
|
|
metaElem.name = "darkreader-lock";
|
|
|
- metaElem.classList.add("bytm-disable-darkreader");
|
|
|
+ metaElem.id = "bytm-disable-dark-reader";
|
|
|
document.head.appendChild(metaElem);
|
|
|
info("Disabled Dark Reader");
|
|
|
-}const inputIgnoreTagNames = ["INPUT", "TEXTAREA", "SELECT", "BUTTON", "A", "TP-YT-PAPER-SLIDER"];
|
|
|
+}const inputIgnoreTagNames = ["INPUT", "TEXTAREA", "SELECT", "BUTTON", "A"];
|
|
|
//#region arrow key skip
|
|
|
async function initArrowKeySkip() {
|
|
|
document.addEventListener("keydown", (evt) => {
|
|
@@ -3900,7 +3910,7 @@ async function initArrowKeySkip() {
|
|
|
if (evt.code === "ArrowLeft")
|
|
|
skipBy *= -1;
|
|
|
log(`Captured arrow key '${evt.code}' - skipping by ${skipBy} seconds`);
|
|
|
- const vidElem = document.querySelector(getVideoSelector());
|
|
|
+ const vidElem = getVideoElement();
|
|
|
if (vidElem)
|
|
|
vidElem.currentTime = UserUtils.clamp(vidElem.currentTime + skipBy, 0, vidElem.duration);
|
|
|
});
|
|
@@ -3977,7 +3987,7 @@ async function initNumKeysSkip() {
|
|
|
const ignoreElement = numKeysIgnoreTagNames.includes((_b = (_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.tagName) !== null && _b !== void 0 ? _b : "");
|
|
|
if ((document.activeElement !== document.body && ignoreElement) || ignoreElement)
|
|
|
return info("Captured valid key to skip video to, but ignored it since this element is currently active:", document.activeElement);
|
|
|
- const vidElem = document.querySelector(getVideoSelector());
|
|
|
+ const vidElem = getVideoElement();
|
|
|
if (!vidElem)
|
|
|
return warn("Could not find video element, so the keypress is ignored");
|
|
|
const newVidTime = vidElem.duration / (10 / Number(e.key));
|
|
@@ -5795,6 +5805,7 @@ const globalFuncs = {
|
|
|
registerPlugin,
|
|
|
/**/ getPluginInfo,
|
|
|
// bytm-specific:
|
|
|
+ getDomain,
|
|
|
getResourceUrl,
|
|
|
getSessionId,
|
|
|
// dom:
|
|
@@ -5803,6 +5814,7 @@ const globalFuncs = {
|
|
|
getVideoTime,
|
|
|
getThumbnailUrl,
|
|
|
getBestThumbnailUrl,
|
|
|
+ waitVideoElementReady,
|
|
|
// translations:
|
|
|
/**/ setLocale: setLocaleInterface,
|
|
|
getLocale,
|
|
@@ -6235,6 +6247,10 @@ document.addEventListener("DOMContentLoaded", () => domLoaded = true);
|
|
|
//#region video time, volume
|
|
|
/** Returns the video element selector string based on the current domain */
|
|
|
const getVideoSelector = () => getDomain() === "ytm" ? "ytmusic-player video" : "#player-container ytd-player video";
|
|
|
+/** Returns the video element based on the current domain */
|
|
|
+function getVideoElement() {
|
|
|
+ return document.querySelector(getVideoSelector());
|
|
|
+}
|
|
|
/**
|
|
|
* Returns the current video time in seconds, with the given {@linkcode precision} (2 decimal digits by default).
|
|
|
* Rounds down if the precision is set to 0. The maximum average available precision on YTM is 6.
|
|
@@ -6246,7 +6262,7 @@ function getVideoTime(precision = 2) {
|
|
|
await waitVideoElementReady();
|
|
|
try {
|
|
|
if (getDomain() === "ytm") {
|
|
|
- const vidElem = document.querySelector(getVideoSelector());
|
|
|
+ const vidElem = getVideoElement();
|
|
|
if (vidElem)
|
|
|
return res(Number(precision <= 0 ? Math.floor(vidElem.currentTime) : vidElem.currentTime.toFixed(precision)));
|
|
|
addSelectorListener("playerBar", "tp-yt-paper-slider#progress-bar tp-yt-paper-progress#sliderBar", {
|
|
@@ -6254,7 +6270,7 @@ function getVideoTime(precision = 2) {
|
|
|
});
|
|
|
}
|
|
|
else if (getDomain() === "yt") {
|
|
|
- const vidElem = document.querySelector(getVideoSelector());
|
|
|
+ const vidElem = getVideoElement();
|
|
|
if (vidElem)
|
|
|
return res(Number(precision <= 0 ? Math.floor(vidElem.currentTime) : vidElem.currentTime.toFixed(precision)));
|
|
|
// YT doesn't update the progress bar when it's hidden (contrary to YTM which never hides it)
|
|
@@ -6317,6 +6333,9 @@ function ytForceShowVideoTime() {
|
|
|
*/
|
|
|
function waitVideoElementReady() {
|
|
|
return new Promise(async (res) => {
|
|
|
+ var _a;
|
|
|
+ if (((_a = getVideoElement()) === null || _a === void 0 ? void 0 : _a.readyState) === 4)
|
|
|
+ return res(getVideoElement());
|
|
|
const waitForEl = () => addSelectorListener("body", getVideoSelector(), {
|
|
|
listener: async (vidElem) => {
|
|
|
if (vidElem) {
|
|
@@ -6439,16 +6458,40 @@ function info(...args) {
|
|
|
function warn(...args) {
|
|
|
console.warn(consPrefix, ...args);
|
|
|
}
|
|
|
+let errorDialog;
|
|
|
+function getErrorDialog(errName, args) {
|
|
|
+ if (errorDialog)
|
|
|
+ return errorDialog;
|
|
|
+ return errorDialog = new MarkdownDialog({
|
|
|
+ id: "generic-error",
|
|
|
+ height: 400,
|
|
|
+ width: 500,
|
|
|
+ small: true,
|
|
|
+ renderHeader() {
|
|
|
+ const header = document.createElement("h2");
|
|
|
+ header.classList.add("bytm-dialog-title");
|
|
|
+ header.role = "heading";
|
|
|
+ header.ariaLevel = "1";
|
|
|
+ header.tabIndex = 0;
|
|
|
+ header.textContent = header.ariaLabel = errName;
|
|
|
+ return header;
|
|
|
+ },
|
|
|
+ body: args.join(" "),
|
|
|
+ });
|
|
|
+}
|
|
|
/** Logs all passed values to the console as an error, no matter the log level. */
|
|
|
function error(...args) {
|
|
|
var _a, _b;
|
|
|
console.error(consPrefix, ...args);
|
|
|
- getFeature("showToastOnGenericError")
|
|
|
- && showIconToast({
|
|
|
- message: t("generic_error_toast", (_b = (_a = args.find(a => a instanceof Error)) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : t("error")),
|
|
|
+ if (getFeature("showToastOnGenericError")) {
|
|
|
+ const errName = (_b = (_a = args.find(a => a instanceof Error)) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : t("error");
|
|
|
+ showIconToast({
|
|
|
+ message: t("generic_error_toast", errName),
|
|
|
icon: "icon-error",
|
|
|
iconFill: "var(--bytm-error-col)",
|
|
|
+ onClick: () => getErrorDialog(errName, Array.isArray(args) ? args : []).open(),
|
|
|
});
|
|
|
+ }
|
|
|
}
|
|
|
/** Logs all passed values to the console with a debug-specific prefix */
|
|
|
function dbg(...args) {
|