Merge branch 'master' into update-matrix

This commit is contained in:
Ajay Ramachandran
2021-09-03 16:36:51 -04:00
committed by GitHub
52 changed files with 1663 additions and 299 deletions

View File

@@ -3,6 +3,8 @@ module.exports = {
browser: true, browser: true,
es2021: true, es2021: true,
node: true, node: true,
jest: true,
jasmine: true,
}, },
extends: [ extends: [
"eslint:recommended", "eslint:recommended",

View File

@@ -1,6 +1,6 @@
module.exports = { module.exports = {
"roots": [ "roots": [
"src" "test"
], ],
"transform": { "transform": {
"^.+\\.ts$": "ts-jest" "^.+\\.ts$": "ts-jest"

View File

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

432
package-lock.json generated
View File

@@ -11,6 +11,7 @@
"dependencies": { "dependencies": {
"@types/react": "^16.9.22", "@types/react": "^16.9.22",
"@types/react-dom": "^16.9.5", "@types/react-dom": "^16.9.5",
"@types/selenium-webdriver": "^4.0.15",
"babel": "^6.23.0", "babel": "^6.23.0",
"babel-core": "^6.26.3", "babel-core": "^6.26.3",
"babel-loader": "^8.0.6", "babel-loader": "^8.0.6",
@@ -31,6 +32,7 @@
"@types/jquery": "^3.3.31", "@types/jquery": "^3.3.31",
"@typescript-eslint/eslint-plugin": "^4.9.1", "@typescript-eslint/eslint-plugin": "^4.9.1",
"@typescript-eslint/parser": "^4.9.1", "@typescript-eslint/parser": "^4.9.1",
"chromedriver": "^92.0.0",
"copy-webpack-plugin": "^6.0.3", "copy-webpack-plugin": "^6.0.3",
"eslint": "^7.15.0", "eslint": "^7.15.0",
"eslint-plugin-react": "^7.21.5", "eslint-plugin-react": "^7.21.5",
@@ -44,6 +46,7 @@
======= =======
"jest": "^27.0.6", "jest": "^27.0.6",
"rimraf": "^3.0.0", "rimraf": "^3.0.0",
"selenium-webdriver": "^4.0.0-beta.4",
"ts-jest": "^27.0.3", "ts-jest": "^27.0.3",
"ts-loader": "^6.2.1", "ts-loader": "^6.2.1",
"typescript": "~4.3", "typescript": "~4.3",
@@ -22025,6 +22028,12 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/@testim/chrome-version": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.0.7.tgz",
"integrity": "sha512-8UT/J+xqCYfn3fKtOznAibsHpiuDshCb0fwgWxRazTT19Igp9ovoXMPhXyLD6m3CKQGTMHgqoxaFfMWaL40Rnw==",
"dev": true
},
"node_modules/@tootallnate/once": { "node_modules/@tootallnate/once": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
@@ -22235,6 +22244,11 @@
"@types/react": "*" "@types/react": "*"
} }
}, },
"node_modules/@types/selenium-webdriver": {
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-4.0.15.tgz",
"integrity": "sha512-5760PIZkzhPejy3hsKAdCKe5LJygGdxLKOLxmZL9GEUcFlO5OgzM6G2EbdbvOnaw4xvUSa9Uip6Ipwkih12BPA=="
},
"node_modules/@types/sizzle": { "node_modules/@types/sizzle": {
"version": "2.3.2", "version": "2.3.2",
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz",
@@ -23564,6 +23578,15 @@
"integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==", "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==",
"dev": true "dev": true
}, },
"node_modules/axios": {
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
"dev": true,
"dependencies": {
"follow-redirects": "^1.10.0"
}
},
"node_modules/babel": { "node_modules/babel": {
"version": "6.23.0", "version": "6.23.0",
"resolved": "https://registry.npmjs.org/babel/-/babel-6.23.0.tgz", "resolved": "https://registry.npmjs.org/babel/-/babel-6.23.0.tgz",
@@ -25415,6 +25438,28 @@
"node": ">=6.0" "node": ">=6.0"
} }
}, },
"node_modules/chromedriver": {
"version": "92.0.0",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-92.0.0.tgz",
"integrity": "sha512-IdJ5n5jLL6tCsGQF/fQHF2gDEhVzoYIqktUn6hE/BSsXlCcyDTi45fQbhTEhZlmshM8+BpnRtPuIT5DRbxNqKg==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
"@testim/chrome-version": "^1.0.7",
"axios": "^0.21.1",
"del": "^6.0.0",
"extract-zip": "^2.0.1",
"https-proxy-agent": "^5.0.0",
"proxy-from-env": "^1.1.0",
"tcp-port-used": "^1.0.1"
},
"bin": {
"chromedriver": "bin/chromedriver"
},
"engines": {
"node": ">=10"
}
},
"node_modules/ci-info": { "node_modules/ci-info": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
@@ -26176,21 +26221,6 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/copy-webpack-plugin/node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"dependencies": {
"glob": "^7.1.3"
},
"bin": {
"rimraf": "bin.js"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/copy-webpack-plugin/node_modules/schema-utils": { "node_modules/copy-webpack-plugin/node_modules/schema-utils": {
"version": "2.7.0", "version": "2.7.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
@@ -26425,12 +26455,19 @@
"dev": true "dev": true
}, },
"node_modules/debug": { "node_modules/debug": {
"version": "4.1.1", "version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
"dependencies": { "dependencies": {
"ms": "^2.1.1" "ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
} }
}, },
"node_modules/decamelize": { "node_modules/decamelize": {
@@ -26777,6 +26814,37 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/del": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz",
"integrity": "sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==",
"dev": true,
"dependencies": {
"globby": "^11.0.1",
"graceful-fs": "^4.2.4",
"is-glob": "^4.0.1",
"is-path-cwd": "^2.2.0",
"is-path-inside": "^3.0.2",
"p-map": "^4.0.0",
"rimraf": "^3.0.2",
"slash": "^3.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/del/node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/delayed-stream": { "node_modules/delayed-stream": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -28330,6 +28398,41 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/extract-zip": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
"integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
"dev": true,
"dependencies": {
"debug": "^4.1.1",
"get-stream": "^5.1.0",
"yauzl": "^2.10.0"
},
"bin": {
"extract-zip": "cli.js"
},
"engines": {
"node": ">= 10.17.0"
},
"optionalDependencies": {
"@types/yauzl": "^2.9.1"
}
},
"node_modules/extract-zip/node_modules/get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"dev": true,
"dependencies": {
"pump": "^3.0.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/extsprintf": { "node_modules/extsprintf": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
@@ -28719,21 +28822,6 @@
"node": "^10.12.0 || >=12.0.0" "node": "^10.12.0 || >=12.0.0"
} }
}, },
"node_modules/flat-cache/node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"dependencies": {
"glob": "^7.1.3"
},
"bin": {
"rimraf": "bin.js"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/flatstr": { "node_modules/flatstr": {
"version": "1.0.12", "version": "1.0.12",
"resolved": "https://registry.npmjs.org/flatstr/-/flatstr-1.0.12.tgz", "resolved": "https://registry.npmjs.org/flatstr/-/flatstr-1.0.12.tgz",
@@ -28764,6 +28852,26 @@
"readable-stream": "^2.3.6" "readable-stream": "^2.3.6"
} }
}, },
"node_modules/follow-redirects": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==",
"dev": true,
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/for-in": { "node_modules/for-in": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@@ -29768,6 +29876,15 @@
"url": "https://github.com/sindresorhus/invert-kv?sponsor=1" "url": "https://github.com/sindresorhus/invert-kv?sponsor=1"
} }
}, },
"node_modules/ip-regex": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz",
"integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/ipaddr.js": { "node_modules/ipaddr.js": {
"version": "1.9.1", "version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@@ -30106,6 +30223,15 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/is-path-cwd": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
"integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/is-path-inside": { "node_modules/is-path-inside": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
@@ -30218,6 +30344,12 @@
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
"dev": true "dev": true
}, },
"node_modules/is-url": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
"integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==",
"dev": true
},
"node_modules/is-utf8": { "node_modules/is-utf8": {
"version": "0.2.1", "version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
@@ -30250,6 +30382,20 @@
"integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
"dev": true "dev": true
}, },
"node_modules/is2": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/is2/-/is2-2.0.7.tgz",
"integrity": "sha512-4vBQoURAXC6hnLFxD4VW7uc04XiwTTl/8ydYJxKvPwkWQrSjInkuM5VZVg6BGr1/natq69zDuvO9lGpLClJqvA==",
"dev": true,
"dependencies": {
"deep-is": "^0.1.3",
"ip-regex": "^4.1.0",
"is-url": "^1.2.4"
},
"engines": {
"node": ">=v0.10.0"
}
},
"node_modules/isarray": { "node_modules/isarray": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@@ -36718,6 +36864,12 @@
"node": ">= 0.10" "node": ">= 0.10"
} }
}, },
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"dev": true
},
"node_modules/prr": { "node_modules/prr": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
@@ -37332,9 +37484,9 @@
} }
}, },
"node_modules/rimraf": { "node_modules/rimraf": {
"version": "3.0.1", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.1.tgz", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-IQ4ikL8SjBiEDZfk+DFVwqRK8md24RWMEJkdSlgNLkyyAImcjf8SWvU1qFMDOb4igBClbTQ/ugPqXcRwdFTxZw==", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"glob": "^7.1.3" "glob": "^7.1.3"
@@ -37470,6 +37622,21 @@
"seek-table": "bin/seek-bzip-table" "seek-table": "bin/seek-bzip-table"
} }
}, },
"node_modules/selenium-webdriver": {
"version": "4.0.0-beta.4",
"resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.0.0-beta.4.tgz",
"integrity": "sha512-+s/CIYkWzmnC9WASBxxVj7Lm0dcyl6OaFxwIJaFCT5WCuACiimEEr4lUnOOFP/QlKfkDQ56m+aRczaq2EvJEJg==",
"dev": true,
"dependencies": {
"jszip": "^3.6.0",
"rimraf": "^3.0.2",
"tmp": "^0.2.1",
"ws": ">=7.4.6"
},
"engines": {
"node": ">= 10.15.0"
}
},
"node_modules/semver": { "node_modules/semver": {
"version": "6.3.0", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
@@ -38735,6 +38902,16 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true "dev": true
}, },
"node_modules/tcp-port-used": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz",
"integrity": "sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==",
"dev": true,
"dependencies": {
"debug": "4.3.1",
"is2": "^2.0.6"
}
},
"node_modules/terminal-link": { "node_modules/terminal-link": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
@@ -42228,6 +42405,12 @@
"defer-to-connect": "^1.0.1" "defer-to-connect": "^1.0.1"
} }
}, },
"@testim/chrome-version": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.0.7.tgz",
"integrity": "sha512-8UT/J+xqCYfn3fKtOznAibsHpiuDshCb0fwgWxRazTT19Igp9ovoXMPhXyLD6m3CKQGTMHgqoxaFfMWaL40Rnw==",
"dev": true
},
"@tootallnate/once": { "@tootallnate/once": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
@@ -42435,6 +42618,11 @@
"@types/react": "*" "@types/react": "*"
} }
}, },
"@types/selenium-webdriver": {
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-4.0.15.tgz",
"integrity": "sha512-5760PIZkzhPejy3hsKAdCKe5LJygGdxLKOLxmZL9GEUcFlO5OgzM6G2EbdbvOnaw4xvUSa9Uip6Ipwkih12BPA=="
},
"@types/sizzle": { "@types/sizzle": {
"version": "2.3.2", "version": "2.3.2",
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz",
@@ -43475,6 +43663,15 @@
"integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==", "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==",
"dev": true "dev": true
}, },
"axios": {
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
"dev": true,
"requires": {
"follow-redirects": "^1.10.0"
}
},
"babel": { "babel": {
"version": "6.23.0", "version": "6.23.0",
"resolved": "https://registry.npmjs.org/babel/-/babel-6.23.0.tgz", "resolved": "https://registry.npmjs.org/babel/-/babel-6.23.0.tgz",
@@ -45084,6 +45281,21 @@
"tslib": "^1.9.0" "tslib": "^1.9.0"
} }
}, },
"chromedriver": {
"version": "92.0.0",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-92.0.0.tgz",
"integrity": "sha512-IdJ5n5jLL6tCsGQF/fQHF2gDEhVzoYIqktUn6hE/BSsXlCcyDTi45fQbhTEhZlmshM8+BpnRtPuIT5DRbxNqKg==",
"dev": true,
"requires": {
"@testim/chrome-version": "^1.0.7",
"axios": "^0.21.1",
"del": "^6.0.0",
"extract-zip": "^2.0.1",
"https-proxy-agent": "^5.0.0",
"proxy-from-env": "^1.1.0",
"tcp-port-used": "^1.0.1"
}
},
"ci-info": { "ci-info": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
@@ -45693,15 +45905,6 @@
"find-up": "^4.0.0" "find-up": "^4.0.0"
} }
}, },
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
},
"schema-utils": { "schema-utils": {
"version": "2.7.0", "version": "2.7.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
@@ -45903,11 +46106,11 @@
"dev": true "dev": true
}, },
"debug": { "debug": {
"version": "4.1.1", "version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"requires": { "requires": {
"ms": "^2.1.1" "ms": "2.1.2"
} }
}, },
"decamelize": { "decamelize": {
@@ -46193,6 +46396,30 @@
} }
} }
}, },
"del": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz",
"integrity": "sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==",
"dev": true,
"requires": {
"globby": "^11.0.1",
"graceful-fs": "^4.2.4",
"is-glob": "^4.0.1",
"is-path-cwd": "^2.2.0",
"is-path-inside": "^3.0.2",
"p-map": "^4.0.0",
"rimraf": "^3.0.2",
"slash": "^3.0.0"
},
"dependencies": {
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true
}
}
},
"delayed-stream": { "delayed-stream": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -47399,6 +47626,29 @@
} }
} }
}, },
"extract-zip": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
"integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
"dev": true,
"requires": {
"@types/yauzl": "^2.9.1",
"debug": "^4.1.1",
"get-stream": "^5.1.0",
"yauzl": "^2.10.0"
},
"dependencies": {
"get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
}
}
},
"extsprintf": { "extsprintf": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
@@ -47721,17 +47971,6 @@
"requires": { "requires": {
"flatted": "^3.1.0", "flatted": "^3.1.0",
"rimraf": "^3.0.2" "rimraf": "^3.0.2"
},
"dependencies": {
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
}
} }
}, },
"flatstr": { "flatstr": {
@@ -47761,6 +48000,12 @@
"readable-stream": "^2.3.6" "readable-stream": "^2.3.6"
} }
}, },
"follow-redirects": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==",
"dev": true
},
"for-in": { "for-in": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@@ -48546,6 +48791,12 @@
"integrity": "sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==", "integrity": "sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==",
"dev": true "dev": true
}, },
"ip-regex": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz",
"integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==",
"dev": true
},
"ipaddr.js": { "ipaddr.js": {
"version": "1.9.1", "version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@@ -48781,6 +49032,12 @@
"dev": true, "dev": true,
"peer": true "peer": true
}, },
"is-path-cwd": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
"integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
"dev": true
},
"is-path-inside": { "is-path-inside": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
@@ -48857,6 +49114,12 @@
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
"dev": true "dev": true
}, },
"is-url": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
"integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==",
"dev": true
},
"is-utf8": { "is-utf8": {
"version": "0.2.1", "version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
@@ -48883,6 +49146,17 @@
"integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
"dev": true "dev": true
}, },
"is2": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/is2/-/is2-2.0.7.tgz",
"integrity": "sha512-4vBQoURAXC6hnLFxD4VW7uc04XiwTTl/8ydYJxKvPwkWQrSjInkuM5VZVg6BGr1/natq69zDuvO9lGpLClJqvA==",
"dev": true,
"requires": {
"deep-is": "^0.1.3",
"ip-regex": "^4.1.0",
"is-url": "^1.2.4"
}
},
"isarray": { "isarray": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@@ -53936,6 +54210,12 @@
"ipaddr.js": "1.9.1" "ipaddr.js": "1.9.1"
} }
}, },
"proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"dev": true
},
"prr": { "prr": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
@@ -54438,9 +54718,9 @@
"dev": true "dev": true
}, },
"rimraf": { "rimraf": {
"version": "3.0.1", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.1.tgz", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-IQ4ikL8SjBiEDZfk+DFVwqRK8md24RWMEJkdSlgNLkyyAImcjf8SWvU1qFMDOb4igBClbTQ/ugPqXcRwdFTxZw==", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true, "dev": true,
"requires": { "requires": {
"glob": "^7.1.3" "glob": "^7.1.3"
@@ -54557,6 +54837,18 @@
"commander": "^2.8.1" "commander": "^2.8.1"
} }
}, },
"selenium-webdriver": {
"version": "4.0.0-beta.4",
"resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.0.0-beta.4.tgz",
"integrity": "sha512-+s/CIYkWzmnC9WASBxxVj7Lm0dcyl6OaFxwIJaFCT5WCuACiimEEr4lUnOOFP/QlKfkDQ56m+aRczaq2EvJEJg==",
"dev": true,
"requires": {
"jszip": "^3.6.0",
"rimraf": "^3.0.2",
"tmp": "^0.2.1",
"ws": ">=7.4.6"
}
},
"semver": { "semver": {
"version": "6.3.0", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
@@ -55597,6 +55889,16 @@
"xtend": "^4.0.0" "xtend": "^4.0.0"
} }
}, },
"tcp-port-used": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz",
"integrity": "sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==",
"dev": true,
"requires": {
"debug": "4.3.1",
"is2": "^2.0.6"
}
},
"terminal-link": { "terminal-link": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",

View File

@@ -6,6 +6,7 @@
"dependencies": { "dependencies": {
"@types/react": "^16.9.22", "@types/react": "^16.9.22",
"@types/react-dom": "^16.9.5", "@types/react-dom": "^16.9.5",
"@types/selenium-webdriver": "^4.0.15",
"babel": "^6.23.0", "babel": "^6.23.0",
"babel-core": "^6.26.3", "babel-core": "^6.26.3",
"babel-loader": "^8.0.6", "babel-loader": "^8.0.6",
@@ -21,11 +22,13 @@
"@types/jquery": "^3.3.31", "@types/jquery": "^3.3.31",
"@typescript-eslint/eslint-plugin": "^4.9.1", "@typescript-eslint/eslint-plugin": "^4.9.1",
"@typescript-eslint/parser": "^4.9.1", "@typescript-eslint/parser": "^4.9.1",
"chromedriver": "^92.0.0",
"copy-webpack-plugin": "^6.0.3", "copy-webpack-plugin": "^6.0.3",
"eslint": "^7.15.0", "eslint": "^7.15.0",
"eslint-plugin-react": "^7.21.5", "eslint-plugin-react": "^7.21.5",
"jest": "^27.0.6", "jest": "^27.0.6",
"rimraf": "^3.0.0", "rimraf": "^3.0.0",
"selenium-webdriver": "^4.0.0-beta.4",
"ts-jest": "^27.0.3", "ts-jest": "^27.0.3",
"ts-loader": "^6.2.1", "ts-loader": "^6.2.1",
"typescript": "~4.3", "typescript": "~4.3",
@@ -53,7 +56,8 @@
"dev:firefox": "npm run build:dev:firefox && concurrently \"npm run web-run:firefox\" \"npm run build:watch:firefox\"", "dev:firefox": "npm run build:dev:firefox && concurrently \"npm run web-run:firefox\" \"npm run build:watch:firefox\"",
"dev:firefox-android": "npm run build:dev:firefox && concurrently \"npm run web-run:firefox-android\" \"npm run build:watch:firefox\"", "dev:firefox-android": "npm run build:dev:firefox && concurrently \"npm run web-run:firefox-android\" \"npm run build:watch:firefox\"",
"clean": "rimraf dist", "clean": "rimraf dist",
"test": "npx jest", "test": "npm run build:chrome && npx jest",
"test-without-building": "npx jest",
"lint": "eslint src", "lint": "eslint src",
"lint:fix": "eslint src --fix" "lint:fix": "eslint src --fix"
}, },

View File

@@ -57,5 +57,35 @@
}, },
"manualPaused": { "manualPaused": {
"message": "تم إيقاف الموقت" "message": "تم إيقاف الموقت"
},
"confirmMSG": {
"message": "لتحرير أو حذف قيّم فردياً، انقر فوق زر المعلومات أو فتح الإضافة عن طريق النقر على أيقونة الإضافة في الزاوية اليمنى العليا."
},
"clearThis": {
"message": "هل أنت متأكد أنك تريد حذف هذا؟\n\n"
},
"Unknown": {
"message": "حدث خطأ في إرسال توقيت الرعاة الخاص بك، الرجاء المحاولة مرة أخرى لاحقاً."
},
"sponsorFound": {
"message": "يحتوي هذا الفيديو على أجزاء في قاعدة البيانات!"
},
"sponsor404": {
"message": "لم يتم العثور على أجزاء"
},
"sponsorStart": {
"message": "يبدأ الجزء الآن"
},
"sponsorEnd": {
"message": "ينتهي الجزء الآن"
},
"sponsorCancel": {
"message": "إلغاء إنشاء جزء"
},
"noVideoID": {
"message": "لم يتم العثور على فيديو يوتيوب.\nإذا كان هذا غير صحيح، قم بتحديث الصفحة."
},
"refreshSegments": {
"message": "تحديث الأجزاء"
} }
} }

View File

