Compare commits

..

12 Commits
4.6.2 ... 4.6.4

Author SHA1 Message Date
Ajay
d352c6efb4 bump version 2022-07-13 12:16:11 -04:00
Ajay
5ff9b10f21 Fix double skip issue 2022-07-13 12:15:56 -04:00
Ajay Ramachandran
3ee2e2517a bump version 2022-07-12 11:43:58 -04:00
Ajay Ramachandran
dd7f227305 Merge pull request #1388 from mchangrh/revert-module-fix-ci
Revert module & fix ci
2022-07-12 11:43:32 -04:00
Ajay Ramachandran
c1d3c7d680 New Crowdin updates (#1393) 2022-07-12 11:42:09 -04:00
Ajay
fae6d0d0cf Add comments 2022-07-12 01:03:28 -04:00
Ajay
60d106fc52 Fix cases with multiple segments starting at the exact same time 2022-07-12 00:59:13 -04:00
Ajay
a4df2eab8f Retry for errors again 2022-07-11 15:00:48 -04:00
Ajay
7a50167222 Remove first event check 2022-07-05 16:02:05 -04:00
Ajay
e48d956577 Fix segments disapearing when changing skip options 2022-07-03 22:44:32 -04:00
Michael C
7ed01a181e sort invidiousList for consistency, update from failed CI 2022-06-30 21:47:54 -04:00
Michael C
4119fd8433 revert module conversion 2022-06-30 21:39:28 -04:00
15 changed files with 157 additions and 74 deletions

View File

@@ -49,7 +49,7 @@ const reliableCheck = mapped
.filter(instance => instance.url.includes(instance.name))
// finally map to array
const result: string[] = reliableCheck.map(instance => instance.name)
const result: string[] = reliableCheck.map(instance => instance.name).sort()
writeFile(join(__dirname, "./invidiouslist.json"), JSON.stringify(result), (err) => {
if (err) return console.log(err);
})

View File

@@ -1 +1 @@
["yewtu.be","vid.puffyan.us","invidious.snopyta.org","inv.riverside.rocks","invidious-us.kavin.rocks","invidious.osi.kr","tube.cthd.icu","invidious.flokinet.to","yt.artemislena.eu","invidious.mutahar.rocks","invidious.esmailelbob.xyz","youtube.076.ne.jp","invidious.weblibre.org","invidious.namazso.eu","invidious.kavin.rocks"]
["inv.cthd.icu","inv.riverside.rocks","invidio.xamh.de","invidious.kavin.rocks","invidious.namazso.eu","invidious.osi.kr","invidious.snopyta.org","vid.puffyan.us","yewtu.be","youtube.076.ne.jp","yt.artemislena.eu"]

View File

@@ -1,7 +1,7 @@
{
"name": "__MSG_fullName__",
"short_name": "SponsorBlock",
"version": "4.6.2",
"version": "4.6.4",
"default_locale": "en",
"description": "__MSG_Description__",
"homepage_url": "https://sponsor.ajay.app",

View File

@@ -3,7 +3,6 @@
"version": "1.0.0",
"description": "",
"main": "background.js",
"type": "module",
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"

View File

@@ -53,7 +53,7 @@
"message": "Pomiń"
},
"unmute": {
"message": "Odcisz"
"message": "Anuluj wyciszenie"
},
"paused": {
"message": "Zatrzymany"
@@ -246,16 +246,16 @@
"message": "Pełnowymiarowe powiadomienia o przewinięciu"
},
"noticeVisibilityMode1": {
"message": "Małe powiadomienia o automatycznym pomijaniu"
"message": "Małe powiadomienia o automatycznym przewinięciu"
},
"noticeVisibilityMode2": {
"message": "Małe powiadomienia o przewinięciu"
},
"noticeVisibilityMode3": {
"message": "Znikające powiadomienia o automatycznym pomijaniu"
"message": "Półprzezroczyste powiadomienie o automatycznym przewinięciu"
},
"noticeVisibilityMode4": {
"message": "Znikające powiadomienia o pomijaniu"
"message": "Półprzezroczyste powiadomienie dla wszystkich przewinięć"
},
"longDescription": {
"message": "SponsorBlock pozwala pomijać sponsorów, intra, outra, przypomnienia o subskrypcjach i inne irytujące fragmenty filmów na YouTube. SponsorBlock jest opartym na crowdsourcingu rozszerzeniem do przeglądarki, które pozwala każdemu zgłosić początek i koniec segmentów sponsorowanych oraz innych segmentów w filmach na YouTube. Kiedy ktoś już zamieści te informacje, wszyscy pozostali z tym rozszerzeniem będą pomijać segment sponsorowany. Możesz również pomijać fragmenty teledysków bez muzyki.",
@@ -549,7 +549,7 @@
"message": "Zawiera płynne przejścia"
},
"generic_guideline2": {
"message": "Odtwarza się, jakby nic nie zostało pominięte"
"message": "Pominięcie bez zauważalnego przeskoku"
},
"category_sponsor": {
"message": "Sponsor"
@@ -649,7 +649,7 @@
"message": "Nie dla sekcji, które zawierają potrzebne informacje"
},
"category_filler": {
"message": "Wypełniacz nietematyczny/Żart"
"message": "Wypełniacz nietematyczny/żart"
},
"category_filler_description": {
"message": "Sceny nietematyczne dodawane tylko jako wypełniacz lub dla humoru, które nie są wymagane do zrozumienia głównej treści filmu. Nie powinno to obejmować segmentów zawierających informacje kontekstowe lub szczegółowe."
@@ -664,7 +664,7 @@
"message": "Rozpraszacze, wpadki, powtórki"
},
"category_filler_guideline3": {
"message": "Nie dla scen wymaganych, by zrozumieć temat"
"message": "Nie nadaje się do scen wymaganych do zrozumienia tematu"
},
"category_music_offtopic": {
"message": "Muzyka: Sekcja niemuzyczna"
@@ -691,10 +691,10 @@
"message": "Część filmu, której szuka większość osób"
},
"category_poi_highlight_guideline2": {
"message": "Może pomijać kontekst"
"message": "Może pomóc pominąć kontekst"
},
"category_poi_highlight_guideline3": {
"message": "Może pomijać do tytułu lub miniaturki"
"message": "Może pomić do karty tytułowej lub miniaturki"
},
"category_livestream_messages": {
"message": "Transmisja live: Dotacja/Czytanie wiadomości"
@@ -737,7 +737,7 @@
"description": "Referring to the category pill that is now shown on videos that are entirely sponsor or entirely selfpromo"
},
"previewColor": {
"message": "Nieprzesłany kolor",
"message": "Kolor nieprzesłanego segmentu",
"description": "Referring to submissions that have not been sent to the server yet."
},
"seekBarColor": {
@@ -1007,7 +1007,7 @@
"description": "Appears in Options as a tab header for advanced/niche options. To fit inside the button, it should not be longer than ~20-25 characters (depending on their width)."
},
"noticeVisibilityLabel": {
"message": "Pomiń wygląd wpisu",
"message": "Wygląd okna pomijania",
"description": "Option label"
},
"unbind": {

View File

@@ -239,6 +239,9 @@
"showSkipNotice": {
"message": "Показувати сповіщення після пропуску сегмента"
},
"showCategoryGuidelines": {
"message": "Показати Довідку по Категоріях"
},
"noticeVisibilityMode0": {
"message": "Повнорозмірні сповіщення про пропуски"
},

View File

@@ -239,6 +239,9 @@
"showSkipNotice": {
"message": "Hiển thị thông báo sau khi bỏ qua phân đoạn"
},
"showCategoryGuidelines": {
"message": "Hiển thị Danh mục Trợ giúp"
},
"noticeVisibilityMode0": {
"message": "Thông báo bỏ qua với kích thước đầy đủ"
},
@@ -542,18 +545,36 @@
"message": "đến",
"description": "Used between segments. Example: 1:20 to 1:30"
},
"generic_guideline2": {
"message": "Chơi như thể không có gì bị bỏ qua"
},
"category_sponsor": {
"message": "Nhà tài trợ"
},
"category_sponsor_description": {
"message": "Nội dung được trả tiền để quảng cáo, giới thiệu và quảng cáo trực tiếp. Không phải là quảng cáo không trả công hay được đề cập miễn phí."
},
"category_sponsor_guideline1": {
"message": "Quảng cáo trả phí"
},
"category_sponsor_guideline2": {
"message": "Không dành cho các khoản đóng góp"
},
"category_selfpromo": {
"message": "Quảng cáo không trả công/Tự quảng cáo"
},
"category_selfpromo_description": {
"message": "Tương tự như 'nhà tài trợ' ngoại trừ việc quảng cáo không được trả tiền hay tự quảng cáo. Điều này bao gồm các phần hàng hóa, đóng góp, hoặc thông tin về người mà họ hợp tác cùng."
},
"category_selfpromo_guideline1": {
"message": "Quyên góp, tư cách thành viên và hàng hóa tùy chỉnh"
},
"category_selfpromo_guideline2": {
"message": "Lời cảm ơn miễn phí không thêm vào video"
},
"category_selfpromo_guideline3": {
"message": "Không dành cho các sản phẩm và hàng hóa do công ty thiết kế"
},
"category_exclusive_access": {
"message": "Truy cập riêng"
},
@@ -564,12 +585,24 @@
"message": "Video này giới thiệu sản phẩm, dịch vụ hoặc vị trí mà họ đã nhận được quyền truy cập miễn phí hoặc được trợ cấp",
"description": "Short description for this category"
},
"category_exclusive_access_guideline1": {
"message": "Toàn bộ video giới thiệu nội dung nào đó có quyền truy cập miễn phí hoặc được trợ cấp"
},
"category_interaction": {
"message": "Nhắc tương tác (Đăng ký)"
},
"category_interaction_description": {
"message": "Nhắc nhở người xem Thích, Đăng ký hoặc Theo dõi. Nếu nó dài hoặc là một cái gì cụ thể, nó nên là danh mục \"Tự quảng cáo\"."
},
"category_interaction_guideline1": {
"message": "Lời nhắc ngắn gọn để thích, đăng ký hoặc theo dõi"
},
"category_interaction_guideline2": {
"message": "Bao gồm lời nhắc gián tiếp để nhận xét"
},
"category_interaction_guideline3": {
"message": "Không dành cho quảng cáo chung, chỉ dành cho lời kêu gọi hành động"
},
"category_interaction_short": {
"message": "Nhắc nhở tương tác"
},
@@ -582,18 +615,36 @@
"category_intro_short": {
"message": "Tạm ngừng"
},
"category_intro_guideline1": {
"message": "Khoảng thời gian không có nội dung thực tế"
},
"category_intro_guideline2": {
"message": "Không dành cho chuyển tiếp với thông tin"
},
"category_outro": {
"message": "Màn hình kết thúc/Danh đề"
},
"category_outro_description": {
"message": "Credits hoặc khi thẻ màn hình kết thúc của YouTube xuất hiện. Không dùng với những đoạn có thông tin."
},
"category_outro_guideline1": {
"message": "Không bao gồm nội dung, ngay cả khi thẻ kết thúc ở trên màn hình"
},
"category_preview": {
"message": "Xem trước/Tóm tắt"
},
"category_preview_description": {
"message": "Tóm tắt nhanh về tập trước/tập sau trong 1 chuỗi video (series) dài (hoặc cũng có thể là tóm tắt trước về video sắp chiếu)."
},
"category_preview_guideline1": {
"message": "Các clip xuất hiện sau đó hoặc trong một video trong tương lai"
},
"category_preview_guideline2": {
"message": "Tóm tắt video trước đó"
},
"category_preview_guideline3": {
"message": "Không dành cho các phần thêm nội dung bổ sung"
},
"category_filler_description": {
"message": "Tập hợp các cảnh không bắt buộc để xem trong video. Điều này không bao gồm các đoạn chứa nội dung hoặc nói về ngữ cảnh của video."
},

