diff --git a/manifest/manifest.json b/manifest/manifest.json index 1c52c561..c9350235 100644 --- a/manifest/manifest.json +++ b/manifest/manifest.json @@ -1,7 +1,7 @@ { "name": "__MSG_fullName__", "short_name": "SponsorBlock", - "version": "3.3.2", + "version": "3.3.3", "default_locale": "en", "description": "__MSG_Description__", "homepage_url": "https://sponsor.ajay.app", diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json index 072f6a7e..e3bedc09 100644 --- a/public/_locales/en/messages.json +++ b/public/_locales/en/messages.json @@ -183,7 +183,7 @@ "message": "This hides the buttons that appear on the YouTube player to submit skip segments." }, "showSkipButton": { - "message": "Keep Skip to Highlight Button on Player" + "message": "Keep Skip To Highlight Button On Player" }, "showInfoButton": { "message": "Show Info Button On YouTube Player" diff --git a/public/_locales/id/messages.json b/public/_locales/id/messages.json index 7a24e7bb..0b44c6bf 100644 --- a/public/_locales/id/messages.json +++ b/public/_locales/id/messages.json @@ -52,6 +52,9 @@ "reskip": { "message": "Lewati Ulang" }, + "unmute": { + "message": "Bunyikan" + }, "paused": { "message": "Dijeda" }, @@ -85,6 +88,9 @@ "noVideoID": { "message": "Video YouTube tidak ditemukan.\nJika terjadi kesalahan, segarkan halaman." }, + "refreshSegments": { + "message": "Segarkan segmen" + }, "success": { "message": "Sukses!" }, @@ -155,6 +161,9 @@ "setUsername": { "message": "Atur Nama Pengguna" }, + "copyPublicID": { + "message": "Salin UserID Publik" + }, "discordAdvert": { "message": "Gabung dengan server resmi discord untuk memberikan kritik dan saran!" }, @@ -179,6 +188,9 @@ "hideInfoButton": { "message": "Sembunyikan Tombol Info Di Pemutar Video YouTube" }, + "autoHideInfoButton": { + "message": "Otomatis Sembunyikan Tombol Info" + }, "hideDeleteButton": { "message": "Sembunyikan Tombol Hapus Di Pemutar Video YouTube" }, @@ -269,9 +281,15 @@ "skip": { "message": "Lewati" }, + "mute": { + "message": "Bisukan" + }, "skip_category": { "message": "Lewati {0}?" }, + "mute_category": { + "message": "Bisukan {0}?" + }, "skip_to_category": { "message": "Lompat ke {0}?", "description": "Used for skipping to things (Skip to Highlight)" @@ -280,6 +298,10 @@ "message": "{0} dilewati", "description": "Example: Sponsor Skipped" }, + "muted": { + "message": "{0} Dibisukan", + "description": "Example: Sponsor Muted" + }, "skipped_to_category": { "message": "Melewati ke {0}", "description": "Used for skipping to things (Skipped to Highlight)" @@ -332,6 +354,9 @@ "changeUserID": { "message": "Impor/Ekspor UserID" }, + "whatChangeUserID": { + "message": "Ini harus dirahasiakan. Ini seperti kata sandi dan tidak boleh dibagikan kepada siapa pun. Jika seseorang mempunyai ini, mereka bisa menyamar jadi anda. Jika anda mencari UserID publik anda, klik ikon papan tulis di popup." + }, "setUserID": { "message": "Atur UserID" }, @@ -347,9 +372,19 @@ "supportOtherSites": { "message": "Dukung Situs Youtube Pihak Ketiga" }, + "supportOtherSitesDescription": { + "message": "Dukung klien YouTube pihak ketiga. Untuk mengaktifkan dukungan, anda harus menerima izin tambahan. Ini tidak akan bekerja di Mode Samaran di Chrome dan varian Chromium lainnya.", + "description": "This replaces the 'supports Invidious' option because it now works on other YouTube sites such as Cloudtube" + }, + "supportedSites": { + "message": "Situs yang didukung: " + }, "optionsInfo": { "message": "Aktifkan dukungan Invidious, nonaktifkan lewati otomatis, tombol sembunyi dan lainnya." }, + "addInvidiousInstance": { + "message": "Tambah Instance Klien Pihak Ketiga" + }, "add": { "message": "Tambah" }, diff --git a/public/_locales/uk/messages.json b/public/_locales/uk/messages.json index 609d94eb..065ef22e 100644 --- a/public/_locales/uk/messages.json +++ b/public/_locales/uk/messages.json @@ -591,7 +591,7 @@ "message": "Пропуск вручну" }, "showOverlay": { - "message": "Показувати в смузі прокрутки" + "message": "Показувати в смузі перемотування" }, "disable": { "message": "Вимкнути" @@ -600,7 +600,7 @@ "message": "Автоматический переход к началу" }, "manualSkip_POI": { - "message": "Спросите, когда видео загружается" + "message": "Спитати поки відео завантажується" }, "showOverlay_POI": { "message": "Показать на панели поиска" diff --git a/src/content.ts b/src/content.ts index 4db051e7..f708e4f4 100644 --- a/src/content.ts +++ b/src/content.ts @@ -464,7 +464,7 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?: } // Don't skip if this category should not be skipped - if (!shouldSkip(currentSkip) && skipInfo.array !== sponsorTimesSubmitting) return; + if (!shouldSkip(currentSkip) && !sponsorTimesSubmitting?.some((segment) => segment.segment === currentSkip.segment)) return; const skippingFunction = () => { let forcedSkipTime: number = null; @@ -915,7 +915,7 @@ function getYouTubeVideoID(url: string): string | boolean { if(url.startsWith("https://www.youtube.com/tv#/")) url = url.replace("#", ""); //Attempt to parse url - let urlObject = null; + let urlObject: URL = null; try { urlObject = new URL(url); } catch (e) { @@ -941,9 +941,10 @@ function getYouTubeVideoID(url: string): string | boolean { if (urlObject.searchParams.has("v") && ["/watch", "/watch/"].includes(urlObject.pathname) || urlObject.pathname.startsWith("/tv/watch")) { const id = urlObject.searchParams.get("v"); return id.length == 11 ? id : false; - } else if (urlObject.pathname.startsWith("/embed/")) { + } else if (urlObject.pathname.startsWith("/embed/") || urlObject.pathname.startsWith("/shorts/")) { try { - return urlObject.pathname.substr(7, 11); + const id = urlObject.pathname.split("/")[2]; + if (id && id.length >= 11) return id.substr(0, 11); } catch (e) { console.error("[SB] Video ID not valid for " + url); return false; diff --git a/src/utils.ts b/src/utils.ts index 942146ca..6dacf325 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -189,14 +189,20 @@ export default class Utils { element.classList.add("animationDone"); if (!rightSlide) element.classList.add("autoHideLeft"); + let mouseEntered = false; + container.addEventListener("mouseenter", () => { + mouseEntered = true; element.classList.remove("animationDone"); // Wait for next event loop - setTimeout(() => element.classList.remove("hidden"), 10); + setTimeout(() => { + if (mouseEntered) element.classList.remove("hidden") + }, 10); }); container.addEventListener("mouseleave", () => { + mouseEntered = false; if (element.classList.contains("autoHiding")) { element.classList.add("hidden"); } @@ -205,10 +211,12 @@ export default class Utils { enableAutoHideAnimation(element: Element): void { element.classList.add("autoHiding"); + element.classList.add("hidden"); } disableAutoHideAnimation(element: Element): void { element.classList.remove("autoHiding"); + element.classList.remove("hidden"); } /** diff --git a/src/utils/urlParser.ts b/src/utils/urlParser.ts index 37f5067c..209c7c51 100644 --- a/src/utils/urlParser.ts +++ b/src/utils/urlParser.ts @@ -11,13 +11,13 @@ export function urlTimeToSeconds(time: string): number { return 0; } - const re = /(?:(?\d{1,3})h)?(?:(?\d{1,2})m)?(?\d+)s?/; + const re = /(?:(\d{1,3})h)?(?:(\d{1,2})m)?(\d+)s?/; const match = re.exec(time); if (match) { - const hours = parseInt(match.groups.hours ?? '0', 10); - const minutes = parseInt(match.groups.minutes ?? '0', 10); - const seconds = parseInt(match.groups.seconds ?? '0', 10); + const hours = parseInt(match[1] ?? '0', 10); + const minutes = parseInt(match[2] ?? '0', 10); + const seconds = parseInt(match[3] ?? '0', 10); return hours * 3600 + minutes * 60 + seconds; } else if (/\d+/.test(time)) { diff --git a/test/urlParser.test.ts b/test/urlParser.test.ts index 32cf1568..888227dc 100644 --- a/test/urlParser.test.ts +++ b/test/urlParser.test.ts @@ -5,15 +5,15 @@ describe("getStartTimeFromUrl", () => { expect(getStartTimeFromUrl("https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=123")).toBe(123); }); - it("parses with a seconds", () => { + it("parses with seconds", () => { expect(getStartTimeFromUrl("https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=123s")).toBe(123); }); - it("parses with a minutes", () => { + it("parses with minutes", () => { expect(getStartTimeFromUrl("https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=23m3s")).toBe(23 * 60 + 3); }); - it("parses with a hours", () => { + it("parses with hours", () => { expect(getStartTimeFromUrl("https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=1h2m3s")).toBe(1 * 60 * 60 + 2 * 60 + 3); });