@@ -52,6 +52,9 @@
"reskip": { "reskip": {
"message": "Пропускане отново" "message": "Пропускане отново"
}, },
"unmute": {
"message": "Вкл. на звука"
},
"paused": { "paused": {
"message": "На пауза" "message": "На пауза"
}, },
@@ -161,6 +164,9 @@
"setUsername": { "setUsername": {
"message": "Задайте потребителско име" "message": "Задайте потребителско име"
}, },
"copyPublicID": {
"message": "Копиране на публичния UserID"
},
"discordAdvert": { "discordAdvert": {
"message": "Елате в официалния Discord сървър, за да давате предложения!" "message": "Елате в официалния Discord сървър, за да давате предложения!"
}, },
@@ -299,6 +305,9 @@
"skip": { "skip": {
"message": "Пропускане" "message": "Пропускане"
}, },
"mute": {
"message": "Заглушаване"
},
"skip_category": { "skip_category": {
"message": "Пропускане на {0}?" "message": "Пропускане на {0}?"
}, },
@@ -363,7 +372,7 @@
"message": "Импортиране/експортиране на вашия UserID" "message": "Импортиране/експортиране на вашия UserID"
}, },
"whatChangeUserID": { "whatChangeUserID": {
"message": "Това трябва да се пази тайно. То е като парола и не трябва да се споделя с никого. Ако някой го притежава, той може да се представи за вас." "message": "Това трябва да се пази в тайна. То е като парола и не трябва да се споделя с никого. Ако някой го има, може да се представи за вас. Ако търсите своя публичен потребителски идентификатор, щракнете върху иконата на клипборда в изскачащия прозорец."
}, },
"setUserID": { "setUserID": {
"message": "Задаване на UserID" "message": "Задаване на UserID"
@@ -601,6 +610,9 @@
"autoSkipOnMusicVideos": { "autoSkipOnMusicVideos": {
"message": "Автоматично пропускане на всички сегменти, когато има сегмент без музика" "message": "Автоматично пропускане на всички сегменти, когато има сегмент без музика"
}, },
"muteSegments": {
"message": "Разрешаване на сегменти, които заглушават звука, вместо да се пропускат"
},
"colorFormatIncorrect": { "colorFormatIncorrect": {
"message": "Вашият цвят не е форматиран правилно. Трябва да бъде 3- или 6-цифрен шестнадесетичен код с „#“ в началото." "message": "Вашият цвят не е форматиран правилно. Трябва да бъде 3- или 6-цифрен шестнадесетичен код с „#“ в началото."
}, },

View File

@@ -52,6 +52,9 @@
"reskip": { "reskip": {
"message": "Znovu přeskočit" "message": "Znovu přeskočit"
}, },
"unmute": {
"message": "Zrušit ztlumení"
},
"paused": { "paused": {
"message": "Pozastaveno" "message": "Pozastaveno"
}, },
@@ -161,6 +164,9 @@
"setUsername": { "setUsername": {
"message": "Nastavit uživatelské jméno" "message": "Nastavit uživatelské jméno"
}, },
"copyPublicID": {
"message": "Kopírovat veřejné uživatelské ID"
},
"discordAdvert": { "discordAdvert": {
"message": "Připojte se k oficiálnímu Discord serveru k podání návrhů a zpětné vazby!" "message": "Připojte se k oficiálnímu Discord serveru k podání návrhů a zpětné vazby!"
}, },
@@ -299,6 +305,9 @@
"skip": { "skip": {
"message": "Přeskočit" "message": "Přeskočit"
}, },
"mute": {
"message": "Ztlumit"
},
"skip_category": { "skip_category": {
"message": "Přeskočit {0}?" "message": "Přeskočit {0}?"
}, },
@@ -363,7 +372,7 @@
"message": "Importovat / exportovat vaše UserID" "message": "Importovat / exportovat vaše UserID"
}, },
"whatChangeUserID": { "whatChangeUserID": {
"message": "Toto byste měli udržet v soukromí. Je to jako heslo a neměli byste jej s nikým sdílet. Pokud jej někdo má, může se za vás vydávat." "message": "Toto by mělo být ponecháno v soukromí. Je to jako heslo a nemělo by být s nikým sdíleno. Pokud to někdo má, může se za vás vydávat. Pokud hledáte vaše veřejné uživatelské ID, klikněte na ikonu schránky ve vyskakovacím okně."
}, },
"setUserID": { "setUserID": {
"message": "Nastavit UserID" "message": "Nastavit UserID"
@@ -601,6 +610,9 @@
"autoSkipOnMusicVideos": { "autoSkipOnMusicVideos": {
"message": "Automaticky přeskočit všechny segmenty, když je ve videu nehudební segment" "message": "Automaticky přeskočit všechny segmenty, když je ve videu nehudební segment"
}, },
"muteSegments": {
"message": "Povolit segmenty, které místo přeskočení ztlumují zvuk"
},
"colorFormatIncorrect": { "colorFormatIncorrect": {
"message": "Vaše barva má nesprávný formát. Měl by to být 3 nebo 6 znaků dlouhý HEX kód s křížkem na začátku." "message": "Vaše barva má nesprávný formát. Měl by to být 3 nebo 6 znaků dlouhý HEX kód s křížkem na začátku."
}, },

View File

@@ -32,7 +32,7 @@
"message": "Melden" "message": "Melden"
}, },
"reportButtonInfo": { "reportButtonInfo": {
"message": "Diesen Beitrag als falsch melden." "message": "Beitrag als unzulässig melden."
}, },
"Dismiss": { "Dismiss": {
"message": "Abbrechen" "message": "Abbrechen"
@@ -52,6 +52,9 @@
"reskip": { "reskip": {
"message": "Nochmal überspringen" "message": "Nochmal überspringen"
}, },
"unmute": {
"message": "Ton an"
},
"paused": { "paused": {
"message": "Pausiert" "message": "Pausiert"
}, },
@@ -86,7 +89,7 @@
"message": "Kein YouTube-Video gefunden.\nWenn dies falsch ist, aktualisiere den Tab." "message": "Kein YouTube-Video gefunden.\nWenn dies falsch ist, aktualisiere den Tab."
}, },
"refreshSegments": { "refreshSegments": {
"message": "Segment aktualisieren" "message": "Segmente aktualisieren"
}, },
"success": { "success": {
"message": "Geschafft!" "message": "Geschafft!"
@@ -161,6 +164,9 @@
"setUsername": { "setUsername": {
"message": "Benutzernamen festlegen" "message": "Benutzernamen festlegen"
}, },
"copyPublicID": {
"message": "Öffentliche Benutzer-ID kopieren"
},
"discordAdvert": { "discordAdvert": {
"message": "Tritt dem offiziellen Discord-Server bei und teile Anregungen und Feedback!" "message": "Tritt dem offiziellen Discord-Server bei und teile Anregungen und Feedback!"
}, },
@@ -227,6 +233,21 @@
"showSkipNotice": { "showSkipNotice": {
"message": "Zeige Pop-up nach dem Überspringen eines Segments" "message": "Zeige Pop-up nach dem Überspringen eines Segments"
}, },
"noticeVisibilityMode0": {
"message": "Skip-Meldung in voller größe"
},
"noticeVisibilityMode1": {
"message": "Kleine Skip-Meldung für Auto-Skips"
},
"noticeVisibilityMode2": {
"message": "Alles kleine Skip-Meldungen"
},
"noticeVisibilityMode3": {
"message": "Verblasste Skip-Meldung für Auto-Skip"
},
"noticeVisibilityMode4": {
"message": "Alles verblasste Skip-Meldungen"
},
"longDescription": { "longDescription": {
"message": "SponsorBlock lässt dich gesponserte Videosegmente, Intros, Outros, Interaktions-Erinnerungen, Musikvideoteile ohne Musik und andere nervige Teile von YouTube-Videos überspringen. SponsorBlock ist eine crowdsourced Browser-Erweiterung, in der jeder die Start- und Endzeit gesponserter Videosegmente und anderer Segmente von YouTube-Videos einreicht. Sobald eine Person diese Informationen einreicht, überspringen alle anderen mit dieser Erweiterung das gesponserte Segment.", "message": "SponsorBlock lässt dich gesponserte Videosegmente, Intros, Outros, Interaktions-Erinnerungen, Musikvideoteile ohne Musik und andere nervige Teile von YouTube-Videos überspringen. SponsorBlock ist eine crowdsourced Browser-Erweiterung, in der jeder die Start- und Endzeit gesponserter Videosegmente und anderer Segmente von YouTube-Videos einreicht. Sobald eine Person diese Informationen einreicht, überspringen alle anderen mit dieser Erweiterung das gesponserte Segment.",
"description": "Full description of the extension on the store pages." "description": "Full description of the extension on the store pages."
@@ -262,6 +283,7 @@
"keybindDescriptionComplete": { "keybindDescriptionComplete": {
"message": "Die Taste wurde festgelegt auf: " "message": "Die Taste wurde festgelegt auf: "
}, },
"0": { "0": {
"message": "Zeitüberschreibung. Überprüfe deine Internetverbindung. Bist du mit dem Internet verbunden, ist der Server wahrscheinlich offline." "message": "Zeitüberschreibung. Überprüfe deine Internetverbindung. Bist du mit dem Internet verbunden, ist der Server wahrscheinlich offline."
}, },
@@ -284,6 +306,9 @@
"skip": { "skip": {
"message": "Überspringen" "message": "Überspringen"
}, },
"mute": {
"message": "Ton aus"
},
"skip_category": { "skip_category": {
"message": "{0} überspringen?" "message": "{0} überspringen?"
}, },
@@ -348,7 +373,7 @@
"message": "Benutzer-ID importieren/exportieren" "message": "Benutzer-ID importieren/exportieren"
}, },
"whatChangeUserID": { "whatChangeUserID": {
"message": "Halte diese ID geheim. Sie ist dazu in der Lage dich eindeutig zu identifizieren und sollte mit niemanden geteilt werden." "message": "Dies sollte geheim gehalten werden. Dies ist wie ein Passwort und sollte mit niemandem geteilt werden. Sollte es jemand haben, könnte er sich als dich ausgeben. Wenn du nach deiner öffentlichen Benutzer-ID suchst, klicke das \"Kopieren\"-Symbol bei deinem Benutzernamen im Popup."
}, },
"setUserID": { "setUserID": {
"message": "Interne Benutzer-ID festlegen" "message": "Interne Benutzer-ID festlegen"
@@ -469,7 +494,7 @@
"message": "Vorschau" "message": "Vorschau"
}, },
"unsubmitted": { "unsubmitted": {
"message": "Nicht eingereicht" "message": "Nicht übermittelt"
}, },
"inspect": { "inspect": {
"message": "Überprüfen" "message": "Überprüfen"
@@ -577,12 +602,18 @@
"autoSkip_POI": { "autoSkip_POI": {
"message": "Automatisch zum Start springen" "message": "Automatisch zum Start springen"
}, },
"manualSkip_POI": {
"message": "Beim Laden des Videos fragen"
},
"showOverlay_POI": { "showOverlay_POI": {
"message": "In der Video-Zeitleiste anzeigen" "message": "In Suchleiste anzeigen"
}, },
"autoSkipOnMusicVideos": { "autoSkipOnMusicVideos": {
"message": "Alle Segmente automatisch überspringen, wenn ein nicht-Musiksegment vorhanden ist" "message": "Alle Segmente automatisch überspringen, wenn ein nicht-Musiksegment vorhanden ist"
}, },
"muteSegments": {
"message": "Segmente zulassen, die den Ton ausschalten anstatt zu überspringen"
},
"colorFormatIncorrect": { "colorFormatIncorrect": {
"message": "Die Farbe ist falsch formatiert. Sie sollte ein 3-6-stelliger Hex-Code mit einer Raute am Anfang sein." "message": "Die Farbe ist falsch formatiert. Sie sollte ein 3-6-stelliger Hex-Code mit einer Raute am Anfang sein."
}, },
@@ -693,18 +724,91 @@
"help": { "help": {
"message": "Hilfe" "message": "Hilfe"
}, },
"GotIt": {
"message": "Verstanden",
"description": "Used as the button to dismiss a tooltip"
},
"experiementOptOut": { "experiementOptOut": {
"message": "Abmeldung aller zukünftigen Experimente", "message": "Aus allen zukünftigen Experimenten abmelden",
"description": "This is used in a popup about a new experiment to get a list of unlisted videos to back up since all unlisted videos uploaded before 2017 will be set to private." "description": "This is used in a popup about a new experiment to get a list of unlisted videos to back up since all unlisted videos uploaded before 2017 will be set to private."
}, },
"hideForever": { "hideForever": {
"message": "Dauerhaft verbergen" "message": "Dauerhaft verbergen"
}, },
"warningChatInfo": { "warningChatInfo": {
"message": "Du wurdest ermahnt und kannst zur Zeit keine Segmente einreichen. Uns ist nämlich aufgefallen, dass du ein paar gängige Fehler machst, die nicht bösartig sind. Um die Regeln klarzustellen laden wir dich zu einem kurzem Gespräch auf discord.gg/SponsorBlock oder matrix.to/#/#sponsor:ajay.app ein" "message": "Du wurdest verwarnt und kannst vorrübergehend keine Segmente einreichen. Es ist uns aufgefallen, dass du gängige Fehler machst, welche nicht schädlich sind, und wir wollen dir nur die Regeln klar machen. Du kannst auch dem Chat durch discord.gg/SponsorBlock oder matrix.to/#/#sponsor:ajay.app beitreten"
}, },
"voteRejectedWarning": { "voteRejectedWarning": {
"message": "Abstimmung wegen einer Warnung abgelehnt. Um über sie zu reden, klicke hier, oder schreibe uns später.", "message": "Abstimmung wegen einer Warnung abgelehnt. Klicke hier um einen Chat zu öffnen, oder versuch es später erneut, wenn du Zeit hast.",
"description": "This is an integrated chat panel that will appearing allowing them to talk to the Discord/Matrix chat without leaving their browser." "description": "This is an integrated chat panel that will appearing allowing them to talk to the Discord/Matrix chat without leaving their browser."
},
"Donate": {
"message": "Spenden"
},
"hideDonationLink": {
"message": "Verstecke Spendenlink"
},
"helpPageThanksForInstalling": {
"message": "Danke fürs installieren von SponsorBlock."
},
"helpPageReviewOptions": {
"message": "Bitte überprüfe die unten stehenden Optionen"
},
"helpPageFeatureDisclaimer": {
"message": "Viele Funktionen sind standardmäßig deaktiviert. Wenn du Intros und Outtros überspringen willst, Invidious verwenden willst, usw. aktiviere sie unten. Du kannst auch UI-Elemente verstecken/anzeigen."
},
"helpPageHowSkippingWorks": {
"message": "Wie überspringen funktioniert"
},
"helpPageHowSkippingWorks1": {
"message": "Videosegmente werden automatisch übersprungen, wenn sie in der Datenbank gefunden werden. Du kannst das Popup öffnen, indem du auf das Erweiterungssymbol klickst, um eine Vorschau darüber zu erhalten, was diese sind."
},
"helpPageHowSkippingWorks2": {
"message": "Wannimmer du ein Segment überspringst, wirst du benachrichtigt. Wenn das Timing falsch erscheint, kannst du as durch klicken auf den Downvote button downvoten! Du kannst auch im Popup voten."
},
"Submitting": {
"message": "Übermitteln"
},
"helpPageSubmitting1": {
"message": "Das übermitteln kann entweder im Popup durch das drücken vom \"Segment Started Jetzt\" Knopf oder im Videoplayer mit den Knöpfen im Player gemacht werden."
},
"helpPageSubmitting2": {
"message": "Mit einem Klick auf den Play-Knopf wird der Beginn eines Segments und mit dem klick auf den Stop-Knopf das ende eines Segments markiert. Du kannst mehrere Sponsoren vorbereiten, bevor du auf Absenden klickst. Das klicken des Upload-Knopfes wird die Segmente übermitteln. Das klicken des Mülleimers löscht es."
},
"Editing": {
"message": "Bearbeitung"
},
"helpPageEditing1": {
"message": "Wenn du etwas falsch gemacht hast, kannst du ein Segment bearbeiten oder löschen nachdem du auf den Auf-Pfeil Knopf gedrückt hast."
},
"helpPageTooSlow": {
"message": "Das ist zu langsam"
},
"helpPageTooSlow1": {
"message": "Es gibt Hotkeys, wenn du diese verwenden möchtest. Drücke die Semikolon-Taste um den Anfang/das Ende eines Sponsor-Segments zu markieren und die Abostrophe-Taste um es zu übermitteln. Diese können in den Optionen geändert werden. Wenn du keine QWERTY-Tastatur verwendest, solltest du eventuell die Keybinds ändern."
},
"helpPageCopyOfDatabase": {
"message": "Kann ich eine kopie der Datenbank erhalten? Was passiert wenn du verschwindest?"
},
"helpPageCopyOfDatabase1": {
"message": "Die Datenbank ist öffentlich und verfügbar unter"
},
"helpPageCopyOfDatabase2": {
"message": "Der Quellcode ist frei verfügbar. Selbst wenn mir etwas passieren würde wären deine Übermittlungen nicht verloren."
},
"helpPageNews": {
"message": "Nachrichten und wie es gemacht wird"
},
"helpPageSourceCode": {
"message": "Wo kann ich den Quellcode kriegen?"
},
"Credits": {
"message": "Credits"
},
"highlightNewFeature": {
"message": "Neu! Gehe mit einem Klick zum Punkt des Videos mit der neuen \"Hervorheben\" Kategorie"
},
"LearnMore": {
"message": "Erfahre mehr"
} }
} }

View File

@@ -52,6 +52,9 @@
"reskip": { "reskip": {
"message": "Reskip" "message": "Reskip"
}, },
"unmute": {
"message": "Unmute"
},
"paused": { "paused": {
"message": "Paused" "message": "Paused"
}, },
@@ -161,6 +164,9 @@
"setUsername": { "setUsername": {
"message": "Set Username" "message": "Set Username"
}, },
"copyPublicID": {
"message": "Copy Public UserID"
},
"discordAdvert": { "discordAdvert": {
"message": "Come join the official discord server to give suggestions and feedback!" "message": "Come join the official discord server to give suggestions and feedback!"
}, },
@@ -299,6 +305,9 @@
"skip": { "skip": {
"message": "Skip" "message": "Skip"
}, },
"mute": {
"message": "Mute"
},
"skip_category": { "skip_category": {
"message": "Skip {0}?" "message": "Skip {0}?"
}, },
@@ -363,7 +372,7 @@
"message": "Import/Export Your UserID" "message": "Import/Export Your UserID"
}, },
"whatChangeUserID": { "whatChangeUserID": {
"message": "This should be kept private. This is like a password and should not be shared with anyone. If someone has this, they can impersonate you." "message": "This should be kept private. This is like a password and should not be shared with anyone. If someone has this, they can impersonate you. If you are looking for your public userID, click the clipboard icon in the popup."
}, },
"setUserID": { "setUserID": {
"message": "Set UserID" "message": "Set UserID"
@@ -601,6 +610,9 @@
"autoSkipOnMusicVideos": { "autoSkipOnMusicVideos": {
"message": "Auto skip all segments when there is a non-music segment" "message": "Auto skip all segments when there is a non-music segment"
}, },
"muteSegments": {
"message": "Allow segments that mute audio instead of skip"
},
"colorFormatIncorrect": { "colorFormatIncorrect": {
"message": "Your color is formatted incorrectly. It should be a 3 or 6 digit hex code with a number sign at the beginning." "message": "Your color is formatted incorrectly. It should be a 3 or 6 digit hex code with a number sign at the beginning."
}, },

View File

@@ -161,6 +161,9 @@
"setUsername": { "setUsername": {
"message": "Escoger Nombre De Usuario" "message": "Escoger Nombre De Usuario"
}, },
"copyPublicID": {
"message": "Copiar el ID de usuario público"
},
"discordAdvert": { "discordAdvert": {
"message": "¡Únete al servidor oficial de discord para darnos sugerencias y comentarios!" "message": "¡Únete al servidor oficial de discord para darnos sugerencias y comentarios!"
}, },
@@ -360,16 +363,13 @@
"message": "Comprueba status.sponsor.ajay.app para ver el estado del servidor." "message": "Comprueba status.sponsor.ajay.app para ver el estado del servidor."
}, },
"changeUserID": { "changeUserID": {
"message": "Importar/Exportar tu UserID" "message": "Importar/Exportar tu ID de usuario"
},
"whatChangeUserID": {
"message": "Esto debería mantenerse privado. Es como una contraseña y no debe ser compartido con nadie. Si alguien tiene esto, pueden imitarte."
}, },
"setUserID": { "setUserID": {
"message": "Establecer la ID de usuario" "message": "Establecer el ID de usuario"
}, },
"userIDChangeWarning": { "userIDChangeWarning": {
"message": "Advertencia: El cambio de la ID de usuario es irreversible. ¿Está seguro de que le desea hacerlo? Asegúrese de hacer una copia de respaldo de la anterior por si acaso." "message": "Advertencia: El cambio del ID de usuario es irreversible. ¿Está seguro de que le desea hacerlo? Asegúrese de hacer una copia de respaldo de la anterior por si acaso."
}, },
"createdBy": { "createdBy": {
"message": "Creado Por" "message": "Creado Por"

View File

@@ -52,6 +52,9 @@
"reskip": { "reskip": {
"message": "Jäta uuesti vahele" "message": "Jäta uuesti vahele"
}, },
"unmute": {
"message": "Tühista vaigistus"
},
"paused": { "paused": {
"message": "Pausil" "message": "Pausil"
}, },
@@ -161,6 +164,9 @@
"setUsername": { "setUsername": {
"message": "Määra kasutajanimi" "message": "Määra kasutajanimi"
}, },
"copyPublicID": {
"message": "Kopeeri avalik UserID"
},
"discordAdvert": { "discordAdvert": {
"message": "Tule liitu ametliku Discordi serveriga, et anda soovitusi ja tagasisidet!" "message": "Tule liitu ametliku Discordi serveriga, et anda soovitusi ja tagasisidet!"
}, },
@@ -227,6 +233,21 @@
"showSkipNotice": { "showSkipNotice": {
"message": "Kuva segmendi vahelejätmisel teatis" "message": "Kuva segmendi vahelejätmisel teatis"
}, },
"noticeVisibilityMode0": {
"message": "Täissuuruses vahelejätmise teavitused"
},
"noticeVisibilityMode1": {
"message": "Väikesed vahelejätmise teavitused autom. vahelejätmistele"
},
"noticeVisibilityMode2": {
"message": "Kõik vahelejätmise teavitused on väikesed"
},
"noticeVisibilityMode3": {
"message": "Hääbuvad vahelejätmise teavitused autom. vahelejätmistele"
},
"noticeVisibilityMode4": {
"message": "Kõik vahelejätmise teavitused hääbuvad"
},
"longDescription": { "longDescription": {
"message": "SponsorBlock lubab sul vahele jätta sponsorid, vaheajad, kanali tellimise meeldetuletused ja muud YouTube'i videote tüütud kohad. SponsorBlock on rahva ühistööna toimiv brauserilaiendus, mis lubab igaühel saata sponsoreeritud segmendi algus- ja lõpuaegu ning teiste video segmentide aegu. Kui üks inimene saadab sponsoreeritud segmendi, jätavad teised laienduse kasutajad kohe selle vahele. Laiendus võimaldab ka muusikavideotel mitte-muusika jaotised vahele jätta.", "message": "SponsorBlock lubab sul vahele jätta sponsorid, vaheajad, kanali tellimise meeldetuletused ja muud YouTube'i videote tüütud kohad. SponsorBlock on rahva ühistööna toimiv brauserilaiendus, mis lubab igaühel saata sponsoreeritud segmendi algus- ja lõpuaegu ning teiste video segmentide aegu. Kui üks inimene saadab sponsoreeritud segmendi, jätavad teised laienduse kasutajad kohe selle vahele. Laiendus võimaldab ka muusikavideotel mitte-muusika jaotised vahele jätta.",
"description": "Full description of the extension on the store pages." "description": "Full description of the extension on the store pages."
@@ -284,6 +305,9 @@
"skip": { "skip": {
"message": "Jäta vahele" "message": "Jäta vahele"
}, },
"mute": {
"message": "Vaigista"
},
"skip_category": { "skip_category": {
"message": "Jätad {0} vahele?" "message": "Jätad {0} vahele?"
}, },
@@ -348,7 +372,7 @@
"message": "Impordi/ekspordi oma UserID" "message": "Impordi/ekspordi oma UserID"
}, },
"whatChangeUserID": { "whatChangeUserID": {
"message": "Seda tuleks privaatsena hoida. See on nagu parool ning seda ei tohiks kellegagi jagada. Kui kellelgi see on, saavad nad sinuna esineda." "message": "Seda tuleks privaatsena hoida. See on nagu parool ning seda ei tohiks kellegagi jagada. Kui kellelgi see on, saavad nad sinuna esineda.\nKui otsid avalikku UserID'd, klõpsa hüpikus olevat lõikelaua ikooni."
}, },
"setUserID": { "setUserID": {
"message": "Seadista UserID" "message": "Seadista UserID"
@@ -586,6 +610,9 @@
"autoSkipOnMusicVideos": { "autoSkipOnMusicVideos": {
"message": "Jäta automaatselt kõik segmendid vahele, kui eksisteerib mitte-muusika segment" "message": "Jäta automaatselt kõik segmendid vahele, kui eksisteerib mitte-muusika segment"
}, },
"muteSegments": {
"message": "Luba segmente, mis vahelejätmise asemel vaigistavad heli"
},
"colorFormatIncorrect": { "colorFormatIncorrect": {
"message": "Sinu värv on sobimatult vormistatud. See peaks olema 3- või 6-numbriline 16-kümmendsüsteemis kood, arvu ees trellid." "message": "Sinu värv on sobimatult vormistatud. See peaks olema 3- või 6-numbriline 16-kümmendsüsteemis kood, arvu ees trellid."
}, },
@@ -723,9 +750,15 @@
"helpPageThanksForInstalling": { "helpPageThanksForInstalling": {
"message": "Täname SponsorBlocki paigaldamise eest." "message": "Täname SponsorBlocki paigaldamise eest."
}, },
"helpPageNews": {
"message": "Uudised ja kuidas see on valmistatud"
},
"Credits": { "Credits": {
"message": "Tiitrid" "message": "Tiitrid"
}, },
"highlightNewFeature": {
"message": "Uus! Mine ühe klõpsuga video eesmärgi juurde uue \"esiletõstu\" kategooriaga"
},
"LearnMore": { "LearnMore": {
"message": "Lisateave" "message": "Lisateave"
} }

View File

@@ -52,6 +52,9 @@
"reskip": { "reskip": {
"message": "Ohita uudelleen" "message": "Ohita uudelleen"
}, },
"unmute": {
"message": "Poista mykistys"
},
"paused": { "paused": {
"message": "Pysäytetty" "message": "Pysäytetty"
}, },
@@ -161,6 +164,9 @@
"setUsername": { "setUsername": {
"message": "Aseta käyttäjänimi" "message": "Aseta käyttäjänimi"
}, },
"copyPublicID": {
"message": "Kopio julkinen UserID"
},
"discordAdvert": { "discordAdvert": {
"message": "Liity mukaan viralliselle Discord-palvelimelle, jotta voit antaa ehdotuksia ja palautetta!" "message": "Liity mukaan viralliselle Discord-palvelimelle, jotta voit antaa ehdotuksia ja palautetta!"
}, },
@@ -299,11 +305,14 @@
"skip": { "skip": {
"message": "Ohita" "message": "Ohita"
}, },
"mute": {
"message": "Mykistä"
},
"skip_category": { "skip_category": {
"message": "Ohita {0}?" "message": "Ohita {0}?"
}, },
"skip_to_category": { "skip_to_category": {
"message": "Ohita {0}an?", "message": "Ohita kohtaan: {0}",
"description": "Used for skipping to things (Skip to Highlight)" "description": "Used for skipping to things (Skip to Highlight)"
}, },
"skipped": { "skipped": {
@@ -311,7 +320,7 @@
"description": "Example: Sponsor Skipped" "description": "Example: Sponsor Skipped"
}, },
"skipped_to_category": { "skipped_to_category": {
"message": "Ohitettiin {0}an", "message": "Ohitettiin kohtaan: {0}",
"description": "Used for skipping to things (Skipped to Highlight)" "description": "Used for skipping to things (Skipped to Highlight)"
}, },
"disableAutoSkip": { "disableAutoSkip": {
@@ -363,7 +372,7 @@
"message": "Tuo/vie UserID:si" "message": "Tuo/vie UserID:si"
}, },
"whatChangeUserID": { "whatChangeUserID": {
"message": "Tämä tulisi pitää yksityisenä. Tämä on kuin salasana eikä sitä pitäisi jakaa kenellekään. Jos joku saa tämän, hän voi esiintyä sinuna." "message": "Tämä pitäisi pitää yksityisenä. Tämä on kuin salasana, eikä sitä pitäisi jakaa kenenkään kanssa. Jos jollakulla on tämä, he voivat esiintyä sinuna. Jos etsit julkista userID:täsi, napsauta leikepöydän kuvaketta ponnahdusikkunassa."
}, },
"setUserID": { "setUserID": {
"message": "Aseta UserID" "message": "Aseta UserID"
@@ -601,6 +610,9 @@
"autoSkipOnMusicVideos": { "autoSkipOnMusicVideos": {
"message": "Ohita kaikki segmentit automaattisesti, kun videossa on \"Musiikiton\" segmentti" "message": "Ohita kaikki segmentit automaattisesti, kun videossa on \"Musiikiton\" segmentti"
}, },
"muteSegments": {
"message": "Salli segmentit, jotka mykistävät äänen ohittamisen sijaan"
},
"colorFormatIncorrect": { "colorFormatIncorrect": {
"message": "Väriformaattisi on muotoiltu väärin. Sen pitäisi olla 3 tai 6 numeroinen hex-koodi, jossa on # alussa." "message": "Väriformaattisi on muotoiltu väärin. Sen pitäisi olla 3 tai 6 numeroinen hex-koodi, jossa on # alussa."
}, },

View File

@@ -52,6 +52,9 @@
"reskip": { "reskip": {
"message": "Sauter" "message": "Sauter"
}, },
"unmute": {
"message": "Réactiver le son"
},
"paused": { "paused": {
"message": "En pause" "message": "En pause"
}, },
@@ -161,6 +164,9 @@
"setUsername": { "setUsername": {
"message": "Choisir un pseudonyme" "message": "Choisir un pseudonyme"
}, },
"copyPublicID": {
"message": "Copier l'ID utilisateur"
},
"discordAdvert": { "discordAdvert": {
"message": "Rejoignez le serveur Discord officiel pour toutes suggestions ou remarques!" "message": "Rejoignez le serveur Discord officiel pour toutes suggestions ou remarques!"
}, },
@@ -227,6 +233,21 @@
"showSkipNotice": { "showSkipNotice": {
"message": "Notifier après qu'un segment ait été sauté" "message": "Notifier après qu'un segment ait été sauté"
}, },
"noticeVisibilityMode0": {
"message": "Notifications de passage"
},
"noticeVisibilityMode1": {
"message": "Petite notifications de passage pour l'auto skip"
},
"noticeVisibilityMode2": {
"message": "Toute les petites notifications de passage"
},
"noticeVisibilityMode3": {
"message": "Notifications de passage qui disparaissent pour l'auto skip"
},
"noticeVisibilityMode4": {
"message": "Toute les notifications de passage qui disparaissent"
},
"longDescription": { "longDescription": {
"message": "SponsorBlock vous permet de passer les sponsors, les intros, les outros, les rappels d'abonnement et autres parties ennuyeuses des vidéos YouTube. SponsorBlock est une extension de navigateur qui permet à n'importe qui de soumettre les temps de début et de fin des segments sponsorisés et d'autres segments de vidéos YouTube. Une fois qu'une personne a soumis ces informations, toutes les autres personnes possédant cette extension passeront directement les segments sponsorisés. Vous pouvez également sauter les sections non musicales des vidéos musicales.", "message": "SponsorBlock vous permet de passer les sponsors, les intros, les outros, les rappels d'abonnement et autres parties ennuyeuses des vidéos YouTube. SponsorBlock est une extension de navigateur qui permet à n'importe qui de soumettre les temps de début et de fin des segments sponsorisés et d'autres segments de vidéos YouTube. Une fois qu'une personne a soumis ces informations, toutes les autres personnes possédant cette extension passeront directement les segments sponsorisés. Vous pouvez également sauter les sections non musicales des vidéos musicales.",
"description": "Full description of the extension on the store pages." "description": "Full description of the extension on the store pages."
@@ -284,9 +305,24 @@
"skip": { "skip": {
"message": "Passer" "message": "Passer"
}, },
"mute": {
"message": "Couper le son"
},
"skip_category": { "skip_category": {
"message": "Passer {0} ?" "message": "Passer {0} ?"
}, },
"skip_to_category": {
"message": "Passer à {0}?",
"description": "Used for skipping to things (Skip to Highlight)"
},
"skipped": {
"message": "{0} ignoré",
"description": "Example: Sponsor Skipped"
},
"skipped_to_category": {
"message": "Sauté à {0}",
"description": "Used for skipping to things (Skipped to Highlight)"
},
"disableAutoSkip": { "disableAutoSkip": {
"message": "Désactiver le passage automatique" "message": "Désactiver le passage automatique"
}, },
@@ -336,7 +372,7 @@
"message": "Importer/Exporter Votre ID d'Utilisateur" "message": "Importer/Exporter Votre ID d'Utilisateur"
}, },
"whatChangeUserID": { "whatChangeUserID": {
"message": "Cette information doit rester confidentielle. C'est comme un mot de passe et ne devrait pas être partagé avec quiconque. Si quelqu'un l'obtient, il pourra se faire passer pour vous." "message": "Cela devrait rester privé. C'est comme un mot de passe et ne devrait être partagé avec personne. Si quelqu'un a cela, il peut vous usurper. Si vous recherchez votre identifiant d'utilisateur public, cliquez sur l'icône du presse-papiers dans le popup."
}, },
"setUserID": { "setUserID": {
"message": "Définir \"UserID\"" "message": "Définir \"UserID\""
@@ -538,6 +574,12 @@
"category_music_offtopic_short": { "category_music_offtopic_short": {
"message": "Hors musique" "message": "Hors musique"
}, },
"category_poi_highlight": {
"message": "Surligner"
},
"category_poi_highlight_description": {
"message": "La partie de la vidéo que la plupart des gens veulent voir. Similaire à \"la vidéo commence à x mins\"."
},
"category_livestream_messages": { "category_livestream_messages": {
"message": "Stream : lecture de dons et messages" "message": "Stream : lecture de dons et messages"
}, },
@@ -556,6 +598,21 @@
"disable": { "disable": {
"message": "Désactiver" "message": "Désactiver"
}, },
"autoSkip_POI": {
"message": "Passer automatiquement au début"
},
"manualSkip_POI": {
"message": "Demander lors du chargement de la vidéo"
},
"showOverlay_POI": {
"message": "Afficher dans la barre de recherche"
},
"autoSkipOnMusicVideos": {
"message": "Ignorer automatiquement tous les segments lorsqu'il y a un segment non-musical"
},
"muteSegments": {
"message": "Autoriser les segments qui bloquent l'audio au lieu de le passer"
},
"colorFormatIncorrect": { "colorFormatIncorrect": {
"message": "Votre couleur est mal formatée. Il devrait s'agir d'un code hexadécimal à 3 ou 6 chiffres avec un signe numérique au début." "message": "Votre couleur est mal formatée. Il devrait s'agir d'un code hexadécimal à 3 ou 6 chiffres avec un signe numérique au début."
}, },
@@ -666,11 +723,91 @@
"help": { "help": {
"message": "Aide" "message": "Aide"
}, },
"GotIt": {
"message": "Compris",
"description": "Used as the button to dismiss a tooltip"
},
"experiementOptOut": { "experiementOptOut": {
"message": "Se désinscrire de toutes les futures expériences", "message": "Se désinscrire de toutes les futures expériences",
"description": "This is used in a popup about a new experiment to get a list of unlisted videos to back up since all unlisted videos uploaded before 2017 will be set to private." "description": "This is used in a popup about a new experiment to get a list of unlisted videos to back up since all unlisted videos uploaded before 2017 will be set to private."
}, },
"hideForever": { "hideForever": {
"message": "Cacher pour toujours" "message": "Cacher pour toujours"
},
"warningChatInfo": {
"message": "Vous avez reçu un avertissement et ne pouvez pas soumettre des segments temporairement. Cela signifie que nous avons remarqué que vous commettez des erreurs courantes qui ne sont pas malveillantes, et que nous voulons simplement clarifier les règles. Vous pouvez également rejoindre ce chat en utilisant discord.gg/SponsorBlock ou matrix.to/#/+sponsor:ajay.app"
},
"voteRejectedWarning": {
"message": "Le vote a été rejeté en raison d'un avertissement. Cliquez pour ouvrir un chat et y mettre fin , ou revenez plus tard lorsque vous avez le temps.",
"description": "This is an integrated chat panel that will appearing allowing them to talk to the Discord/Matrix chat without leaving their browser."
},
"Donate": {
"message": "Faire un don"
},
"hideDonationLink": {
"message": "Cacher le lien de don"
},
"helpPageThanksForInstalling": {
"message": "Merci d'avoir installé SponsorBlock."
},
"helpPageReviewOptions": {
"message": "Veuillez vérifier les options ci-dessous"
},
"helpPageFeatureDisclaimer": {
"message": "De nombreuses fonctionnalités sont désactivées par défaut. Si vous voulez ignorer les intros, outros, utiliser Invidious, etc., activez-les ci-dessous. Vous pouvez également masquer/afficher les éléments de l'interface."
},
"helpPageHowSkippingWorks": {
"message": "Comment fonctionne le saut d'un segment"
},
"helpPageHowSkippingWorks1": {
"message": "Les segments vidéo seront automatiquement ignorés s'ils sont trouvés dans la base de données. Vous pouvez ouvrir le popup en cliquant sur l'icône de l'extension pour obtenir un aperçu de ces segments."
},
"helpPageHowSkippingWorks2": {
"message": "À chaque fois que vous sautez un segment, vous en serez averti. Si le timing semble incorrect, vous pouvez disliker le segment, vous pouvez également voter dans le popup."
},
"Submitting": {
"message": "Soumission en cours"
},
"helpPageSubmitting1": {
"message": "La soumission peut être effectuée dans le popup en appuyant sur le bouton \"le segment commence maintenant\" ou dans le lecteur vidéo avec les boutons du lecteur."
},
"helpPageSubmitting2": {
"message": "Cliquer sur le bouton de lecture indique le début d'un segment et cliquer sur l'icône d'arrêt indique la fin. Vous pouvez préparer plusieurs sponsors avant d'appuyer sur Soumettre. Cliquer sur le bouton de soumission enverra le segment. Cliquer sur le poubelle supprimera vos segments."
},
"Editing": {
"message": "Édition en cours"
},
"helpPageEditing1": {
"message": "Si vous avez fait une erreur, vous pouvez modifier ou supprimer vos segments après avoir cliqué sur le bouton avec la flèche vers le haut."
},
"helpPageTooSlow": {
"message": "Ceci est trop lent"
},
"helpPageTooSlow1": {
"message": "Il y a des raccourcis clavier si vous voulez les utiliser. Appuyez sur la touche point-virgule pour indiquer le début / la fin d'un segment sponsorisé et cliquez sur l'apostrophe pour soumettre. Cela peut être modifié dans les options. Si vous n'utilisez pas un clavier QWERTY, vous devriez probablement changer la touche assignée de base."
},
"helpPageCopyOfDatabase": {
"message": "Puis-je obtenir une copie de la base de données ? Que se passe-t-il si vous disparaissez ?"
},
"helpPageCopyOfDatabase1": {
"message": "La base de données est publique et disponible à"
},
"helpPageCopyOfDatabase2": {
"message": "Le code source est librement disponible. Donc, même si il m'arrive quelque chose, vos soumissions ne seront pas perdues."
},
"helpPageNews": {
"message": "Nouvelles et comment elles sont faites"
},
"helpPageSourceCode": {
"message": "Où puis-je obtenir le code source ?"
},
"Credits": {
"message": "Crédits"
},
"highlightNewFeature": {
"message": "Nouveau! Aller à l'essentiel de la vidéo en un clic avec la nouvelle catégorie points essentiels"
},
"LearnMore": {
"message": "En savoir plus"
} }
} }

View File

@@ -179,9 +179,6 @@
"hoursLower": { "hoursLower": {
"message": "h" "message": "h"
}, },
"whatChangeUserID": {
"message": "Ovo bi trebalo ostati privatno. slično je lozinki i ne bi se smjelo dijeliti ni s kime. Ako netko ovo ima, mogu se lažno predstavljati kao ti."
},
"setUserID": { "setUserID": {
"message": "Postavi UserID" "message": "Postavi UserID"
}, },

View File

@@ -329,9 +329,6 @@
"changeUserID": { "changeUserID": {
"message": "UserID importálása / exportálása" "message": "UserID importálása / exportálása"
}, },
"whatChangeUserID": {
"message": "Ezt titokban kell tartani. Olyan, mint egy jelszó, nem szabad senkivel megosztania. Ha valakinek megvan, megszemélyesítheti Önt."
},
"setUserID": { "setUserID": {
"message": "UserID beállítása" "message": "UserID beállítása"
}, },
@@ -431,6 +428,9 @@
"preview": { "preview": {
"message": "Előnézet" "message": "Előnézet"
}, },
"unsubmitted": {
"message": "Nincs beküldve"
},
"inspect": { "inspect": {
"message": "Megvizsgál" "message": "Megvizsgál"
}, },
@@ -495,6 +495,9 @@
"category_outro_description": { "category_outro_description": {
"message": "Stáblista, vagy amikor megjelennek a YouTube zárókártyák. Nem használandó információt tartalmazó következtetésekkor." "message": "Stáblista, vagy amikor megjelennek a YouTube zárókártyák. Nem használandó információt tartalmazó következtetésekkor."
}, },
"category_preview": {
"message": "Előzetes/Ismétlés"
},
"category_music_offtopic": { "category_music_offtopic": {
"message": "Zene: nem-zene szegmens" "message": "Zene: nem-zene szegmens"
}, },
@@ -597,5 +600,33 @@
}, },
"help": { "help": {
"message": "Segítség" "message": "Segítség"
},
"GotIt": {
"message": "Értettem",
"description": "Used as the button to dismiss a tooltip"
},
"hideForever": {
"message": "Eltüntetés örökre"
},
"Donate": {
"message": "Támogatás"
},
"Submitting": {
"message": "Küldés"
},
"Editing": {
"message": "Szerkesztés"
},
"helpPageTooSlow": {
"message": "Ez túl lassú"
},
"helpPageNews": {
"message": "Hírek és hogyan készül"
},
"Credits": {
"message": "Készítők"
},
"LearnMore": {
"message": "Tudj meg többet"
} }
} }

View File

@@ -281,6 +281,18 @@
"skip_category": { "skip_category": {
"message": "Lewati {0}?" "message": "Lewati {0}?"
}, },
"skip_to_category": {
"message": "Lompat ke {0}?",
"description": "Used for skipping to things (Skip to Highlight)"
},
"skipped": {
"message": "{0} dilewati",
"description": "Example: Sponsor Skipped"
},
"skipped_to_category": {
"message": "Melewati ke {0}",
"description": "Used for skipping to things (Skipped to Highlight)"
},
"disableAutoSkip": { "disableAutoSkip": {
"message": "Nonaktifkan Lewati Otomatis" "message": "Nonaktifkan Lewati Otomatis"
}, },
@@ -329,9 +341,6 @@
"changeUserID": { "changeUserID": {
"message": "Impor/Ekspor UserID" "message": "Impor/Ekspor UserID"
}, },
"whatChangeUserID": {
"message": "Ini sebaiknya dirahasiakan. Ini terlihat seperti password dan sebaiknya tidak dibagikan ke orang lain. Jika seseorang mempunyai ini, dia dapat berpura-pura menjadi anda."
},
"setUserID": { "setUserID": {
"message": "Atur UserID" "message": "Atur UserID"
}, },
@@ -344,6 +353,9 @@
"keybindCurrentlySet": { "keybindCurrentlySet": {
"message": ". Saat ini diatur pada:" "message": ". Saat ini diatur pada:"
}, },
"supportOtherSites": {
"message": "Dukung Situs Youtube Pihak Ketiga"
},
"optionsInfo": { "optionsInfo": {
"message": "Aktifkan dukungan Invidious, nonaktifkan lewati otomatis, tombol sembunyi dan lainnya." "message": "Aktifkan dukungan Invidious, nonaktifkan lewati otomatis, tombol sembunyi dan lainnya."
}, },
@@ -428,6 +440,9 @@
"preview": { "preview": {
"message": "Pratinjau" "message": "Pratinjau"
}, },
"unsubmitted": {
"message": "Belum dikirim"
},
"inspect": { "inspect": {
"message": "Inspeksi" "message": "Inspeksi"
}, },
@@ -492,6 +507,12 @@
"category_outro_description": { "category_outro_description": {
"message": "Kredit atau saat kartu akhir YouTube muncul. Tidak untuk kesimpulan dengan informasi." "message": "Kredit atau saat kartu akhir YouTube muncul. Tidak untuk kesimpulan dengan informasi."
}, },
"category_preview": {
"message": "Pratinjau/Rekap"
},
"category_preview_description": {
"message": "Rekapan singkat dari episode sebelumnya, atau pratinjau tentang apa yang akan terjadi nanti di video. Dimaksudkan untuk klip bersama yang di edit, bukan ringkasan yang diucapkan."
},
"category_music_offtopic": { "category_music_offtopic": {
"message": "Musik: Bagian Non-Musik" "message": "Musik: Bagian Non-Musik"
}, },
@@ -519,9 +540,22 @@
"disable": { "disable": {
"message": "Nonaktif" "message": "Nonaktif"
}, },
"manualSkip_POI": {
"message": "Tanya saat video dimuat"
},
"showOverlay_POI": {
"message": "Tampilkan di Bilah Waktu"
},
"autoSkipOnMusicVideos": {
"message": "Lewati semua segmen secara otomatis ketika ada segmen non-music"
},
"colorFormatIncorrect": { "colorFormatIncorrect": {
"message": "Warna anda tidak diformat dengan benar. Harusnya terdiri dari 3 atau 6 digit kode heksa dengan tagar di awal." "message": "Warna anda tidak diformat dengan benar. Harusnya terdiri dari 3 atau 6 digit kode heksa dengan tagar di awal."
}, },
"previewColor": {
"message": "Warna yang Belum Dikirim",
"description": "Referring to submissions that have not been sent to the server yet."
},
"seekBarColor": { "seekBarColor": {
"message": "Warna Bilah Waktu" "message": "Warna Bilah Waktu"
}, },
@@ -622,7 +656,29 @@
"categoryUpdate2": { "categoryUpdate2": {
"message": "Buka opsi untuk melewati intro, outro, merch, dll." "message": "Buka opsi untuk melewati intro, outro, merch, dll."
}, },
"help": {
"message": "Bantuan"
},
"GotIt": {
"message": "Mengerti",
"description": "Used as the button to dismiss a tooltip"
},
"hideForever": { "hideForever": {
"message": "Sembunyikan selamanya" "message": "Sembunyikan selamanya"
},
"Donate": {
"message": "Donasi"
},
"hideDonationLink": {
"message": "Sembunyikan tautan donasi"
},
"helpPageThanksForInstalling": {
"message": "Terima kasih telah menginstall SponsorBlock."
},
"helpPageReviewOptions": {
"message": "Haram ditinjau opsi di bawah ini"
},
"helpPageHowSkippingWorks": {
"message": "Cara kerja melewati segmen"
} }
} }