View File

@@ -111,8 +111,6 @@ class CategorySkipOptionsComponent extends React.Component<CategorySkipOptionsPr
skipOptionSelected(event: React.ChangeEvent<HTMLSelectElement>): void {
let option: CategorySkipOption;
this.removeCurrentCategorySelection();
switch (event.target.value) {
case "disable":
return;
@@ -130,28 +128,17 @@ class CategorySkipOptionsComponent extends React.Component<CategorySkipOptionsPr
break;
}
Config.config.categorySelections.push({
name: this.props.category,
option: option
});
// Forces the Proxy to send this to the chrome storage API
Config.config.categorySelections = Config.config.categorySelections;
}
/** Removes this category from the config list of category selections */
removeCurrentCategorySelection(): void {
// Remove it if it exists
for (let i = 0; i < Config.config.categorySelections.length; i++) {
if (Config.config.categorySelections[i].name === this.props.category) {
Config.config.categorySelections.splice(i, 1);
// Forces the Proxy to send this to the chrome storage API
Config.config.categorySelections = Config.config.categorySelections;
break;
}
const existingSelection = Config.config.categorySelections.find(selection => selection.name === this.props.category);
if (existingSelection) {
existingSelection.option = option;
} else {
Config.config.categorySelections.push({
name: this.props.category,
option: option
});
}
Config.forceSyncUpdate("categorySelections");
}
getCategorySkipOptions(): JSX.Element[] {

View File

@@ -74,9 +74,6 @@ let lastPreviewBarUpdate;
// Is the video currently being switched
let switchingVideos = null;
// Made true every videoID change
let firstEvent = false;
// Used by the play and playing listeners to make sure two aren't
// called at the same time
let lastCheckTime = 0;
@@ -120,8 +117,8 @@ let submissionNotice: SubmissionNotice = null;
// If there is an advert playing (or about to be played), this is true
let isAdPlaying = false;
// last response status
let lastResponseStatus: number;
let retryCount = 0;
// Contains all of the functions and variables needed by the skip notice
const skipNoticeContentContainer: ContentContainer = () => ({
@@ -278,6 +275,7 @@ if (!Config.configSyncListeners.includes(contentConfigUpdateListener)) {
function resetValues() {
lastCheckTime = 0;
lastCheckVideoTime = -1;
retryCount = 0;
//reset sponsor times
sponsorTimes = null;
@@ -307,8 +305,6 @@ function resetValues() {
logDebug("Setting switching videos to true (reset data)");
}
firstEvent = true;
// Reset advert playing flag
isAdPlaying = false;
@@ -573,6 +569,19 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
openNotice: skipInfo.openNotice
});
// These are segments that start at the exact same time but need seperate notices
for (const extra of skipInfo.extraIndexes) {
const extraSkip = skipInfo.array[extra];
if (shouldSkip(extraSkip)) {
skipToTime({
v: video,
skipTime: [extraSkip.scheduledTime, extraSkip.segment[1]],
skippingSegments: [extraSkip],
openNotice: skipInfo.openNotice
});
}
}
if (utils.getCategorySelection(currentSkip.category)?.option === CategorySkipOption.ManualSkip
|| currentSkip.actionType === ActionType.Mute) {
forcedSkipTime = skipTime[0] + 0.001;
@@ -707,8 +716,7 @@ function setupVideoListeners() {
// This check makes sure that changing the video resolution doesn't cause the extension to think it
// gone back to the begining
if (video.readyState <= HTMLMediaElement.HAVE_CURRENT_DATA
&& !firstEvent && video.currentTime === 0) return;
firstEvent = false;
&& video.currentTime === 0) return;
updateVirtualTime();
@@ -857,7 +865,7 @@ async function sponsorsLookup(keepOldSubmissions = true) {
?.map((video) => video.segments)[0];
if (!recievedSegments || !recievedSegments.length) {
// return if no video found
retryFetch();
retryFetch(404);
return;
}
@@ -919,9 +927,7 @@ async function sponsorsLookup(keepOldSubmissions = true) {
updatePreviewBar();
}
} else {
if (lastResponseStatus === 404) {
retryFetch();
}
retryFetch(lastResponseStatus);
}
if (Config.config.isVip) {
@@ -955,16 +961,23 @@ async function lockedCategoriesLookup(): Promise<void> {
}
}
function retryFetch(): void {
function retryFetch(errorCode: number): void {
if (!Config.config.refetchWhenNotFound) return;
sponsorDataFound = false;
if (errorCode !== 404 && retryCount > 1) {
// Too many errors (50x), give up
return;
}
retryCount++;
const delay = errorCode === 404 ? (10000 + Math.random() * 30000) : (2000 + Math.random() * 10000);
setTimeout(() => {
if (sponsorVideoID && sponsorTimes?.length === 0) {
sponsorsLookup();
}
}, 10000 + Math.random() * 30000);
}, delay);
}
/**
@@ -1192,13 +1205,33 @@ async function whitelistCheck() {
* Returns info about the next upcoming sponsor skip
*/
function getNextSkipIndex(currentTime: number, includeIntersectingSegments: boolean, includeNonIntersectingSegments: boolean):
{array: ScheduledTime[], index: number, endIndex: number, openNotice: boolean} {
{array: ScheduledTime[], index: number, endIndex: number, extraIndexes: number[], openNotice: boolean} {
const autoSkipSorter = (segment: ScheduledTime) => {
const skipOption = utils.getCategorySelection(segment.category)?.option;
if (skipOption === CategorySkipOption.AutoSkip
&& segment.actionType === ActionType.Skip) {
return 0;
} else if (skipOption !== CategorySkipOption.ShowOverlay) {
return 1;
} else {
return 2;
}
}
const { includedTimes: submittedArray, scheduledTimes: sponsorStartTimes } =
getStartTimes(sponsorTimes, includeIntersectingSegments, includeNonIntersectingSegments);
const { scheduledTimes: sponsorStartTimesAfterCurrentTime } = getStartTimes(sponsorTimes, includeIntersectingSegments, includeNonIntersectingSegments, currentTime, true, true);
const minSponsorTimeIndex = sponsorStartTimes.indexOf(Math.min(...sponsorStartTimesAfterCurrentTime));
// This is an array in-case multiple segments have the exact same start time
const minSponsorTimeIndexes = GenericUtils.indexesOf(sponsorStartTimes, Math.min(...sponsorStartTimesAfterCurrentTime));
// Find auto skipping segments if possible, sort by duration otherwise
const minSponsorTimeIndex = minSponsorTimeIndexes.sort(
(a, b) => ((autoSkipSorter(submittedArray[a]) - autoSkipSorter(submittedArray[b]))
|| (submittedArray[a].segment[1] - submittedArray[a].segment[0]) - (submittedArray[b].segment[1] - submittedArray[b].segment[0])))[0] ?? -1;
// Store extra indexes for the non-auto skipping segments if others occur at the exact same start time
const extraIndexes = minSponsorTimeIndexes.filter((i) => i !== minSponsorTimeIndex && autoSkipSorter(submittedArray[i]) !== 0);
const endTimeIndex = getLatestEndTimeIndex(submittedArray, minSponsorTimeIndex);
const { includedTimes: unsubmittedArray, scheduledTimes: unsubmittedSponsorStartTimes } =
@@ -1214,6 +1247,7 @@ function getNextSkipIndex(currentTime: number, includeIntersectingSegments: bool
array: submittedArray,
index: minSponsorTimeIndex,
endIndex: endTimeIndex,
extraIndexes, // Segments at same time that need seperate notices
openNotice: true
};
} else {
@@ -1221,6 +1255,7 @@ function getNextSkipIndex(currentTime: number, includeIntersectingSegments: bool
array: unsubmittedArray,
index: minUnsubmittedSponsorTimeIndex,
endIndex: previewEndTimeIndex,
extraIndexes: [], // No manual things for unsubmitted
openNotice: false
};
}

View File

@@ -64,8 +64,17 @@ function hexToRgb(hex: string): {r: number, g: number, b: number} {
} : null;
}
/**
* List of all indexes that have the specified value
* https://stackoverflow.com/a/54954694/1985387
*/
function indexesOf<T>(array: T[], value: T): number[] {
return array.map((v, i) => v === value ? i : -1).filter(i => i !== -1);
}
export const GenericUtils = {
wait,
getErrorMessage,
getLuminance
getLuminance,
indexesOf
}

View File

@@ -1,15 +1,12 @@
/* eslint-disable @typescript-eslint/no-var-requires */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import webpack from "webpack"
import path from "path"
import { fileURLToPath } from "url"
import CopyPlugin from "copy-webpack-plugin"
import BuildManifest from "./webpack.manifest.cjs";
const srcDir = "../src/";
import fs from "fs";
import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin";
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const webpack = require("webpack");
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
const BuildManifest = require('./webpack.manifest');
const srcDir = '../src/';
const fs = require("fs");
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const edgeLanguages = [
"de",
@@ -27,7 +24,7 @@ const edgeLanguages = [
"zh_CN"
]
export default env => ({
module.exports = env => ({
entry: {
popup: path.join(__dirname, srcDir + 'popup.ts'),
background: path.join(__dirname, srcDir + 'background.ts'),

View File

@@ -1,7 +1,8 @@
import { merge } from "webpack-merge";
import common from './webpack.common.js';
/* eslint-disable @typescript-eslint/no-var-requires */
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
export default env => merge(common(env), {
module.exports = env => merge(common(env), {
devtool: 'inline-source-map',
mode: 'development'
});

View File

@@ -1,7 +1,8 @@
import { merge } from "webpack-merge";
import common from './webpack.common.js';
/* eslint-disable @typescript-eslint/no-var-requires */
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
export default env => {
module.exports = env => {
let mode = "production";
env.mode = mode;