View File

@@ -161,6 +161,9 @@
"setUsername": { "setUsername": {
"message": "Imposta Username" "message": "Imposta Username"
}, },
"copyPublicID": {
"message": "Copia UserID Pubblico"
},
"discordAdvert": { "discordAdvert": {
"message": "Entra nel server Discord ufficiale per darci suggerimenti e feedback!" "message": "Entra nel server Discord ufficiale per darci suggerimenti e feedback!"
}, },
@@ -363,7 +366,7 @@
"message": "Importa/Esporta Il Tuo ID Utente" "message": "Importa/Esporta Il Tuo ID Utente"
}, },
"whatChangeUserID": { "whatChangeUserID": {
"message": "Questo dovrebbe essere tenuto privato. Questo è come una password e non dovrebbe essere condiviso con nessuno. Se qualcuno ha questo, ti può impersonare." "message": "Questo dovrebbe esser mantenuto privato. È come una password e non dovrebbe esser condiviso con nessuno. Se qualcuno lo possiede, può impersonarti. Se stai cercando il tuo userID pubblico, clicca l'icona degli appunti nel popup."
}, },
"setUserID": { "setUserID": {
"message": "Imposta ID utente" "message": "Imposta ID utente"

View File

@@ -362,9 +362,6 @@
"changeUserID": { "changeUserID": {
"message": "ユーザーIDのインポート/エクスポート" "message": "ユーザーIDのインポート/エクスポート"
}, },
"whatChangeUserID": {
"message": "ユーザーIDは公開しないでください。これはパスワードのようなもので誰とも共有するべきではありません。 他の誰かが知った場合、あなたになりすます可能性があります。"
},
"setUserID": { "setUserID": {
"message": "ユーザーIDを設定" "message": "ユーザーIDを設定"
}, },

View File

@@ -52,6 +52,9 @@
"reskip": { "reskip": {
"message": "다시 건너뛰기" "message": "다시 건너뛰기"
}, },
"unmute": {
"message": "음소거 해제"
},
"paused": { "paused": {
"message": "정지됨" "message": "정지됨"
}, },
@@ -161,6 +164,9 @@
"setUsername": { "setUsername": {
"message": "사용자 이름 설정" "message": "사용자 이름 설정"
}, },
"copyPublicID": {
"message": "공개 사용자 ID 복사"
},
"discordAdvert": { "discordAdvert": {
"message": "공식 디스코드 서버에 들어와서 기능 제안을 해주시거나 피드백을 남겨주세요!" "message": "공식 디스코드 서버에 들어와서 기능 제안을 해주시거나 피드백을 남겨주세요!"
}, },
@@ -227,6 +233,21 @@
"showSkipNotice": { "showSkipNotice": {
"message": "구간을 건너뛴 후 알림 표시" "message": "구간을 건너뛴 후 알림 표시"
}, },
"noticeVisibilityMode0": {
"message": "건너뛰기 알림 크게"
},
"noticeVisibilityMode1": {
"message": "자동 건너뛰기에 대해서는 건너뛰기 알림 작게"
},
"noticeVisibilityMode2": {
"message": "모든 건너뛰기 알림 작게"
},
"noticeVisibilityMode3": {
"message": "자동 건너뛰기에 대해서는 건너뛰기 알림 숨김"
},
"noticeVisibilityMode4": {
"message": "모든 건너뛰기 알림 숨김"
},
"longDescription": { "longDescription": {
"message": "SponsorBlock을 사용하면 영상에서 스폰서 광고, 인트로 영상, 아웃트로 영상, 구독 광고와 그 외 쓸데없는 부분을 즉시 건너뛸 수 있습니다. SponsorBlock은 모든 사람들이 참여하는 브라우저 확장 기능으로 확장 기능 사용자는 스폰서 광고 또는 다른 광고의 시작 시간과 끝 시간을 확인하여 서버로 전송할 수 있습니다. 이러한 정보가 전송되면 그 영상을 보는 다른 사용자들은 광고 구간이 나오기 전에 자동으로 건너뛸 수 있습니다. SponsorBlock을 사용하면 뮤직 비디오에서 음악이나 노래가 아닌 구간도 건너뛸 수 있습니다.", "message": "SponsorBlock을 사용하면 영상에서 스폰서 광고, 인트로 영상, 아웃트로 영상, 구독 광고와 그 외 쓸데없는 부분을 즉시 건너뛸 수 있습니다. SponsorBlock은 모든 사람들이 참여하는 브라우저 확장 기능으로 확장 기능 사용자는 스폰서 광고 또는 다른 광고의 시작 시간과 끝 시간을 확인하여 서버로 전송할 수 있습니다. 이러한 정보가 전송되면 그 영상을 보는 다른 사용자들은 광고 구간이 나오기 전에 자동으로 건너뛸 수 있습니다. SponsorBlock을 사용하면 뮤직 비디오에서 음악이나 노래가 아닌 구간도 건너뛸 수 있습니다.",
"description": "Full description of the extension on the store pages." "description": "Full description of the extension on the store pages."
@@ -284,6 +305,9 @@
"skip": { "skip": {
"message": "스킵" "message": "스킵"
}, },
"mute": {
"message": "음소거"
},
"skip_category": { "skip_category": {
"message": "{0} 을(를) 건너뛰겠어요?" "message": "{0} 을(를) 건너뛰겠어요?"
}, },
@@ -348,7 +372,7 @@
"message": "사용자 ID 가져오기/내보내기" "message": "사용자 ID 가져오기/내보내기"
}, },
"whatChangeUserID": { "whatChangeUserID": {
"message": "이 정보는 다른 사람에게 공개하지 마세요. 이것은 비밀번호처럼 절대로 알려주면 안되는 정보입니다. 다른 사람이 이 정보를 습득했을 경우 사용자를 사칭할 수도 있습니다." "message": "이 정보는 다른 사람에게 공개하지 마세요. 이것은 비밀번호처럼 절대로 알려주면 안되는 정보입니다. 다른 사람이 이 정보를 습득했을 경우 사용자를 사칭할 수도 있습니다. 혹시 공개 사용자 ID를 찾고 있다면, 팝업 내 클립보드 아이콘을 누르시기 바랍니다."
}, },
"setUserID": { "setUserID": {
"message": "사용자ID 설정" "message": "사용자ID 설정"
@@ -586,6 +610,9 @@
"autoSkipOnMusicVideos": { "autoSkipOnMusicVideos": {
"message": "음악이 아닌 구간이 있을 때는 모든 구간 자동 건너뛰기" "message": "음악이 아닌 구간이 있을 때는 모든 구간 자동 건너뛰기"
}, },
"muteSegments": {
"message": "구간을 건너뛰지 않고 음소거 처리하도록 합니다"
},
"colorFormatIncorrect": { "colorFormatIncorrect": {
"message": "올바르지 않은 색상 코드입니다. 색상 코드는 샵 (#) 기호로 시작하여 3자리 또는 6자리의 16진수로 구성되어야 합니다." "message": "올바르지 않은 색상 코드입니다. 색상 코드는 샵 (#) 기호로 시작하여 3자리 또는 6자리의 16진수로 구성되어야 합니다."
}, },
@@ -744,6 +771,9 @@
"helpPageSubmitting1": { "helpPageSubmitting1": {
"message": "\"광고 구간 시작\" 버튼을 누른 다음 팝업에서 제출할 수도 있으며 동영상 플레이어 내 버튼으로 제출할 수도 있습니다." "message": "\"광고 구간 시작\" 버튼을 누른 다음 팝업에서 제출할 수도 있으며 동영상 플레이어 내 버튼으로 제출할 수도 있습니다."
}, },
"helpPageSubmitting2": {
"message": "재생 아이콘을 누르면 구간의 시점을 정할 수 있고 중지 아이콘을 누르면 구간의 종점을 정할 수 있습니다. 제출하기 전 여러 구간을 설정할 수 있습니다. 업로드 아이콘을 눌러 제출할 수 있습니다. 휴지통 아이콘을 눌러 구간을 제거할 수 있습니다."
},
"Editing": { "Editing": {
"message": "수정" "message": "수정"
}, },
@@ -753,6 +783,18 @@
"helpPageTooSlow": { "helpPageTooSlow": {
"message": "너무 느립니다" "message": "너무 느립니다"
}, },
"helpPageTooSlow1": {
"message": "원하는 경우 단축키를 이용할 수 있습니다. 쌍반점 키를 눌러 스폰서 구간의 시점/종점을 설정할 수 있으며 작은따옴표 키를 눌러 구간을 제출할 수 있습니다. 설정에서 이를 변경할 수 있습니다. QWERTY 자판을 사용하지 않는 경우, 단축키 설정을 변경해야 할 수 있습니다."
},
"helpPageCopyOfDatabase": {
"message": "데이터베이스의 사본을 구할 수 있을까요? 개발자에게 무슨 일이 생기면 어떻게 되는 거죠?"
},
"helpPageCopyOfDatabase1": {
"message": "데이터베이스는 공개되어 있으며 다음 주소를 통해 접근할 수 있습니다"
},
"helpPageCopyOfDatabase2": {
"message": "소스 코드는 자유롭게 이용할 수 있습니다. 따라서 제게 무슨 일이 생기더라도, 기여 사항이 사라지는 일은 없습니다."
},
"helpPageNews": { "helpPageNews": {
"message": "소식 및 제작 방법" "message": "소식 및 제작 방법"
}, },

View File

@@ -320,9 +320,6 @@
"changeUserID": { "changeUserID": {
"message": "നിങ്ങളുടെ യൂസർ ഐഡി ഇറക്കുമതി ചെയ്യുക / കയറ്റുമതി ചെയ്യുക" "message": "നിങ്ങളുടെ യൂസർ ഐഡി ഇറക്കുമതി ചെയ്യുക / കയറ്റുമതി ചെയ്യുക"
}, },
"whatChangeUserID": {
"message": "ഇത് സ്വകാര്യമായി സൂക്ഷിക്കണം. ഇത് ഒരു പാസ്‌വേഡ് പോലെയാണ്, ഇത് ആരുമായും പങ്കിടാൻ പാടില്ല. ആർക്കെങ്കിലും ഇത് ഉണ്ടെങ്കിൽ, അവർക്ക് നിങ്ങളെ ആൾമാറാട്ടം നടത്താം."
},
"setUserID": { "setUserID": {
"message": "യൂസർ ഐഡി സജ്ജമാക്കുക" "message": "യൂസർ ഐഡി സജ്ജമാക്കുക"
}, },

View File

@@ -320,9 +320,6 @@
"changeUserID": { "changeUserID": {
"message": "Import / Eksport Id Pengguna Anda" "message": "Import / Eksport Id Pengguna Anda"
}, },
"whatChangeUserID": {
"message": "Perkara ini harus dirahsiakan. Ini seperti kata laluan dan tidak boleh dikongsi dengan sesiapa pun. Sekiranya seseorang mempunyai ini, mereka boleh menyamar sebagai anda."
},
"setUserID": { "setUserID": {
"message": "Tetapkan Id Pengguna" "message": "Tetapkan Id Pengguna"
}, },

View File

@@ -52,6 +52,9 @@
"reskip": { "reskip": {
"message": "Opnieuw overslaan" "message": "Opnieuw overslaan"
}, },
"unmute": {
"message": "Niet meer dempen"
},
"paused": { "paused": {
"message": "Gepauzeerd" "message": "Gepauzeerd"
}, },
@@ -161,6 +164,9 @@
"setUsername": { "setUsername": {
"message": "Gebruikersnaam instellen" "message": "Gebruikersnaam instellen"
}, },
"copyPublicID": {
"message": "Publieke gebruikers-ID kopiëren"
},
"discordAdvert": { "discordAdvert": {
"message": "Word lid van de officiële Discord-server om suggesties en feedback te geven!" "message": "Word lid van de officiële Discord-server om suggesties en feedback te geven!"
}, },
@@ -299,6 +305,9 @@
"skip": { "skip": {
"message": "Overslaan" "message": "Overslaan"
}, },
"mute": {
"message": "Dempen"
},
"skip_category": { "skip_category": {
"message": "{0} overslaan?" "message": "{0} overslaan?"
}, },
@@ -363,7 +372,7 @@
"message": "Uw gebruikers-ID importeren/exporteren" "message": "Uw gebruikers-ID importeren/exporteren"
}, },
"whatChangeUserID": { "whatChangeUserID": {
"message": "Dit moet privé gehouden worden. Dit is als een wachtwoord en mag met niemand gedeeld worden. Als iemand dit heeft, kan hij zich voordoen als u." "message": "Dit moet privé gehouden worden. Dit is als een wachtwoord en mag met niemand gedeeld worden. Als iemand dit heeft, kan hij zich voordoen als u. Klik op het klembordpictogram in de popup als u op zoek bent naar uw publieke gebrukers-ID."
}, },
"setUserID": { "setUserID": {
"message": "Gebruikers-ID instellen" "message": "Gebruikers-ID instellen"
@@ -601,6 +610,9 @@
"autoSkipOnMusicVideos": { "autoSkipOnMusicVideos": {
"message": "Automatisch alle segmenten overslaan wanneer er een niet-muziek-segment is" "message": "Automatisch alle segmenten overslaan wanneer er een niet-muziek-segment is"
}, },
"muteSegments": {
"message": "Segmenten toestaan die audio dempen in plaats van overslaan"
},
"colorFormatIncorrect": { "colorFormatIncorrect": {
"message": "Uw kleur is verkeerd geformatteerd. Het moet een hexadecimale code van 3 of 6 cijfers zijn met een hekje aan het begin." "message": "Uw kleur is verkeerd geformatteerd. Het moet een hexadecimale code van 3 of 6 cijfers zijn met een hekje aan het begin."
}, },

View File

@@ -320,9 +320,6 @@
"changeUserID": { "changeUserID": {
"message": "Importer/Eksporter din bruker-ID" "message": "Importer/Eksporter din bruker-ID"
}, },
"whatChangeUserID": {
"message": "Dette burde holdes privat. Dette er som et passord og burde ikke deles med noen. Hvis noen har dette, kan de etterligne deg."
},
"setUserID": { "setUserID": {
"message": "Angi bruker-ID" "message": "Angi bruker-ID"
}, },

View File

@@ -287,6 +287,10 @@
"skip_category": { "skip_category": {
"message": "Pominąć {0}?" "message": "Pominąć {0}?"
}, },
"skip_to_category": {
"message": "Przejść do {0}?",
"description": "Used for skipping to things (Skip to Highlight)"
},
"disableAutoSkip": { "disableAutoSkip": {
"message": "Wyłącz autopomijanie" "message": "Wyłącz autopomijanie"
}, },
@@ -335,9 +339,6 @@
"changeUserID": { "changeUserID": {
"message": "Importuj/Eksportuj swój identyfikator użytkownika" "message": "Importuj/Eksportuj swój identyfikator użytkownika"
}, },
"whatChangeUserID": {
"message": "Ta informacja jest poufna i działa jak hasło. Użytkownik, który ma do niej dostęp, może zgłaszać treści jako ty."
},
"setUserID": { "setUserID": {
"message": "Ustaw identyfikator użytkownika" "message": "Ustaw identyfikator użytkownika"
}, },
@@ -538,6 +539,9 @@
"category_music_offtopic_short": { "category_music_offtopic_short": {
"message": "Bez muzyki" "message": "Bez muzyki"
}, },
"category_poi_highlight": {
"message": "Podświetlone"
},
"category_livestream_messages": { "category_livestream_messages": {
"message": "Transmisja live: Dotacja/Czytanie wiadomości" "message": "Transmisja live: Dotacja/Czytanie wiadomości"
}, },
@@ -682,5 +686,14 @@
"voteRejectedWarning": { "voteRejectedWarning": {
"message": "Głosowanie odrzucone z powodu ostrzeżenia. Kliknij, aby otworzyć czat w celu rozwiązania problemu lub wróć później, gdy będziesz miał czas.", "message": "Głosowanie odrzucone z powodu ostrzeżenia. Kliknij, aby otworzyć czat w celu rozwiązania problemu lub wróć później, gdy będziesz miał czas.",
"description": "This is an integrated chat panel that will appearing allowing them to talk to the Discord/Matrix chat without leaving their browser." "description": "This is an integrated chat panel that will appearing allowing them to talk to the Discord/Matrix chat without leaving their browser."
},
"helpPageSourceCode": {
"message": "Gdzie mogę otrzymać kod źródłowy?"
},
"Credits": {
"message": "Autorzy"
},
"LearnMore": {
"message": "Dowiedz się więcej"
} }
} }

View File

@@ -362,9 +362,6 @@
"changeUserID": { "changeUserID": {
"message": "Importar/Exportar seu ID de usuário" "message": "Importar/Exportar seu ID de usuário"
}, },
"whatChangeUserID": {
"message": "Isso deve ser mantido em segredo. É como se fosse uma senha e não deve ser compartilhado com ninguém. Se alguém tiver isso, poderá se passar por você."
},
"setUserID": { "setUserID": {
"message": "Definir ID de usuário" "message": "Definir ID de usuário"
}, },

View File

@@ -320,9 +320,6 @@
"changeUserID": { "changeUserID": {
"message": "Importă/Exportă Id-ul Tău De Utilizator" "message": "Importă/Exportă Id-ul Tău De Utilizator"
}, },
"whatChangeUserID": {
"message": "Acest lucru trebuie să fie păstrat. Este ca și o parolă și nu ar trebui împartășită cu nimeni. Daca cineva are acest lucru, se poate da drept tu."
},
"setUserID": { "setUserID": {
"message": "Setează Id-ul Utilizatorului" "message": "Setează Id-ul Utilizatorului"
}, },

View File

@@ -52,6 +52,9 @@
"reskip": { "reskip": {
"message": "Пропустить" "message": "Пропустить"
}, },
"unmute": {
"message": "Включить звук"
},
"paused": { "paused": {
"message": "Пауза" "message": "Пауза"
}, },
@@ -161,6 +164,9 @@
"setUsername": { "setUsername": {
"message": "Установить имя пользователя" "message": "Установить имя пользователя"
}, },
"copyPublicID": {
"message": "Копировать публичный UserID"
},
"discordAdvert": { "discordAdvert": {
"message": "Присоединяйтесь к официальному серверу Discord, чтобы оставить предложения и обратную связь!" "message": "Присоединяйтесь к официальному серверу Discord, чтобы оставить предложения и обратную связь!"
}, },
@@ -299,6 +305,9 @@
"skip": { "skip": {
"message": "Пропустить" "message": "Пропустить"
}, },
"mute": {
"message": "Заглушить"
},
"skip_category": { "skip_category": {
"message": "Пропустить {0}?" "message": "Пропустить {0}?"
}, },
@@ -363,7 +372,7 @@
"message": "Импорт/Экспорт Вашего идентификатора пользователя" "message": "Импорт/Экспорт Вашего идентификатора пользователя"
}, },
"whatChangeUserID": { "whatChangeUserID": {
"message": "Его нужно держать в секрете. Это как пароль, не стоит им ни с кем делиться. Если он у кого-то есть, он сможет выдать себя за Вас." "message": "Держите его в тайне. Относитесь к нему как к паролю и не передавайте никому. Если кто-то им завладеет, то сможет выдать себя за вас. Если вы ищете публичный ID пользователя, нажмите значок буфера обмена во всплывающем окне."
}, },
"setUserID": { "setUserID": {
"message": "Установить идентификатор пользователя" "message": "Установить идентификатор пользователя"
@@ -601,6 +610,9 @@
"autoSkipOnMusicVideos": { "autoSkipOnMusicVideos": {
"message": "Пропускать все сегменты автоматически при наличии сегмента без музыки" "message": "Пропускать все сегменты автоматически при наличии сегмента без музыки"
}, },
"muteSegments": {
"message": "Разрешить сегменты, которые отключают звук вместо пропуска"
},
"colorFormatIncorrect": { "colorFormatIncorrect": {
"message": "Вы ввели цвет в неправильном формате. Это должно быть 3-х или 6-ти значное шестнадцатеричное число с символом # в начале." "message": "Вы ввели цвет в неправильном формате. Это должно быть 3-х или 6-ти значное шестнадцатеричное число с символом # в начале."
}, },

View File

@@ -52,6 +52,9 @@
"reskip": { "reskip": {
"message": "Znovu preskočiť" "message": "Znovu preskočiť"
}, },
"unmute": {
"message": "Zrušiť stíšenie"
},
"paused": { "paused": {
"message": "Pozastavené" "message": "Pozastavené"
}, },
@@ -161,6 +164,9 @@
"setUsername": { "setUsername": {
"message": "Nastaviť Používateľské meno" "message": "Nastaviť Používateľské meno"
}, },
"copyPublicID": {
"message": "Skopírovať verejné ID používateľa"
},
"discordAdvert": { "discordAdvert": {
"message": "Pripojte sa k oficiálnemu Discord serveru a zanechajte nám pripomienky!" "message": "Pripojte sa k oficiálnemu Discord serveru a zanechajte nám pripomienky!"
}, },
@@ -284,6 +290,9 @@
"skip": { "skip": {
"message": "Preskočiť" "message": "Preskočiť"
}, },
"mute": {
"message": "Stíšiť"
},
"skip_category": { "skip_category": {
"message": "Preskočiť {0}?" "message": "Preskočiť {0}?"
}, },
@@ -348,7 +357,7 @@
"message": "Import/export vášho ID používateľa" "message": "Import/export vášho ID používateľa"
}, },
"whatChangeUserID": { "whatChangeUserID": {
"message": "Toto si držte v bezpečí. Je to ako heslo a nemali by ste ho s nikým zdieľať. Ten kto ho má by sa mohol zas vydávať." "message": "Toto si starostlivo uchovajte. Podobne ako heslo by ste to nemali s nikým zdieľať. Ak by to získal niekto ďalší, mohol bym uškodiť. Ak hľadáte vaše verejné ID používateľa, stlačte ikonu schránky v podokne."
}, },
"setUserID": { "setUserID": {
"message": "Nastaviť Používateľove ID" "message": "Nastaviť Používateľove ID"
@@ -586,6 +595,9 @@
"autoSkipOnMusicVideos": { "autoSkipOnMusicVideos": {
"message": "Automaticky preskočiť všetky segmenty ak neexistuje segment bez hudby" "message": "Automaticky preskočiť všetky segmenty ak neexistuje segment bez hudby"
}, },
"muteSegments": {
"message": "Povoliť segmenty, ktoré namiesto preskočenia stíšía zvuk"
},
"colorFormatIncorrect": { "colorFormatIncorrect": {
"message": "Vaša farba je nesprávne naformátovaná. Mal by to byť 3 alebo 6-miestny hexadecimálny kód so znakom čísla na začiatku." "message": "Vaša farba je nesprávne naformátovaná. Mal by to byť 3 alebo 6-miestny hexadecimálny kód so znakom čísla na začiatku."
}, },

View File

@@ -52,6 +52,9 @@
"reskip": { "reskip": {
"message": "Hoppa över igen" "message": "Hoppa över igen"
}, },
"unmute": {
"message": "Ljud på"
},
"paused": { "paused": {
"message": "Pausad" "message": "Pausad"
}, },
@@ -161,6 +164,9 @@
"setUsername": { "setUsername": {
"message": "Ange användarnamn" "message": "Ange användarnamn"
}, },
"copyPublicID": {
"message": "Kopiera publikt Användar-ID"
},
"discordAdvert": { "discordAdvert": {
"message": "Gå med i den officiella discordservern för att ge förslag och feedback!" "message": "Gå med i den officiella discordservern för att ge förslag och feedback!"
}, },
@@ -299,6 +305,9 @@
"skip": { "skip": {
"message": "Hoppa över" "message": "Hoppa över"
}, },
"mute": {
"message": "Ljud av"
},
"skip_category": { "skip_category": {
"message": "Hoppa över {0}?" "message": "Hoppa över {0}?"
}, },
@@ -363,7 +372,7 @@
"message": "Importera/Exportera Ditt AnvändarID" "message": "Importera/Exportera Ditt AnvändarID"
}, },
"whatChangeUserID": { "whatChangeUserID": {
"message": "Denna ska hållas privat. Den fungerar som ett lösenord och ska inte delas med någon. Om någon får tag i den kan de utge sig för att vara dig." "message": "Detta ska hållas privat. Detta är som ett lösenord och ska inte delas med någon. Om andra får tag i det kan de utge sig för att vara dig. Om du letar efter ditt offentliga Användar-ID kan du klicka på urklippsikonen i popupen."
}, },
"setUserID": { "setUserID": {
"message": "Ange AnvändarID" "message": "Ange AnvändarID"
@@ -601,6 +610,9 @@
"autoSkipOnMusicVideos": { "autoSkipOnMusicVideos": {
"message": "Hoppa över alla segment automatiskt när det finns ett icke-musiksegment" "message": "Hoppa över alla segment automatiskt när det finns ett icke-musiksegment"
}, },
"muteSegments": {
"message": "Tillåt segment som tystar ljudet i stället för att hoppa över"
},
"colorFormatIncorrect": { "colorFormatIncorrect": {
"message": "Din färg är felaktigt formaterad. Det ska vara en 3- eller 6-siffrig hex-kod med en siffra i början." "message": "Din färg är felaktigt formaterad. Det ska vara en 3- eller 6-siffrig hex-kod med en siffra i början."
}, },

View File

@@ -320,9 +320,6 @@
"changeUserID": { "changeUserID": {
"message": "உங்கள் பயனர் ஐடியை இறக்குமதி / ஏற்றுமதி செய்யுங்கள்" "message": "உங்கள் பயனர் ஐடியை இறக்குமதி / ஏற்றுமதி செய்யுங்கள்"
}, },
"whatChangeUserID": {
"message": "இதை தனிப்பட்ட முறையில் வைத்திருக்க வேண்டும். இது கடவுச்சொல் போன்றது மற்றும் யாருடனும் பகிரக்கூடாது. யாராவது இதை வைத்திருந்தால், அவர்கள் உங்களைப் போல ஆள்மாறாட்டம் செய்யலாம்."
},
"setUserID": { "setUserID": {
"message": "UserID ஐ அமைக்கவும்" "message": "UserID ஐ அமைக்கவும்"
}, },

View File

@@ -320,9 +320,6 @@
"changeUserID": { "changeUserID": {
"message": "మీ యూజర్‌ఐడిని దిగుమతి / ఎగుమతి చేయండి" "message": "మీ యూజర్‌ఐడిని దిగుమతి / ఎగుమతి చేయండి"
}, },
"whatChangeUserID": {
"message": "దీన్ని ప్రైవేట్‌గా ఉంచాలి. ఇది పాస్‌వర్డ్ లాంటిది మరియు ఎవరితోనూ భాగస్వామ్యం చేయకూడదు. ఎవరైనా దీన్ని కలిగి ఉంటే, వారు మిమ్మల్ని వంచించగలరు."
},
"setUserID": { "setUserID": {
"message": "UserID ని సెట్ చేయండి" "message": "UserID ని సెట్ చేయండి"
}, },

View File

@@ -52,6 +52,9 @@
"reskip": { "reskip": {
"message": "Tekrar atla" "message": "Tekrar atla"
}, },
"unmute": {
"message": "Sesi Aç"
},
"paused": { "paused": {
"message": "Duraklatıldı" "message": "Duraklatıldı"
}, },
@@ -161,6 +164,9 @@
"setUsername": { "setUsername": {
"message": "Kullanıcı Adı Belirle" "message": "Kullanıcı Adı Belirle"
}, },
"copyPublicID": {
"message": "Herkese Açık Kullanıcı Kimliğini Kopyala"
},
"discordAdvert": { "discordAdvert": {
"message": "Öneri ve geri bildirimleriniz için resmi Discord serverımıza katılın!" "message": "Öneri ve geri bildirimleriniz için resmi Discord serverımıza katılın!"
}, },
@@ -227,6 +233,15 @@
"showSkipNotice": { "showSkipNotice": {
"message": "Bir Kısmı Atladıktan Sonra Uyarı Göster" "message": "Bir Kısmı Atladıktan Sonra Uyarı Göster"
}, },
"noticeVisibilityMode0": {
"message": "Tam Boyutlu Atlama Bildirimleri"
},
"noticeVisibilityMode1": {
"message": "Otomatik Atlama için Küçük Atlama Bildirimleri"
},
"noticeVisibilityMode2": {
"message": "Tüm Küçük Atlama Bildirimleri"
},
"longDescription": { "longDescription": {
"message": "SponsorBlock, sponsorları, giriş ve bitiş kısımlarını, abonelik hatırlatıcılarını ve YouTube videolarının diğer can sıkıcı kısımlarını atlamanıza olanak tanır. SponsorBlock, herkesin sponsorlu kısımları ve YouTube videolarının diğer kısımlarının başlangıç ve bitiş zamanlarını göndermesine izin veren kitle kaynaklı bir tarayıcı uzantısıdır. Bir kişi bu bilgiyi gönderdikten sonra, bu uzantıya sahip diğer herkes sponsorlu kısımları hemen atlayacaktır. Müzik videolarının müzik dışı bölümlerini de atlayabilirsiniz.", "message": "SponsorBlock, sponsorları, giriş ve bitiş kısımlarını, abonelik hatırlatıcılarını ve YouTube videolarının diğer can sıkıcı kısımlarını atlamanıza olanak tanır. SponsorBlock, herkesin sponsorlu kısımları ve YouTube videolarının diğer kısımlarının başlangıç ve bitiş zamanlarını göndermesine izin veren kitle kaynaklı bir tarayıcı uzantısıdır. Bir kişi bu bilgiyi gönderdikten sonra, bu uzantıya sahip diğer herkes sponsorlu kısımları hemen atlayacaktır. Müzik videolarının müzik dışı bölümlerini de atlayabilirsiniz.",
"description": "Full description of the extension on the store pages." "description": "Full description of the extension on the store pages."
@@ -284,6 +299,9 @@
"skip": { "skip": {
"message": "Atla" "message": "Atla"
}, },
"mute": {
"message": "Sustur"
},
"skip_category": { "skip_category": {
"message": "{0} atla?" "message": "{0} atla?"
}, },
@@ -348,7 +366,7 @@
"message": "Kullanıcı kimliğini Dışarı/İçeri Aktar" "message": "Kullanıcı kimliğini Dışarı/İçeri Aktar"
}, },
"whatChangeUserID": { "whatChangeUserID": {
"message": "Bu gizli tutulmalıdır. Bu bir şifreye benzer ve diğerleriyle paylaşılmaması gerekir. Birinin eline geçerse, sizi taklit edebilir." "message": "Bu gizli tutulmalıdır. Bu bir şifre gibidir ve kimseyle paylaşılmamalıdır. Eğer birisi buna sahipse, seni taklit edebilir. Herkese açık kullanıcı kimliğinizi arıyorsanız, açılır pencerede pano simgesine tıklayın."
}, },
"setUserID": { "setUserID": {
"message": "Kullanıcı kimliği Belirle" "message": "Kullanıcı kimliği Belirle"
@@ -550,6 +568,12 @@
"category_music_offtopic_short": { "category_music_offtopic_short": {
"message": "Müzik Olmayan Bölüm" "message": "Müzik Olmayan Bölüm"
}, },
"category_poi_highlight": {
"message": "Vurgu"
},
"category_poi_highlight_description": {
"message": "Videoda, çoğu insanın aradığı kısım. \"Video x sürede başlıyor\" yorumlarına benzer."
},
"category_livestream_messages": { "category_livestream_messages": {
"message": "Canlı Yayın: Bağış/Mesaj Okuma" "message": "Canlı Yayın: Bağış/Mesaj Okuma"
}, },
@@ -580,6 +604,9 @@
"autoSkipOnMusicVideos": { "autoSkipOnMusicVideos": {
"message": "Müzik olmayan kısım varsa tüm kısımları otomatik atla" "message": "Müzik olmayan kısım varsa tüm kısımları otomatik atla"
}, },
"muteSegments": {
"message": "Atlamak yerine sesi kapatan bölümlere izin ver"
},
"colorFormatIncorrect": { "colorFormatIncorrect": {
"message": "Renginiz yanlış biçimlendirilmiştir. Başında bir kare işareti bulunan 3 veya 6 basamaklı bir onaltılık kod olmalıdır." "message": "Renginiz yanlış biçimlendirilmiştir. Başında bir kare işareti bulunan 3 veya 6 basamaklı bir onaltılık kod olmalıdır."
}, },
@@ -690,6 +717,10 @@
"help": { "help": {
"message": "Yardım" "message": "Yardım"
}, },
"GotIt": {
"message": "Anladım",
"description": "Used as the button to dismiss a tooltip"
},
"experiementOptOut": { "experiementOptOut": {
"message": "Gelecekteki deneylerin hiçbirine katılma", "message": "Gelecekteki deneylerin hiçbirine katılma",
"description": "This is used in a popup about a new experiment to get a list of unlisted videos to back up since all unlisted videos uploaded before 2017 will be set to private." "description": "This is used in a popup about a new experiment to get a list of unlisted videos to back up since all unlisted videos uploaded before 2017 will be set to private."
@@ -703,5 +734,23 @@
"voteRejectedWarning": { "voteRejectedWarning": {
"message": "Bir uyarı nedeniyle oy reddedildi. Çözüm bulmak için buraya tıklayarak bir sohbet açın veya daha sonra vaktiniz olduğunda uğrayın.", "message": "Bir uyarı nedeniyle oy reddedildi. Çözüm bulmak için buraya tıklayarak bir sohbet açın veya daha sonra vaktiniz olduğunda uğrayın.",
"description": "This is an integrated chat panel that will appearing allowing them to talk to the Discord/Matrix chat without leaving their browser." "description": "This is an integrated chat panel that will appearing allowing them to talk to the Discord/Matrix chat without leaving their browser."
},
"Donate": {
"message": "Bağış Yap"
},
"hideDonationLink": {
"message": "Bağış Bağlantısını Gizle"
},
"helpPageThanksForInstalling": {
"message": "SponsorBlock'u yüklediğiniz için teşekkürler."
},
"helpPageReviewOptions": {
"message": "Lütfen aşağıdaki seçenekleri inceleyin"
},
"helpPageFeatureDisclaimer": {
"message": "Birçok özellik varsayılan olarak devre dışıdır. İntroları, outroları atlamak vb. kullanmak istiyorsanız, bunları aşağıdan etkinleştirin. Ayrıca arayüz öğelerini gizleyebilir/gösterebilirsiniz."
},
"helpPageHowSkippingWorks": {
"message": "Atlama nasıl çalışıyor"
} }
} }

View File

@@ -52,6 +52,9 @@
"reskip": { "reskip": {
"message": "Пропустити" "message": "Пропустити"
}, },
"unmute": {
"message": "Увімкнути звук"
},
"paused": { "paused": {
"message": "Пауза" "message": "Пауза"
}, },
@@ -161,6 +164,9 @@
"setUsername": { "setUsername": {
"message": "Встановити ім'я користувача" "message": "Встановити ім'я користувача"
}, },
"copyPublicID": {
"message": "Копіювати публічний UserID"
},
"discordAdvert": { "discordAdvert": {
"message": "Приєднуйтесь до офіційного сервера Discord, щоб залишити пропозиції і зворотний зв'язок!" "message": "Приєднуйтесь до офіційного сервера Discord, щоб залишити пропозиції і зворотний зв'язок!"
}, },
@@ -227,6 +233,21 @@
"showSkipNotice": { "showSkipNotice": {
"message": "Показувати сповіщення після пропуску сегмента" "message": "Показувати сповіщення після пропуску сегмента"
}, },
"noticeVisibilityMode0": {
"message": "Повнорозмірні сповіщення про пропуски"
},
"noticeVisibilityMode1": {
"message": "Зменшені сповіщення для автоматичних пропусків"
},
"noticeVisibilityMode2": {
"message": "Всі сповіщення зменшеного розміру"
},
"noticeVisibilityMode3": {
"message": "Напівпрозорі сповіщення для автоматичних пропусків"
},
"noticeVisibilityMode4": {
"message": "Напівпрозорі сповіщення для всіх пропусків"
},
"longDescription": { "longDescription": {
"message": "SponsorBlock дозволяє пропускати спонсорські вставки, початкові і кінцеві заставки, прохання підписатися і інше в відео на YouTube. SponsorBlock - колективне розширення, яке дозволяє кожному надіслати час початку і кінця подібних сегментів в відео. Після того, як хто-небудь надсилає цю інформацію, всі інші користувачі розширення будуть автоматично пропускати ці сегменти. Так само можна пропускати частини кліпів без музики.", "message": "SponsorBlock дозволяє пропускати спонсорські вставки, початкові і кінцеві заставки, прохання підписатися і інше в відео на YouTube. SponsorBlock - колективне розширення, яке дозволяє кожному надіслати час початку і кінця подібних сегментів в відео. Після того, як хто-небудь надсилає цю інформацію, всі інші користувачі розширення будуть автоматично пропускати ці сегменти. Так само можна пропускати частини кліпів без музики.",
"description": "Full description of the extension on the store pages." "description": "Full description of the extension on the store pages."
@@ -284,6 +305,9 @@
"skip": { "skip": {
"message": "Пропустити" "message": "Пропустити"
}, },
"mute": {
"message": "Вимкнути звук"
},
"skip_category": { "skip_category": {
"message": "Пропустити {0}?" "message": "Пропустити {0}?"
}, },
@@ -348,7 +372,7 @@
"message": "Імпортувати/Експортувати Ваш ідентифікатор користувача" "message": "Імпортувати/Експортувати Ваш ідентифікатор користувача"
}, },
"whatChangeUserID": { "whatChangeUserID": {
"message": "Це потрібно тримати в секреті. Це як пароль, не варто ним ні з ким ділитися. Якщо він у кого-то є, він зможе видати себе за Вас." "message": "Тримайте його в таємниці. Ставтеся до нього як до паролю і не передавайте нікому. Якщо хтось їм заволодіє, то зможе видати себе за вас. Якщо ви шукаєте публічний ID користувача, натисніть значок буфера обміну у спливаючому вікні."
}, },
"setUserID": { "setUserID": {
"message": "Встановити ідентифікатор користувача" "message": "Встановити ідентифікатор користувача"
@@ -586,6 +610,9 @@
"autoSkipOnMusicVideos": { "autoSkipOnMusicVideos": {
"message": "Автоматично пропустити усі сегменти, якщо присутній сегмент без музики" "message": "Автоматично пропустити усі сегменти, якщо присутній сегмент без музики"
}, },
"muteSegments": {
"message": "Дозволити сегменти, які відключають звук замість пропуску"
},
"colorFormatIncorrect": { "colorFormatIncorrect": {
"message": "Ви ввели колір в неправильному форматі. Це повинно бути 3-х або 6-ти значне шістнадцяткове число з символом # на початку." "message": "Ви ввели колір в неправильному форматі. Це повинно бути 3-х або 6-ти значне шістнадцяткове число з символом # на початку."
}, },
@@ -696,6 +723,10 @@
"help": { "help": {
"message": "Довідка" "message": "Довідка"
}, },
"GotIt": {
"message": "Зрозуміло",
"description": "Used as the button to dismiss a tooltip"
},
"experiementOptOut": { "experiementOptOut": {
"message": "Відмова від усіх майбутніх експериментів", "message": "Відмова від усіх майбутніх експериментів",
"description": "This is used in a popup about a new experiment to get a list of unlisted videos to back up since all unlisted videos uploaded before 2017 will be set to private." "description": "This is used in a popup about a new experiment to get a list of unlisted videos to back up since all unlisted videos uploaded before 2017 will be set to private."
@@ -709,5 +740,74 @@
"voteRejectedWarning": { "voteRejectedWarning": {
"message": "Голосування відхилено через попередження. Натисніть, щоб відкрити чат для вирішення цієї проблеми, або поверніться пізніше.", "message": "Голосування відхилено через попередження. Натисніть, щоб відкрити чат для вирішення цієї проблеми, або поверніться пізніше.",
"description": "This is an integrated chat panel that will appearing allowing them to talk to the Discord/Matrix chat without leaving their browser." "description": "This is an integrated chat panel that will appearing allowing them to talk to the Discord/Matrix chat without leaving their browser."
},
"Donate": {
"message": "Пожертвувати"
},
"hideDonationLink": {
"message": "Приховати посилання на пожертвування"
},
"helpPageThanksForInstalling": {
"message": "Дякую за встановлення SponsorBlock."
},
"helpPageReviewOptions": {
"message": "Будь ласка, ознайомтеся з налаштуваннями нижче"
},
"helpPageFeatureDisclaimer": {
"message": "Багато функцій за замовчуванням відключені. Якщо ви хочете пропускати початкові і кінцеві заставки, використовувати Invidious, тощо, увімкніть їх нижче. Ви також можете приховати / показати елементи інтерфейсу."
},
"helpPageHowSkippingWorks": {
"message": "Як працює пропуск"
},
"helpPageHowSkippingWorks1": {
"message": "Сегменти відео будуть автоматично пропущені, якщо вони знаходяться в базі даних. Ви можете відкрити спливаюче вікно, натиснувши на значок розширення, щоб подивитися, які сегменти додані."
},
"helpPageHowSkippingWorks2": {
"message": "Коли ви будете пропускати сегмент, ви отримаєте сповіщення. Якщо час здасться вам неправильним, проголосуйте проти, натиснувши на палець вниз! Ви також можете проголосувати у спливаючому вікні."
},
"Submitting": {
"message": "Відправлення"
},
"helpPageSubmitting1": {
"message": "Відправлення може бути виконана у спливаючому вікні натисканням на кнопку \"Сегмент починається звідси\" або кнопками в відеоплеєрі."
},
"helpPageSubmitting2": {
"message": "Натискання на кнопку відтворення означає початок сегмента і натискання на кнопку стоп позначає його кінець. Ви можете позначити кілька сегментів перед тим, як натиснути на кнопку відправлення. Натискання на кошик видалить все."
},
"Editing": {
"message": "Редагування"
},
"helpPageEditing1": {
"message": "Якщо ви зробили щось не так, ви можете відредагувати або видалити сегменти, натиснувши на кнопку зі стрілкою вгору."
},
"helpPageTooSlow": {
"message": "Це занадто повільно"
},
"helpPageTooSlow1": {
"message": "Все це також можна робити за допомогою гарячих клавіш. Натисніть \"ж\" для вказівки початку/кінця сегмента, \"є\" для відправки. Клавіші можуть бути змінені в налаштуваннях. Якщо ви не використовуєте QWERTY, то варто відразу поміняти гарячі клавіші."
},
"helpPageCopyOfDatabase": {
"message": "Чи можу я отримати копію бази даних? Що якщо ви пропадете?"
},
"helpPageCopyOfDatabase1": {
"message": "База даних доступна для всіх тут:"
},
"helpPageCopyOfDatabase2": {
"message": "Вихідний код у відкритому доступі, так що навіть якщо щось трапиться зі мною, ваш вклад не пропаде."
},
"helpPageNews": {
"message": "Новини та як це зроблено"
},
"helpPageSourceCode": {
"message": "Де можна отримати вихідний код?"
},
"Credits": {
"message": "Автори"
},
"highlightNewFeature": {
"message": "Новинка! Переходьте відразу до головного моменту відео за допомогою нової категорії \"Важливе\""
},
"LearnMore": {
"message": "Дізнатися більше"
} }
} }

View File

@@ -161,6 +161,9 @@
"setUsername": { "setUsername": {
"message": "Đặt tên người dùng" "message": "Đặt tên người dùng"
}, },
"copyPublicID": {
"message": "Sao chép Public UserID"
},
"discordAdvert": { "discordAdvert": {
"message": "Hãy tham gia server Discord chính thức để đăng gợi ý và phản hồi!" "message": "Hãy tham gia server Discord chính thức để đăng gợi ý và phản hồi!"
}, },
@@ -227,6 +230,21 @@
"showSkipNotice": { "showSkipNotice": {
"message": "Hiển thị thông báo sau khi bỏ qua quảng cáo" "message": "Hiển thị thông báo sau khi bỏ qua quảng cáo"
}, },
"noticeVisibilityMode0": {
"message": "Thông báo bỏ qua với kích thước đầy đủ"
},
"noticeVisibilityMode1": {
"message": "Thông báo bỏ qua kích thước nhỏ nếu phân đoạn được tự động bỏ qua"
},
"noticeVisibilityMode2": {
"message": "Thông báo bỏ qua kích thước nhỏ cho toàn bộ phân đoạn"
},
"noticeVisibilityMode3": {
"message": "Thông báo bỏ qua mờ nếu phân đoạn được tự động bỏ qua"
},
"noticeVisibilityMode4": {
"message": "Thông báo bỏ qua mờ cho tất cả các phân đoạn"
},
"longDescription": { "longDescription": {
"message": "SponsorBlock giúp bạn bỏ qua quảng cáo từ nhà tài trợ, đoạn giới thiệu, đoạn kết, lời nhắc đăng ký kênh, và những phần khó chịu khác trong các video Youtube. SponsorBlock là một tiện ích mở rộng cho trình duyệt, cho phép tất cả người dùng đăng thời điểm bắt đầu và kết thúc của những đoạn quảng cáo từ nhà tài trợ và các đoạn khác trong video Youtube. Sau khi một người đăng thông tin này lên, tất cả mọi người dùng tiện ích mở rộng này sẽ bỏ qua đoạn quảng cáo đó. Bạn cũng có thể bỏ qua phần không có nhạc trong những video âm nhạc.", "message": "SponsorBlock giúp bạn bỏ qua quảng cáo từ nhà tài trợ, đoạn giới thiệu, đoạn kết, lời nhắc đăng ký kênh, và những phần khó chịu khác trong các video Youtube. SponsorBlock là một tiện ích mở rộng cho trình duyệt, cho phép tất cả người dùng đăng thời điểm bắt đầu và kết thúc của những đoạn quảng cáo từ nhà tài trợ và các đoạn khác trong video Youtube. Sau khi một người đăng thông tin này lên, tất cả mọi người dùng tiện ích mở rộng này sẽ bỏ qua đoạn quảng cáo đó. Bạn cũng có thể bỏ qua phần không có nhạc trong những video âm nhạc.",
"description": "Full description of the extension on the store pages." "description": "Full description of the extension on the store pages."
@@ -335,9 +353,6 @@
"changeUserID": { "changeUserID": {
"message": "Nhập/Xuất mã người dùng của bạn" "message": "Nhập/Xuất mã người dùng của bạn"
}, },
"whatChangeUserID": {
"message": "Bạn nên giữ bí mật mã này. Nó như mật khẩu vậy, do đó không nên chia sẻ với người khác. Nếu ai đó có mã này, họ có thể giả mạo bạn."
},
"setUserID": { "setUserID": {
"message": "Đặt mã người dùng" "message": "Đặt mã người dùng"
}, },
@@ -682,5 +697,20 @@
"voteRejectedWarning": { "voteRejectedWarning": {
"message": "Bỏ phiếu bị từ chối do có cảnh báo. Nhấp để mở cuộc trò chuyện để giải quyết hoặc quay lại sau.", "message": "Bỏ phiếu bị từ chối do có cảnh báo. Nhấp để mở cuộc trò chuyện để giải quyết hoặc quay lại sau.",
"description": "This is an integrated chat panel that will appearing allowing them to talk to the Discord/Matrix chat without leaving their browser." "description": "This is an integrated chat panel that will appearing allowing them to talk to the Discord/Matrix chat without leaving their browser."
},
"Donate": {
"message": "Donate"
},
"hideDonationLink": {
"message": "Ẩn link donate"
},
"helpPageThanksForInstalling": {
"message": "Cảm ơn bạn đã cài đặt SponsorBlock."
},
"helpPageReviewOptions": {
"message": "Xin hãy xem xét các tuỳ chọn bên dưới"
},
"helpPageTooSlow": {
"message": "Quá chậm"
} }
} }

View File

@@ -323,9 +323,6 @@
"changeUserID": { "changeUserID": {
"message": "导入/导出您的用户 ID" "message": "导入/导出您的用户 ID"
}, },
"whatChangeUserID": {
"message": "这应该被保密。这就像一个密码,且不应该告诉任何人。如果有人拥有它,他就可以冒充您。"
},
"setUserID": { "setUserID": {
"message": "设定用户 ID" "message": "设定用户 ID"
}, },

View File

@@ -335,9 +335,6 @@
"changeUserID": { "changeUserID": {
"message": "匯入/匯出您的使用者 ID" "message": "匯入/匯出您的使用者 ID"
}, },
"whatChangeUserID": {
"message": "這應該被保密。這就像一個密碼,不應該與他人分享。如果有人擁有它,他們就可以冒充您。"
},
"setUserID": { "setUserID": {
"message": "設定使用者 ID" "message": "設定使用者 ID"
}, },

View File

@@ -140,7 +140,6 @@
min-width: 350px; min-width: 350px;
max-width: 50%; max-width: 50%;
border-radius: 5px;
border-spacing: 5px 10px; border-spacing: 5px 10px;
padding-left: 5px; padding-left: 5px;
padding-right: 5px; padding-right: 5px;
@@ -148,13 +147,20 @@
border-collapse: unset; border-collapse: unset;
} }
.sponsorSkipNotice { .sponsorSkipNoticeTableContainer {
min-width: 350px;
background-color: rgba(28, 28, 28, 0.9); background-color: rgba(28, 28, 28, 0.9);
border-radius: 5px;
min-width: 100%;
}
.sponsorSkipNotice {
transition: all 0.1s ease-out; transition: all 0.1s ease-out;
} }
.sponsorSkipNoticeLimitWidth {
min-width: calc(100% - 50px);
}
.sponsorSkipNotice .hidden { .sponsorSkipNotice .hidden {
display: none; display: none;
} }
@@ -311,7 +317,6 @@
.sponsorTimesInfoMessage { .sponsorTimesInfoMessage {
font-size: 13.3333px; font-size: 13.3333px;
color: rgb(235, 235, 235); color: rgb(235, 235, 235);
text-align: center;
} }
.voteButton { .voteButton {
@@ -467,7 +472,7 @@ input::-webkit-inner-spin-button {
text-decoration: underline; text-decoration: underline;
} }
.sponsorTimeCategories { .sponsorTimeEditSelector {
margin-top: 5px; margin-top: 5px;
margin-bottom: 5px; margin-bottom: 5px;

View File

@@ -119,7 +119,7 @@
<a href="https://github.com/ajayyy/SponsorBlockServer/graphs/contributors">SponsorBlockServer contributors</a> and <a href="https://github.com/ajayyy/SponsorBlockServer/graphs/contributors">SponsorBlockServer contributors</a> and
<a href="https://github.com/ajayyy/SponsorBlockSite/graphs/contributors">SponsorBlockSite contributors</a> such <a href="https://github.com/ajayyy/SponsorBlockSite/graphs/contributors">SponsorBlockSite contributors</a> such
as <a href="https://github.com/NDevTK">NDev</a>, <a href="https://github.com/Joe-Dowd">Joe Dowd</a>, as <a href="https://github.com/NDevTK">NDev</a>, <a href="https://github.com/Joe-Dowd">Joe Dowd</a>,
<a href="https://github.com/bershanskiy">Anton Bershanskiy</a> and more. <a href="https://mchang.name/">Michael Chang</a> and more.
</p> </p>
<p>The awesome <a href="https://github.com/omarroth/invidious/wiki/API">Invidious API</a> is used to grab the time the video was published.</p> <p>The awesome <a href="https://github.com/omarroth/invidious/wiki/API">Invidious API</a> is used to grab the time the video was published.</p>

View File

@@ -50,6 +50,22 @@
<br/> <br/>
</div> </div>
<div option-type="toggle" sync-option="muteSegments">
<label class="switch-container">
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>
<div class="switch-label">
__MSG_muteSegments__
</div>
</label>
<br/>
<br/>
<br/>
</div>
<br/> <br/>
<br/> <br/>

View File

@@ -265,7 +265,7 @@ background-color:#ec1c1c;
align-items: center; align-items: center;
} }
.sbSlimButton, #additionalButtons>button, button#setUsernameButton, #submitUsername { .sbSlimButton, #additionalButtons>button, button#setUsernameButton, #submitUsername, #copyUserID {
background: none; background: none;
border: none; border: none;
color: white; color: white;
@@ -341,6 +341,14 @@ label>p, #disableExtension>p, #usernameValue, #usernameElement > div > p,#sponso
cursor: pointer; cursor: pointer;
} }
#copyUserID {
width: 100%;
}
#setUsernameContainer {
display: flex;
}
#usernameElement > div, #sponsorTimesContributionsContainer > div { #usernameElement > div, #sponsorTimesContributionsContainer > div {
display: flex; display: flex;
flex-flow: column nowrap; flex-flow: column nowrap;

View File

@@ -19,7 +19,7 @@
<p id="loadingIndicator">__MSG_noVideoID__</p> <p id="loadingIndicator">__MSG_noVideoID__</p>
<!-- If the video was found in the database --> <!-- If the video was found in the database -->
<p id="videoFound"></p> <p id="videoFound"></p>
<button class="sbSlimButton hidden" id="refreshSegmentsButton" title="__MSG_refreshSegments__"> <button class="sbSlimButton" id="refreshSegmentsButton" title="__MSG_refreshSegments__">
<img id="refreshSegments" src="/icons/refresh.svg"/> <img id="refreshSegments" src="/icons/refresh.svg"/>
</button> </button>
</div> </div>
@@ -90,6 +90,9 @@
<button id="setUsernameButton" title="__MSG_setUsername__"> <button id="setUsernameButton" title="__MSG_setUsername__">
<img src="/icons/pencil.svg" alt="__MSG_setUsername__" width="16" height="16" id="sbPopupIconEdit"> <img src="/icons/pencil.svg" alt="__MSG_setUsername__" width="16" height="16" id="sbPopupIconEdit">
</button> </button>
<button id="copyUserID" title="__MSG_copyPublicID__">
<img src="/icons/clipboard.svg" alt="__MSG_copyPublicID__" width="16" height="16" id="sbPopupIconCopyUserID">
</button>
</div> </div>
<div id="setUsername" style="display: none"> <div id="setUsername" style="display: none">
<div id="setUsernameStatusContainer" style="display: none"> <div id="setUsernameStatusContainer" style="display: none">

View File

@@ -25,6 +25,7 @@ export interface NoticeProps {
bottomRow?: React.ReactElement[], bottomRow?: React.ReactElement[],
smaller?: boolean, smaller?: boolean,
limitWidth?: boolean,
// Callback for when this is closed // Callback for when this is closed
closeListener: () => void, closeListener: () => void,
@@ -102,13 +103,16 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
onMouseEnter={(e) => this.onMouseEnter(e) } onMouseEnter={(e) => this.onMouseEnter(e) }
onMouseLeave={() => this.timerMouseLeave()} onMouseLeave={() => this.timerMouseLeave()}
style={noticeStyle} > style={noticeStyle} >
<table className={"sponsorSkipObject sponsorSkipNotice" <div className={"sponsorSkipNoticeTableContainer"
+ (this.props.fadeIn ? " sponsorSkipNoticeFadeIn" : "") + (this.props.fadeIn ? " sponsorSkipNoticeFadeIn" : "")
+ (this.state.startFaded ? " sponsorSkipNoticeFaded" : "") }> + (this.state.startFaded ? " sponsorSkipNoticeFaded" : "") }>
<table className={"sponsorSkipObject sponsorSkipNotice"
+ (this.props.limitWidth ? " sponsorSkipNoticeLimitWidth" : "")}>
<tbody> <tbody>
{/* First row */} {/* First row */}
<tr id={"sponsorSkipNoticeFirstRow" + this.idSuffix}> <tr id={"sponsorSkipNoticeFirstRow" + this.idSuffix}
className="sponsorSkipNoticeFirstRow">
{/* Left column */} {/* Left column */}
<td className="noticeLeftIcon"> <td className="noticeLeftIcon">
{/* Logo */} {/* Logo */}
@@ -161,6 +165,7 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
</tbody> </tbody>
</table> </table>
</div>
{/* Add as a hidden table to keep the height constant */} {/* Add as a hidden table to keep the height constant */}
{this.props.smaller && this.props.bottomRow ? {this.props.smaller && this.props.bottomRow ?

View File

@@ -1,7 +1,7 @@
import * as React from "react"; import * as React from "react";
import * as CompileConfig from "../../config.json"; import * as CompileConfig from "../../config.json";
import Config from "../config" import Config from "../config"
import { Category, ContentContainer, CategoryActionType, SponsorHideType, SponsorTime, NoticeVisbilityMode } from "../types"; import { Category, ContentContainer, CategoryActionType, SponsorHideType, SponsorTime, NoticeVisbilityMode, ActionType } from "../types";
import NoticeComponent from "./NoticeComponent"; import NoticeComponent from "./NoticeComponent";
import NoticeTextSelectionComponent from "./NoticeTextSectionComponent"; import NoticeTextSelectionComponent from "./NoticeTextSectionComponent";
@@ -39,8 +39,9 @@ export interface SkipNoticeState {
maxCountdownTime?: () => number; maxCountdownTime?: () => number;
countdownText?: string; countdownText?: string;
unskipText?: string; skipButtonText?: string;
unskipCallback?: (index: number) => void; skipButtonCallback?: (index: number) => void;
showSkipButton?: boolean;
downvoting?: boolean; downvoting?: boolean;
choosingCategory?: boolean; choosingCategory?: boolean;
@@ -110,8 +111,9 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
countdownTime: Config.config.skipNoticeDuration, countdownTime: Config.config.skipNoticeDuration,
countdownText: null, countdownText: null,
unskipText: chrome.i18n.getMessage("unskip"), skipButtonText: this.getUnskipText(),
unskipCallback: (index) => this.unskip(index), skipButtonCallback: (index) => this.unskip(index),
showSkipButton: true,
downvoting: false, downvoting: false,
choosingCategory: false, choosingCategory: false,
@@ -126,7 +128,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
if (!this.autoSkip) { if (!this.autoSkip) {
// Assume manual skip is only skipping 1 submission // Assume manual skip is only skipping 1 submission
Object.assign(this.state, this.getUnskippedModeInfo(0, chrome.i18n.getMessage("skip"))); Object.assign(this.state, this.getUnskippedModeInfo(0, this.getSkipText()));
} }
} }
@@ -165,6 +167,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
ref={this.noticeRef} ref={this.noticeRef}
closeListener={() => this.closeListener()} closeListener={() => this.closeListener()}
smaller={this.state.smaller} smaller={this.state.smaller}
limitWidth={true}
firstColumn={firstColumn} firstColumn={firstColumn}
bottomRow={[...this.getMessageBoxes(), ...this.getBottomRow() ]} bottomRow={[...this.getMessageBoxes(), ...this.getBottomRow() ]}
onMouseEnter={() => this.onMouseEnter() } > onMouseEnter={() => this.onMouseEnter() } >
@@ -296,9 +299,9 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
} }
getSkipButton(): JSX.Element { getSkipButton(): JSX.Element {
if (this.segments.length > 1 if (this.state.showSkipButton && (this.segments.length > 1
|| getCategoryActionType(this.segments[0].category) !== CategoryActionType.POI || getCategoryActionType(this.segments[0].category) !== CategoryActionType.POI
|| this.props.unskipTime) { || this.props.unskipTime)) {
return ( return (
<span className="sponsorSkipNoticeUnskipSection"> <span className="sponsorSkipNoticeUnskipSection">
<button id={"sponsorSkipUnskipButton" + this.idSuffix} <button id={"sponsorSkipUnskipButton" + this.idSuffix}
@@ -306,7 +309,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
style={{marginLeft: "4px"}} style={{marginLeft: "4px"}}
onClick={() => this.prepAction(SkipNoticeAction.Unskip)}> onClick={() => this.prepAction(SkipNoticeAction.Unskip)}>
{this.state.unskipText + (this.state.showKeybindHint ? " (" + Config.config.skipKeybind + ")" : "")} {this.state.skipButtonText + (this.state.showKeybindHint ? " (" + Config.config.skipKeybind + ")" : "")}
</button> </button>
</span> </span>
); );
@@ -396,7 +399,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
this.contentContainer().vote(undefined, this.segments[index].UUID, this.categoryOptionRef.current.value as Category, this) this.contentContainer().vote(undefined, this.segments[index].UUID, this.categoryOptionRef.current.value as Category, this)
break; break;
case SkipNoticeAction.Unskip: case SkipNoticeAction.Unskip:
this.state.unskipCallback(index); this.state.skipButtonCallback(index);
break; break;
} }
@@ -456,7 +459,29 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
unskip(index: number): void { unskip(index: number): void {
this.contentContainer().unskipSponsorTime(this.segments[index], this.props.unskipTime); this.contentContainer().unskipSponsorTime(this.segments[index], this.props.unskipTime);
this.unskippedMode(index, chrome.i18n.getMessage("reskip")); this.unskippedMode(index, this.getReskipText());
}
reskip(index: number): void {
this.contentContainer().reskipSponsorTime(this.segments[index]);
const newState: SkipNoticeState = {
skipButtonText: this.getUnskipText(),
skipButtonCallback: this.unskip.bind(this),
maxCountdownTime: () => Config.config.skipNoticeDuration,
countdownTime: Config.config.skipNoticeDuration
};
// See if the title should be changed
if (!this.autoSkip) {
newState.noticeTitle = chrome.i18n.getMessage("noticeTitle");
}
//reset countdown
this.setState(newState, () => {
this.noticeRef.current.resetCountdown();
});
} }
/** Sets up notice to be not skipped yet */ /** Sets up notice to be not skipped yet */
@@ -478,36 +503,14 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
} : this.state.maxCountdownTime; } : this.state.maxCountdownTime;
return { return {
unskipText: buttonText, skipButtonText: buttonText,
unskipCallback: (index) => this.reskip(index), skipButtonCallback: (index) => this.reskip(index),
// change max duration to however much of the sponsor is left // change max duration to however much of the sponsor is left
maxCountdownTime: maxCountdownTime, maxCountdownTime: maxCountdownTime,
countdownTime: maxCountdownTime() countdownTime: maxCountdownTime()
} as SkipNoticeState; } as SkipNoticeState;
} }
reskip(index: number): void {
this.contentContainer().reskipSponsorTime(this.segments[index]);
const newState: SkipNoticeState = {
unskipText: chrome.i18n.getMessage("unskip"),
unskipCallback: this.unskip.bind(this),
maxCountdownTime: () => Config.config.skipNoticeDuration,
countdownTime: Config.config.skipNoticeDuration
};
// See if the title should be changed
if (!this.autoSkip) {
newState.noticeTitle = chrome.i18n.getMessage("noticeTitle");
}
//reset countdown
this.setState(newState, () => {
this.noticeRef.current.resetCountdown();
});
}
afterVote(segment: SponsorTime, type: number, category: Category): void { afterVote(segment: SponsorTime, type: number, category: Category): void {
this.addVoteButtonInfo(chrome.i18n.getMessage("voted")); this.addVoteButtonInfo(chrome.i18n.getMessage("voted"));
@@ -558,6 +561,52 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
this.props.closeListener(); this.props.closeListener();
} }
unmutedListener(): void {
if (this.props.segments.length === 1
&& this.props.segments[0].actionType === ActionType.Mute
&& this.contentContainer().v.currentTime >= this.props.segments[0].segment[1]) {
this.setState({
showSkipButton: false
});
}
}
private getUnskipText(): string {
switch (this.props.segments[0].actionType) {
case ActionType.Mute: {
return chrome.i18n.getMessage("unmute");
}
case ActionType.Skip:
default: {
return chrome.i18n.getMessage("unskip");
}
}
}
private getReskipText(): string {
switch (this.props.segments[0].actionType) {
case ActionType.Mute: {
return chrome.i18n.getMessage("mute");
}
case ActionType.Skip:
default: {
return chrome.i18n.getMessage("reskip");
}
}
}
private getSkipText(): string {
switch (this.props.segments[0].actionType) {
case ActionType.Mute: {
return chrome.i18n.getMessage("mute");
}
case ActionType.Skip:
default: {
return chrome.i18n.getMessage("skip");
}
}
}
} }
export default SkipNoticeComponent; export default SkipNoticeComponent;

View File

@@ -1,12 +1,12 @@
import * as React from "react"; import * as React from "react";
import Config from "../config";
import * as CompileConfig from "../../config.json"; import * as CompileConfig from "../../config.json";
import Config from "../config";
import { ActionType, ActionTypes, Category, CategoryActionType, ContentContainer, SponsorTime } from "../types";
import Utils from "../utils"; import Utils from "../utils";
import { Category, CategoryActionType, ContentContainer, SponsorTime } from "../types";
import SubmissionNoticeComponent from "./SubmissionNoticeComponent";
import { getCategoryActionType } from "../utils/categoryUtils"; import { getCategoryActionType } from "../utils/categoryUtils";
import SubmissionNoticeComponent from "./SubmissionNoticeComponent";
const utils = new Utils(); const utils = new Utils();
export interface SponsorTimeEditProps { export interface SponsorTimeEditProps {
@@ -32,6 +32,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
idSuffix: string; idSuffix: string;
categoryOptionRef: React.RefObject<HTMLSelectElement>; categoryOptionRef: React.RefObject<HTMLSelectElement>;
actionTypeOptionRef: React.RefObject<HTMLSelectElement>;
configUpdateListener: () => void; configUpdateListener: () => void;
@@ -39,6 +40,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
super(props); super(props);
this.categoryOptionRef = React.createRef(); this.categoryOptionRef = React.createRef();
this.actionTypeOptionRef = React.createRef();
this.idSuffix = this.props.idSuffix; this.idSuffix = this.props.idSuffix;
@@ -171,7 +173,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
{/* Category */} {/* Category */}
<div style={{position: "relative"}}> <div style={{position: "relative"}}>
<select id={"sponsorTimeCategories" + this.idSuffix} <select id={"sponsorTimeCategories" + this.idSuffix}
className="sponsorTimeCategories" className="sponsorTimeEditSelector sponsorTimeCategories"
defaultValue={sponsorTime.category} defaultValue={sponsorTime.category}
ref={this.categoryOptionRef} ref={this.categoryOptionRef}
onChange={this.categorySelectionChange.bind(this)}> onChange={this.categorySelectionChange.bind(this)}>
@@ -188,6 +190,19 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
</a> </a>
</div> </div>
{/* Action Type */}
{getCategoryActionType(sponsorTime.category) === CategoryActionType.Skippable ? (
<div style={{position: "relative"}}>
<select id={"sponsorTimeActionTypes" + this.idSuffix}
className="sponsorTimeEditSelector sponsorTimeActionTypes"
defaultValue={sponsorTime.actionType}
ref={this.actionTypeOptionRef}
onChange={() => this.saveEditTimes()}>
{this.getActionTypeOptions()}
</select>
</div>
): ""}
<br/> <br/>
{/* Editing Tools */} {/* Editing Tools */}
@@ -269,6 +284,21 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
this.saveEditTimes(); this.saveEditTimes();
} }
getActionTypeOptions(): React.ReactElement[] {
const elements = [];
for (const actionType of ActionTypes) {
elements.push(
<option value={actionType}
key={actionType}>
{chrome.i18n.getMessage(actionType)}
</option>
);
}
return elements;
}
setTimeToNow(index: number): void { setTimeToNow(index: number): void {
this.setTimeTo(index, this.props.contentContainer().getRealCurrentTime()); this.setTimeTo(index, this.props.contentContainer().getRealCurrentTime());
} }
@@ -331,6 +361,8 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
} }
sponsorTimesSubmitting[this.props.index].category = this.categoryOptionRef.current.value as Category; sponsorTimesSubmitting[this.props.index].category = this.categoryOptionRef.current.value as Category;
sponsorTimesSubmitting[this.props.index].actionType =
this.actionTypeOptionRef?.current ? this.actionTypeOptionRef.current.value as ActionType : ActionType.Skip;
Config.config.segmentTimes.set(this.props.contentContainer().sponsorVideoID, sponsorTimesSubmitting); Config.config.segmentTimes.set(this.props.contentContainer().sponsorVideoID, sponsorTimesSubmitting);

View File

@@ -17,6 +17,7 @@ interface SBConfig {
submissionCountSinceCategories: number, // New count used to show the "Read The Guidelines!!" message submissionCountSinceCategories: number, // New count used to show the "Read The Guidelines!!" message
showTimeWithSkips: boolean, showTimeWithSkips: boolean,
disableSkipping: boolean, disableSkipping: boolean,
muteSegments: boolean,
trackViewCount: boolean, trackViewCount: boolean,
trackViewCountInPrivate: boolean, trackViewCountInPrivate: boolean,
dontShowNotice: boolean, dontShowNotice: boolean,
@@ -162,6 +163,7 @@ const Config: SBObject = {
submissionCountSinceCategories: 0, submissionCountSinceCategories: 0,
showTimeWithSkips: true, showTimeWithSkips: true,
disableSkipping: false, disableSkipping: false,
muteSegments: true,
trackViewCount: true, trackViewCount: true,
trackViewCountInPrivate: true, trackViewCountInPrivate: true,
dontShowNotice: false, dontShowNotice: false,

View File

@@ -1,5 +1,5 @@
import Config from "./config"; import Config from "./config";
import { SponsorTime, CategorySkipOption, VideoID, SponsorHideType, VideoInfo, StorageChangesObject, CategoryActionType, ChannelIDInfo, ChannelIDStatus, SponsorSourceType, SegmentUUID, Category, SkipToTimeParams, ToggleSkippable } from "./types"; import { SponsorTime, CategorySkipOption, VideoID, SponsorHideType, VideoInfo, StorageChangesObject, CategoryActionType, ChannelIDInfo, ChannelIDStatus, SponsorSourceType, SegmentUUID, Category, SkipToTimeParams, ToggleSkippable, ActionType, ScheduledTime } from "./types";
import { ContentContainer } from "./types"; import { ContentContainer } from "./types";
import Utils from "./utils"; import Utils from "./utils";
@@ -45,6 +45,7 @@ let sponsorSkipped: boolean[] = [];
//the video //the video
let video: HTMLVideoElement; let video: HTMLVideoElement;
let videoMuted = false; // Has it been attempted to be muted
let videoMutationObserver: MutationObserver = null; let videoMutationObserver: MutationObserver = null;
// List of videos that have had event listeners added to them // List of videos that have had event listeners added to them
const videosWithEventListeners: HTMLVideoElement[] = []; const videosWithEventListeners: HTMLVideoElement[] = [];
@@ -396,7 +397,6 @@ function cancelSponsorSchedule(): void {
} }
/** /**
*
* @param currentTime Optional if you don't want to use the actual current time * @param currentTime Optional if you don't want to use the actual current time
*/ */
function startSponsorSchedule(includeIntersectingSegments = false, currentTime?: number, includeNonIntersectingSegments = true): void { function startSponsorSchedule(includeIntersectingSegments = false, currentTime?: number, includeNonIntersectingSegments = true): void {
@@ -412,6 +412,17 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
} }
if (!video || video.paused) return; if (!video || video.paused) return;
if (currentTime === undefined || currentTime === null) currentTime = video.currentTime;
if (videoMuted && !inMuteSegment(currentTime)) {
video.muted = false;
videoMuted = false;
for (const notice of skipNotices) {
// So that the notice can hide buttons
notice.unmutedListener();
}
}
if (Config.config.disableSkipping || channelWhitelisted || (channelIDInfo.status === ChannelIDStatus.Fetching && Config.config.forceChannelCheck)){ if (Config.config.disableSkipping || channelWhitelisted || (channelIDInfo.status === ChannelIDStatus.Fetching && Config.config.forceChannelCheck)){
return; return;
@@ -419,14 +430,12 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
if (incorrectVideoCheck()) return; if (incorrectVideoCheck()) return;
if (currentTime === undefined || currentTime === null) currentTime = video.currentTime;
const skipInfo = getNextSkipIndex(currentTime, includeIntersectingSegments, includeNonIntersectingSegments); const skipInfo = getNextSkipIndex(currentTime, includeIntersectingSegments, includeNonIntersectingSegments);
if (skipInfo.index === -1) return; if (skipInfo.index === -1) return;
const currentSkip = skipInfo.array[skipInfo.index]; const currentSkip = skipInfo.array[skipInfo.index];
const skipTime: number[] = [currentSkip.segment[0], skipInfo.array[skipInfo.endIndex].segment[1]]; const skipTime: number[] = [currentSkip.scheduledTime, skipInfo.array[skipInfo.endIndex].segment[1]];
const timeUntilSponsor = skipTime[0] - currentTime; const timeUntilSponsor = skipTime[0] - currentTime;
const videoID = sponsorVideoID; const videoID = sponsorVideoID;
@@ -461,7 +470,8 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
openNotice: skipInfo.openNotice openNotice: skipInfo.openNotice
}); });
if (utils.getCategorySelection(currentSkip.category)?.option === CategorySkipOption.ManualSkip) { if (utils.getCategorySelection(currentSkip.category)?.option === CategorySkipOption.ManualSkip
|| currentSkip.actionType === ActionType.Mute) {
forcedSkipTime = skipTime[0] + 0.001; forcedSkipTime = skipTime[0] + 0.001;
} else { } else {
forcedSkipTime = skipTime[1]; forcedSkipTime = skipTime[1];
@@ -480,12 +490,19 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
} }
} }
function inMuteSegment(currentTime: number): boolean {
const checkFunction = (segment) => segment.actionType === ActionType.Mute && segment.segment[0] <= currentTime && segment.segment[1] > currentTime;
return sponsorTimes?.some(checkFunction) || sponsorTimesSubmitting.some(checkFunction);
}
/** /**
* This makes sure the videoID is still correct and if the sponsorTime is included * This makes sure the videoID is still correct and if the sponsorTime is included
*/ */
function incorrectVideoCheck(videoID?: string, sponsorTime?: SponsorTime): boolean { function incorrectVideoCheck(videoID?: string, sponsorTime?: SponsorTime): boolean {
const currentVideoID = getYouTubeVideoID(document.URL); const currentVideoID = getYouTubeVideoID(document.URL);
if (currentVideoID !== (videoID || sponsorVideoID) || (sponsorTime && (!sponsorTimes || !sponsorTimes.includes(sponsorTime)) && !sponsorTimesSubmitting.includes(sponsorTime))) { if (currentVideoID !== (videoID || sponsorVideoID) || (sponsorTime
&& (!sponsorTimes || !sponsorTimes?.some((time) => time.segment === sponsorTime.segment))
&& !sponsorTimesSubmitting.some((time) => time.segment === sponsorTime.segment))) {
// Something has really gone wrong // Something has really gone wrong
console.error("[SponsorBlock] The videoID recorded when trying to skip is different than what it should be."); console.error("[SponsorBlock] The videoID recorded when trying to skip is different than what it should be.");
console.error("[SponsorBlock] VideoID recorded: " + sponsorVideoID + ". Actual VideoID: " + currentVideoID); console.error("[SponsorBlock] VideoID recorded: " + sponsorVideoID + ". Actual VideoID: " + currentVideoID);
@@ -575,7 +592,7 @@ function setupVideoListeners() {
} }
if (!Config.config.dontShowNotice) { if (!Config.config.dontShowNotice) {
const currentPoiSegment = sponsorTimes.find((segment) => const currentPoiSegment = sponsorTimes?.find((segment) =>
getCategoryActionType(segment.category) === CategoryActionType.POI && getCategoryActionType(segment.category) === CategoryActionType.POI &&
video.currentTime - segment.segment[0] > 0 && video.currentTime - segment.segment[0] > 0 &&
video.currentTime - segment.segment[0] < previewBar.getMinimumSize(true)); video.currentTime - segment.segment[0] < previewBar.getMinimumSize(true));
@@ -644,6 +661,7 @@ async function sponsorsLookup(id: string, keepOldSubmissions = true) {
const hashPrefix = (await utils.getHash(id, 1)).substr(0, 4); const hashPrefix = (await utils.getHash(id, 1)).substr(0, 4);
const response = await utils.asyncRequestToServer('GET', "/api/skipSegments/" + hashPrefix, { const response = await utils.asyncRequestToServer('GET', "/api/skipSegments/" + hashPrefix, {
categories, categories,
actionTypes: Config.config.muteSegments ? [ActionType.Skip, ActionType.Mute] : [ActionType.Skip],
userAgent: `${chrome.runtime.id}` userAgent: `${chrome.runtime.id}`
}); });
@@ -945,31 +963,33 @@ async function whitelistCheck() {
* Returns info about the next upcoming sponsor skip * Returns info about the next upcoming sponsor skip
*/ */
function getNextSkipIndex(currentTime: number, includeIntersectingSegments: boolean, includeNonIntersectingSegments: boolean): function getNextSkipIndex(currentTime: number, includeIntersectingSegments: boolean, includeNonIntersectingSegments: boolean):
{array: SponsorTime[], index: number, endIndex: number, openNotice: boolean} { {array: ScheduledTime[], index: number, endIndex: number, openNotice: boolean} {
const sponsorStartTimes = getStartTimes(sponsorTimes, includeIntersectingSegments, includeNonIntersectingSegments); const { includedTimes: submittedArray, startTimeIndexes: sponsorStartTimes } =
const sponsorStartTimesAfterCurrentTime = getStartTimes(sponsorTimes, includeIntersectingSegments, includeNonIntersectingSegments, currentTime, true, true); getStartTimes(sponsorTimes, includeIntersectingSegments, includeNonIntersectingSegments);
const { startTimeIndexes: sponsorStartTimesAfterCurrentTime } = getStartTimes(sponsorTimes, includeIntersectingSegments, includeNonIntersectingSegments, currentTime, true, true);
const minSponsorTimeIndex = sponsorStartTimes.indexOf(Math.min(...sponsorStartTimesAfterCurrentTime)); const minSponsorTimeIndex = sponsorStartTimes.indexOf(Math.min(...sponsorStartTimesAfterCurrentTime));
const endTimeIndex = getLatestEndTimeIndex(sponsorTimes, minSponsorTimeIndex); const endTimeIndex = getLatestEndTimeIndex(submittedArray, minSponsorTimeIndex);
const unsubmittedSponsorStartTimes = getStartTimes(sponsorTimesSubmitting, includeIntersectingSegments, includeNonIntersectingSegments); const { includedTimes: unsubmittedArray, startTimeIndexes: unsubmittedSponsorStartTimes } =
const unsubmittedSponsorStartTimesAfterCurrentTime = getStartTimes(sponsorTimesSubmitting, includeIntersectingSegments, includeNonIntersectingSegments, currentTime, false, false); getStartTimes(sponsorTimesSubmitting, includeIntersectingSegments, includeNonIntersectingSegments);
const { startTimeIndexes: unsubmittedSponsorStartTimesAfterCurrentTime } = getStartTimes(sponsorTimesSubmitting, includeIntersectingSegments, includeNonIntersectingSegments, currentTime, false, false);
const minUnsubmittedSponsorTimeIndex = unsubmittedSponsorStartTimes.indexOf(Math.min(...unsubmittedSponsorStartTimesAfterCurrentTime)); const minUnsubmittedSponsorTimeIndex = unsubmittedSponsorStartTimes.indexOf(Math.min(...unsubmittedSponsorStartTimesAfterCurrentTime));
const previewEndTimeIndex = getLatestEndTimeIndex(sponsorTimesSubmitting, minUnsubmittedSponsorTimeIndex); const previewEndTimeIndex = getLatestEndTimeIndex(unsubmittedArray, minUnsubmittedSponsorTimeIndex);
if ((minUnsubmittedSponsorTimeIndex === -1 && minSponsorTimeIndex !== -1) || if ((minUnsubmittedSponsorTimeIndex === -1 && minSponsorTimeIndex !== -1) ||
sponsorStartTimes[minSponsorTimeIndex] < unsubmittedSponsorStartTimes[minUnsubmittedSponsorTimeIndex]) { sponsorStartTimes[minSponsorTimeIndex] < unsubmittedSponsorStartTimes[minUnsubmittedSponsorTimeIndex]) {
return { return {
array: sponsorTimes.filter((segment) => getCategoryActionType(segment.category) === CategoryActionType.Skippable), array: submittedArray,
index: minSponsorTimeIndex, index: minSponsorTimeIndex,
endIndex: endTimeIndex, endIndex: endTimeIndex,
openNotice: true openNotice: true
}; };
} else { } else {
return { return {
array: sponsorTimesSubmitting.filter((segment) => getCategoryActionType(segment.category) === CategoryActionType.Skippable), array: unsubmittedArray,
index: minUnsubmittedSponsorTimeIndex, index: minUnsubmittedSponsorTimeIndex,
endIndex: previewEndTimeIndex, endIndex: previewEndTimeIndex,
openNotice: false openNotice: false
@@ -993,7 +1013,10 @@ function getNextSkipIndex(currentTime: number, includeIntersectingSegments: bool
function getLatestEndTimeIndex(sponsorTimes: SponsorTime[], index: number, hideHiddenSponsors = true): number { function getLatestEndTimeIndex(sponsorTimes: SponsorTime[], index: number, hideHiddenSponsors = true): number {
// Only combine segments for AutoSkip // Only combine segments for AutoSkip
if (index == -1 || if (index == -1 ||
shouldAutoSkip(sponsorTimes[index])) return index; !shouldAutoSkip(sponsorTimes[index])
|| sponsorTimes[index].actionType !== ActionType.Skip) {
return index;
}
// Default to the normal endTime // Default to the normal endTime
let latestEndTimeIndex = index; let latestEndTimeIndex = index;
@@ -1004,7 +1027,8 @@ function getLatestEndTimeIndex(sponsorTimes: SponsorTime[], index: number, hideH
if (currentSegment[0] <= latestEndTime && currentSegment[1] > latestEndTime if (currentSegment[0] <= latestEndTime && currentSegment[1] > latestEndTime
&& (!hideHiddenSponsors || sponsorTimes[i].hidden === SponsorHideType.Visible) && (!hideHiddenSponsors || sponsorTimes[i].hidden === SponsorHideType.Visible)
&& shouldAutoSkip(sponsorTimes[i])) { && shouldAutoSkip(sponsorTimes[i])
&& sponsorTimes[i].actionType === ActionType.Skip) {
// Overlapping segment // Overlapping segment
latestEndTimeIndex = i; latestEndTimeIndex = i;
} }
@@ -1029,24 +1053,43 @@ function getLatestEndTimeIndex(sponsorTimes: SponsorTime[], index: number, hideH
* the current time, but end after * the current time, but end after
*/ */
function getStartTimes(sponsorTimes: SponsorTime[], includeIntersectingSegments: boolean, includeNonIntersectingSegments: boolean, function getStartTimes(sponsorTimes: SponsorTime[], includeIntersectingSegments: boolean, includeNonIntersectingSegments: boolean,
minimum?: number, onlySkippableSponsors = false, hideHiddenSponsors = false): number[] { minimum?: number, onlySkippableSponsors = false, hideHiddenSponsors = false): {includedTimes: ScheduledTime[], startTimeIndexes: number[]} {
if (sponsorTimes === null) return []; if (!sponsorTimes) return {includedTimes: [], startTimeIndexes: []};
const startTimes: number[] = []; const includedTimes: ScheduledTime[] = [];
const startTimeIndexes: number[] = [];
for (let i = 0; i < sponsorTimes?.length; i++) { const possibleTimes = sponsorTimes.flatMap((sponsorTime) => {
const results = [{
...sponsorTime,
scheduledTime: sponsorTime.segment[0]
}]
if (sponsorTime.actionType === ActionType.Mute) {
// Schedule at the end time to know when to unmute
results.push({
...sponsorTime,
scheduledTime: sponsorTime.segment[1]
})
}
return results;
})
for (let i = 0; i < possibleTimes.length; i++) {
if ((minimum === undefined if ((minimum === undefined
|| ((includeNonIntersectingSegments && sponsorTimes[i].segment[0] >= minimum) || ((includeNonIntersectingSegments && possibleTimes[i].scheduledTime >= minimum)
|| (includeIntersectingSegments && sponsorTimes[i].segment[0] < minimum && sponsorTimes[i].segment[1] > minimum))) || (includeIntersectingSegments && possibleTimes[i].scheduledTime < minimum && possibleTimes[i].segment[1] > minimum)))
&& (!onlySkippableSponsors || shouldSkip(sponsorTimes[i])) && (!onlySkippableSponsors || shouldSkip(possibleTimes[i]))
&& (!hideHiddenSponsors || sponsorTimes[i].hidden === SponsorHideType.Visible) && (!hideHiddenSponsors || possibleTimes[i].hidden === SponsorHideType.Visible)
&& getCategoryActionType(sponsorTimes[i].category) === CategoryActionType.Skippable) { && getCategoryActionType(possibleTimes[i].category) === CategoryActionType.Skippable) {
startTimes.push(sponsorTimes[i].segment[0]); startTimeIndexes.push(possibleTimes[i].scheduledTime);
includedTimes.push(possibleTimes[i]);
} }
} }
return startTimes; return { includedTimes, startTimeIndexes };
} }
/** /**
@@ -1085,10 +1128,15 @@ function sendTelemetryAndCount(skippingSegments: SponsorTime[], secondsSkipped:
//skip from the start time to the end time for a certain index sponsor time //skip from the start time to the end time for a certain index sponsor time
function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, unskipTime}: SkipToTimeParams): void { function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, unskipTime}: SkipToTimeParams): void {
if (Config.config.disableSkipping) return;
// There will only be one submission if it is manual skip // There will only be one submission if it is manual skip
const autoSkip: boolean = forceAutoSkip || shouldAutoSkip(skippingSegments[0]); const autoSkip: boolean = forceAutoSkip || shouldAutoSkip(skippingSegments[0]);
if ((autoSkip || sponsorTimesSubmitting.includes(skippingSegments[0])) && v.currentTime !== skipTime[1]) { if ((autoSkip || sponsorTimesSubmitting.some((time) => time.segment === skippingSegments[0].segment))
&& v.currentTime !== skipTime[1]) {
switch(skippingSegments[0].actionType) {
case ActionType.Skip: {
// Fix for looped videos not working when skipping to the end #426 // Fix for looped videos not working when skipping to the end #426
// for some reason you also can't skip to 1 second before the end // for some reason you also can't skip to 1 second before the end
if (v.loop && v.duration > 1 && skipTime[1] >= v.duration - 1) { if (v.loop && v.duration > 1 && skipTime[1] >= v.duration - 1) {
@@ -1096,6 +1144,18 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u
} else { } else {
v.currentTime = skipTime[1]; v.currentTime = skipTime[1];
} }
break;
}
case ActionType.Mute: {
if (!v.muted) {
v.muted = true;
videoMuted = true;
}
break;
}
}
} }
if (!autoSkip if (!autoSkip
@@ -1135,12 +1195,21 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u
} }
function unskipSponsorTime(segment: SponsorTime, unskipTime: number = null) { function unskipSponsorTime(segment: SponsorTime, unskipTime: number = null) {
if (segment.actionType === ActionType.Mute) {
video.muted = false;
videoMuted = false;
} else {
//add a tiny bit of time to make sure it is not skipped again //add a tiny bit of time to make sure it is not skipped again
console.log(unskipTime)
video.currentTime = unskipTime ?? segment.segment[0] + 0.001; video.currentTime = unskipTime ?? segment.segment[0] + 0.001;
} }
}
function reskipSponsorTime(segment: SponsorTime) { function reskipSponsorTime(segment: SponsorTime) {
if (segment.actionType === ActionType.Mute) {
video.muted = true;
videoMuted = true;
} else {
const skippedTime = Math.max(segment.segment[1] - video.currentTime, 0); const skippedTime = Math.max(segment.segment[1] - video.currentTime, 0);
const segmentDuration = segment.segment[1] - segment.segment[0]; const segmentDuration = segment.segment[1] - segment.segment[0];
const fullSkip = skippedTime / segmentDuration > manualSkipPercentCount; const fullSkip = skippedTime / segmentDuration > manualSkipPercentCount;
@@ -1149,6 +1218,7 @@ function reskipSponsorTime(segment: SponsorTime) {
sendTelemetryAndCount([segment], skippedTime, fullSkip); sendTelemetryAndCount([segment], skippedTime, fullSkip);
startSponsorSchedule(true, segment.segment[1], false); startSponsorSchedule(true, segment.segment[1], false);
} }
}
function createButton(baseID: string, title: string, callback: () => void, imageName: string, isDraggable = false): HTMLElement { function createButton(baseID: string, title: string, callback: () => void, imageName: string, isDraggable = false): HTMLElement {
const existingElement = document.getElementById(baseID + "Button"); const existingElement = document.getElementById(baseID + "Button");
@@ -1190,13 +1260,13 @@ function createButton(baseID: string, title: string, callback: () => void, image
function shouldAutoSkip(segment: SponsorTime): boolean { function shouldAutoSkip(segment: SponsorTime): boolean {
return utils.getCategorySelection(segment.category)?.option === CategorySkipOption.AutoSkip || return utils.getCategorySelection(segment.category)?.option === CategorySkipOption.AutoSkip ||
(Config.config.autoSkipOnMusicVideos && sponsorTimes.some((s) => s.category === "music_offtopic") (Config.config.autoSkipOnMusicVideos && sponsorTimes?.some((s) => s.category === "music_offtopic")
&& getCategoryActionType(segment.category) === CategoryActionType.Skippable); && getCategoryActionType(segment.category) === CategoryActionType.Skippable);
} }
function shouldSkip(segment: SponsorTime): boolean { function shouldSkip(segment: SponsorTime): boolean {
return utils.getCategorySelection(segment.category)?.option !== CategorySkipOption.ShowOverlay || return utils.getCategorySelection(segment.category)?.option !== CategorySkipOption.ShowOverlay ||
(Config.config.autoSkipOnMusicVideos && sponsorTimes.some((s) => s.category === "music_offtopic")); (Config.config.autoSkipOnMusicVideos && sponsorTimes?.some((s) => s.category === "music_offtopic"));
} }
function getControls(): HTMLElement | false { function getControls(): HTMLElement | false {
@@ -1330,6 +1400,7 @@ function startOrEndTimingNewSegment() {
segment: [getRealCurrentTime()], segment: [getRealCurrentTime()],
UUID: null, UUID: null,
category: Config.config.defaultCategory, category: Config.config.defaultCategory,
actionType: ActionType.Skip,
source: SponsorSourceType.Local source: SponsorSourceType.Local
}); });
} else { } else {
@@ -1386,6 +1457,7 @@ function updateSponsorTimesSubmitting(getFromConfig = true) {
segment: segmentTime.segment, segment: segmentTime.segment,
UUID: segmentTime.UUID, UUID: segmentTime.UUID,
category: segmentTime.category, category: segmentTime.category,
actionType: segmentTime.actionType,
source: segmentTime.source source: segmentTime.source
}); });
} }
@@ -1457,11 +1529,13 @@ function openInfoMenu() {
const logo = <HTMLImageElement> popup.querySelector("#sponsorBlockPopupLogo"); const logo = <HTMLImageElement> popup.querySelector("#sponsorBlockPopupLogo");
const settings = <HTMLImageElement> popup.querySelector("#sbPopupIconSettings"); const settings = <HTMLImageElement> popup.querySelector("#sbPopupIconSettings");
const edit = <HTMLImageElement> popup.querySelector("#sbPopupIconEdit"); const edit = <HTMLImageElement> popup.querySelector("#sbPopupIconEdit");
const copy = <HTMLImageElement> popup.querySelector("#sbPopupIconCopyUserID");
const check = <HTMLImageElement> popup.querySelector("#sbPopupIconCheck"); const check = <HTMLImageElement> popup.querySelector("#sbPopupIconCheck");
const refreshSegments = <HTMLImageElement> popup.querySelector("#refreshSegments"); const refreshSegments = <HTMLImageElement> popup.querySelector("#refreshSegments");
logo.src = chrome.extension.getURL("icons/IconSponsorBlocker256px.png"); logo.src = chrome.extension.getURL("icons/IconSponsorBlocker256px.png");
settings.src = chrome.extension.getURL("icons/settings.svg"); settings.src = chrome.extension.getURL("icons/settings.svg");
edit.src = chrome.extension.getURL("icons/pencil.svg"); edit.src = chrome.extension.getURL("icons/pencil.svg");
copy.src = chrome.extension.getURL("icons/clipboard.svg");
check.src = chrome.extension.getURL("icons/check.svg"); check.src = chrome.extension.getURL("icons/check.svg");
refreshSegments.src = chrome.extension.getURL("icons/refresh.svg"); refreshSegments.src = chrome.extension.getURL("icons/refresh.svg");

View File

@@ -1,9 +1,10 @@
import Config from "./config"; import Config from "./config";
import Utils from "./utils"; import Utils from "./utils";
import { SponsorTime, SponsorHideType } from "./types"; import { SponsorTime, SponsorHideType, CategoryActionType } from "./types";
import { Message, MessageResponse } from "./messageTypes"; import { Message, MessageResponse } from "./messageTypes";
import { showDonationLink } from "./utils/configUtils"; import { showDonationLink } from "./utils/configUtils";
import { getCategoryActionType } from "./utils/categoryUtils";
const utils = new Utils(); const utils = new Utils();
interface MessageListener { interface MessageListener {
@@ -96,6 +97,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
"usernameInput", "usernameInput",
"usernameValue", "usernameValue",
"submitUsername", "submitUsername",
"sbPopupIconCopyUserID",
// More // More
"submissionSection", "submissionSection",
"mainControls", "mainControls",
@@ -134,6 +136,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
PageElements.optionsButton.addEventListener("click", openOptions); PageElements.optionsButton.addEventListener("click", openOptions);
PageElements.helpButton.addEventListener("click", openHelp); PageElements.helpButton.addEventListener("click", openHelp);
PageElements.refreshSegmentsButton.addEventListener("click", refreshSegments); PageElements.refreshSegmentsButton.addEventListener("click", refreshSegments);
PageElements.sbPopupIconCopyUserID.addEventListener("click", async () => navigator.clipboard.writeText(await utils.getHash(Config.config.userID)));
/** If true, the content script is in the process of creating a new segment. */ /** If true, the content script is in the process of creating a new segment. */
let creatingSegment = false; let creatingSegment = false;
@@ -291,12 +294,10 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
if (request.found) { if (request.found) {
PageElements.videoFound.innerHTML = chrome.i18n.getMessage("sponsorFound"); PageElements.videoFound.innerHTML = chrome.i18n.getMessage("sponsorFound");
PageElements.refreshSegmentsButton.classList.remove("hidden");
displayDownloadedSponsorTimes(request); displayDownloadedSponsorTimes(request);
} else { } else {
PageElements.videoFound.innerHTML = chrome.i18n.getMessage("sponsor404"); PageElements.videoFound.innerHTML = chrome.i18n.getMessage("sponsor404");
PageElements.refreshSegmentsButton.classList.add("hidden");
} }
} }
@@ -401,7 +402,10 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
const textNode = document.createTextNode(utils.shortCategoryName(segmentTimes[i].category) + extraInfo); const textNode = document.createTextNode(utils.shortCategoryName(segmentTimes[i].category) + extraInfo);
const segmentTimeFromToNode = document.createElement("div"); const segmentTimeFromToNode = document.createElement("div");
segmentTimeFromToNode.innerText = utils.getFormattedTime(segmentTimes[i].segment[0], true) + " " + chrome.i18n.getMessage("to") + " " + utils.getFormattedTime(segmentTimes[i].segment[1], true); segmentTimeFromToNode.innerText = utils.getFormattedTime(segmentTimes[i].segment[0], true) +
(getCategoryActionType(segmentTimes[i].category) !== CategoryActionType.POI
? " " + chrome.i18n.getMessage("to") + " " + utils.getFormattedTime(segmentTimes[i].segment[1], true)
: "");
segmentTimeFromToNode.style.margin = "5px"; segmentTimeFromToNode.style.margin = "5px";
sponsorTimeButton.appendChild(categoryColorCircle); sponsorTimeButton.appendChild(categoryColorCircle);

View File

@@ -71,6 +71,10 @@ class SkipNotice {
toggleSkip(): void { toggleSkip(): void {
this.skipNoticeRef?.current?.prepAction(SkipNoticeAction.Unskip); this.skipNoticeRef?.current?.prepAction(SkipNoticeAction.Unskip);
} }
unmutedListener(): void {
this.skipNoticeRef?.current?.unmutedListener();
}
} }
export default SkipNotice; export default SkipNotice;

View File

@@ -56,6 +56,13 @@ export enum CategoryActionType {
POI = "_POI" POI = "_POI"
} }
export enum ActionType {
Skip = "skip",
Mute = "mute"
}
export const ActionTypes = [ActionType.Skip, ActionType.Mute];
export type SegmentUUID = string & { __segmentUUIDBrand: unknown }; export type SegmentUUID = string & { __segmentUUIDBrand: unknown };
export type Category = string & { __categoryBrand: unknown }; export type Category = string & { __categoryBrand: unknown };
@@ -69,11 +76,16 @@ export interface SponsorTime {
UUID: SegmentUUID; UUID: SegmentUUID;
category: Category; category: Category;
actionType: ActionType;
hidden?: SponsorHideType; hidden?: SponsorHideType;
source?: SponsorSourceType; source?: SponsorSourceType;
} }
export interface ScheduledTime extends SponsorTime {
scheduledTime: number;
}
export interface PreviewBarOption { export interface PreviewBarOption {
color: string, color: string,
opacity: string opacity: string

146
test/selenium.test.ts Normal file
View File

@@ -0,0 +1,146 @@
import { Builder, By, until, WebDriver } from "selenium-webdriver";
import * as Chrome from "selenium-webdriver/chrome";
import * as Path from "path";
test("Selenium Chrome test", async () => {
const driver = await setup();
try {
await waitForInstall(driver);
// This video has no ads
await goToVideo(driver, "jNQXAC9IVRw");
await createSegment(driver, "4", "10.33", "0:04.000 to 0:10.330");
await editSegments(driver, 0, "0:04.000", "0:10.330", "5", "13.211", "0:05.000 to 0:13.211", false);
await autoskipSegment(driver, 5, 13.211);
await setSegmentActionType(driver, 0, 1, false);
await editSegments(driver, 0, "0:05.000", "0:13.211", "5", "7.5", "0:05.000 to 0:07.500", false);
await muteSkipSegment(driver, 5, 7.5);
} finally {
await driver.quit();
}
}, 100_000);
async function setup(): Promise<WebDriver> {
const options = new Chrome.Options();
options.addArguments("--load-extension=" + Path.join(__dirname, "../dist/"));
options.addArguments("--mute-audio");
options.addArguments("--disable-features=PreloadMediaEngagementData, MediaEngagementBypassAutoplayPolicies");
const driver = await new Builder().forBrowser("chrome").setChromeOptions(options).build();
driver.manage().setTimeouts({
implicit: 5000
});
return driver;
}
async function waitForInstall(driver: WebDriver, startingTab = 0): Promise<void> {
// Selenium only knows about the one tab it's on,
// so we can't wait for the help page to appear
await driver.sleep(3000);
const handles = await driver.getAllWindowHandles();
await driver.switchTo().window(handles[startingTab]);
}
async function goToVideo(driver: WebDriver, videoId: string): Promise<void> {
await driver.get("https://www.youtube.com/watch?v=" + videoId);
await driver.wait(until.elementIsVisible(await driver.findElement(By.className("ytd-video-primary-info-renderer"))));
}
async function createSegment(driver: WebDriver, startTime: string, endTime: string, expectedDisplayedTime: string): Promise<void> {
const startSegmentButton = await driver.findElement(By.id("startSegmentButton"));
const cancelSegmentButton = await driver.findElement(By.id("cancelSegmentButton"));
await driver.executeScript("document.querySelector('video').currentTime = " + startTime);
await startSegmentButton.click();
await driver.wait(until.elementIsVisible(cancelSegmentButton));
await driver.executeScript("document.querySelector('video').currentTime = " + endTime);
await startSegmentButton.click();
await driver.wait(until.elementIsNotVisible(cancelSegmentButton));
const submitButton = await driver.findElement(By.id("submitButton"));
await submitButton.click();
const sponsorTimeDisplays = await driver.findElements(By.className("sponsorTimeDisplay"));
const sponsorTimeDisplay = sponsorTimeDisplays[sponsorTimeDisplays.length - 1];
await driver.wait(until.elementTextIs(sponsorTimeDisplay, expectedDisplayedTime));
}
async function editSegments(driver: WebDriver, index: number, expectedStartTimeBox: string, expectedEndTimeBox: string,
startTime: string, endTime: string, expectedDisplayedTime: string, openSubmitBox: boolean): Promise<void> {
if (openSubmitBox) {
const submitButton = await driver.findElement(By.id("submitButton"));
await submitButton.click();
}
let editButton = await driver.findElement(By.id("sponsorTimeEditButtonSubmissionNotice" + index));
let sponsorTimeDisplays = await driver.findElements(By.className("sponsorTimeDisplay"));
let sponsorTimeDisplay = sponsorTimeDisplays[index];
await sponsorTimeDisplay.click();
// Ensure edit time appears
await driver.findElement(By.id("submittingTime0SubmissionNotice" + index));
// Try the edit button too
await editButton.click();
await editButton.click();
const startTimeBox = await driver.findElement(By.id("submittingTime0SubmissionNotice" + index));
expect((await startTimeBox.getAttribute("value"))).toBe(expectedStartTimeBox);
await startTimeBox.clear();
await startTimeBox.sendKeys(startTime);
const endTimeBox = await driver.findElement(By.id("submittingTime1SubmissionNotice" + index));
expect((await endTimeBox.getAttribute("value"))).toBe(expectedEndTimeBox);
await endTimeBox.clear();
await endTimeBox.sendKeys(endTime);
editButton = await driver.findElement(By.id("sponsorTimeEditButtonSubmissionNotice" + index));
await editButton.click();
sponsorTimeDisplays = await driver.findElements(By.className("sponsorTimeDisplay"));
sponsorTimeDisplay = sponsorTimeDisplays[index];
await driver.wait(until.elementTextIs(sponsorTimeDisplay, expectedDisplayedTime));
}
async function setSegmentActionType(driver: WebDriver, index: number, actionTypeIndex: number, openSubmitBox: boolean): Promise<void> {
if (openSubmitBox) {
const submitButton = await driver.findElement(By.id("submitButton"));
await submitButton.click();
}
const actionTypeSelection = await driver.findElement(By.css(`#sponsorTimeActionTypesSubmissionNotice${index} > option:nth-child(${actionTypeIndex + 1})`));
actionTypeSelection.click();
}
async function autoskipSegment(driver: WebDriver, startTime: number, endTime: number): Promise<void> {
const video = await driver.findElement(By.css("video"));
await driver.executeScript("document.querySelector('video').currentTime = " + (startTime - 0.5));
await driver.executeScript("document.querySelector('video').play()");
await driver.sleep(1300);
expect(parseFloat(await video.getAttribute("currentTime"))).toBeGreaterThan(endTime);
await driver.executeScript("document.querySelector('video').pause()");
}
async function muteSkipSegment(driver: WebDriver, startTime: number, endTime: number): Promise<void> {
const duration = endTime - startTime;
const video = await driver.findElement(By.css("video"));
await driver.executeScript("document.querySelector('video').currentTime = " + (startTime - 0.5));
await driver.executeScript("document.querySelector('video').play()");
await driver.sleep(1300);
expect(await video.getAttribute("muted")).toEqual("true");
await driver.sleep(duration * 1000 + 300);
expect(await video.getAttribute("muted")).toBeNull(); // Default is null for some reason
await driver.executeScript("document.querySelector('video').pause()");
}

View File

@@ -8,6 +8,11 @@
"noEmitOnError": false, "noEmitOnError": false,
"typeRoots": [ "node_modules/@types" ], "typeRoots": [ "node_modules/@types" ],
"resolveJsonModule": true, "resolveJsonModule": true,
"jsx": "react" "jsx": "react",
"lib": [
"es2019",
"dom",
"dom.iterable"
]
} }
} }