mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-06 11:37:02 +03:00
Compare commits
429 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b7f940669 | ||
|
|
bdcd613f02 | ||
|
|
7255300903 | ||
|
|
21b2ad71b9 | ||
|
|
1ff7e69556 | ||
|
|
f7a3f98ad3 | ||
|
|
4cdb874b4f | ||
|
|
5df0801c64 | ||
|
|
e286797ac5 | ||
|
|
e784dc017d | ||
|
|
251339f26b | ||
|
|
3e3b8eab6f | ||
|
|
a7d769dd6d | ||
|
|
ad37e9abe7 | ||
|
|
f99a3f5088 | ||
|
|
6f2a09695b | ||
|
|
9ae8769869 | ||
|
|
f58a16179a | ||
|
|
297c95ac6b | ||
|
|
ced3100b4e | ||
|
|
7358be6faa | ||
|
|
03e29dbb81 | ||
|
|
7cb2915fd7 | ||
|
|
5348496768 | ||
|
|
7526abc3e1 | ||
|
|
1163b6f0ce | ||
|
|
7c809419f8 | ||
|
|
0a42f130ac | ||
|
|
4de0ae51e8 | ||
|
|
f5a4ffabde | ||
|
|
115b1edf11 | ||
|
|
04942a3a5d | ||
|
|
aee0712ef1 | ||
|
|
63568aae9c | ||
|
|
bf90d2a8e6 | ||
|
|
d87cb77895 | ||
|
|
36c4ebda65 | ||
|
|
968df5a2e4 | ||
|
|
259f7a9439 | ||
|
|
4f8e1bc827 | ||
|
|
9e8a520d1e | ||
|
|
7335429541 | ||
|
|
5c227f445a | ||
|
|
dce90e86bf | ||
|
|
36d7dcce9b | ||
|
|
502bec55c4 | ||
|
|
21a61bb238 | ||
|
|
fb974de53b | ||
|
|
a5adf73b88 | ||
|
|
1f4c4c0901 | ||
|
|
338fbcea9c | ||
|
|
a20fa9871e | ||
|
|
25436d9620 | ||
|
|
8d3a633d85 | ||
|
|
f67568e3b6 | ||
|
|
d902cc5efe | ||
|
|
9e89eb521a | ||
|
|
f4c5f50f8c | ||
|
|
4301a6bfe3 | ||
|
|
2c5a78947a | ||
|
|
8f7eb82b6e | ||
|
|
d2e1373e2a | ||
|
|
d705610855 | ||
|
|
c40b6576d6 | ||
|
|
1c3e2fcdad | ||
|
|
7acc6c3329 | ||
|
|
1715ee327f | ||
|
|
0481943737 | ||
|
|
c53bc20294 | ||
|
|
a8fc22eae8 | ||
|
|
4ba82f6e00 | ||
|
|
8fd671d4d3 | ||
|
|
309b1b007e | ||
|
|
d0e7213cc4 | ||
|
|
a2e9688418 | ||
|
|
f42c23cd9a | ||
|
|
52f60d70e2 | ||
|
|
339d05e157 | ||
|
|
c0c3640638 | ||
|
|
a314139302 | ||
|
|
bfa0472f84 | ||
|
|
fa19e435cc | ||
|
|
eb4bf89194 | ||
|
|
da8a1376a7 | ||
|
|
267132cdde | ||
|
|
b8ebe5076b | ||
|
|
cb9877b3b4 | ||
|
|
c73b9ed5a6 | ||
|
|
1bd0b4349f | ||
|
|
d15785146f | ||
|
|
47d9d93818 | ||
|
|
601ff44145 | ||
|
|
cbd451949b | ||
|
|
a7dc207c5f | ||
|
|
c20b67d11f | ||
|
|
0b9def800b | ||
|
|
d8ae73e96a | ||
|
|
c99f7925eb | ||
|
|
3627661e1f | ||
|
|
f1c68a98cf | ||
|
|
92f10d51aa | ||
|
|
bdae68be35 | ||
|
|
2a4abf958d | ||
|
|
1362331a93 | ||
|
|
a70aa7723e | ||
|
|
a3f5200c9a | ||
|
|
1005783034 | ||
|
|
278e40207c | ||
|
|
509b627e88 | ||
|
|
ecd9f6eaff | ||
|
|
1d2b6b2010 | ||
|
|
6c4d5c0705 | ||
|
|
0533919bde | ||
|
|
e02ca1c822 | ||
|
|
039c1a178f | ||
|
|
6f682baa45 | ||
|
|
0241c0a036 | ||
|
|
4ebdcf1cc5 | ||
|
|
46c3187c89 | ||
|
|
c65e3c21e3 | ||
|
|
e35774138f | ||
|
|
a9b678f0ff | ||
|
|
32356d711d | ||
|
|
477ae3eb2c | ||
|
|
0b41118232 | ||
|
|
ea3f9f246e | ||
|
|
9dd954e7d8 | ||
|
|
41352a5116 | ||
|
|
1ac9989288 | ||
|
|
b441cc2123 | ||
|
|
5e2bc43722 | ||
|
|
da17dd8bae | ||
|
|
87098d1c3e | ||
|
|
2a1b60596b | ||
|
|
7bbbe0dcf3 | ||
|
|
25672a6496 | ||
|
|
796bf6ef45 | ||
|
|
6ceeaebd9d | ||
|
|
61b8427270 | ||
|
|
4450aaa3b3 | ||
|
|
b0e0c380dd | ||
|
|
8baf11a053 | ||
|
|
67f9697f3f | ||
|
|
a94d941125 | ||
|
|
2917de6776 | ||
|
|
272698f97b | ||
|
|
3fbb689e0a | ||
|
|
4817af5e4f | ||
|
|
aba08a515e | ||
|
|
83801db82e | ||
|
|
84e4adbc12 | ||
|
|
6a37753753 | ||
|
|
0898c7e28c | ||
|
|
412be37ae5 | ||
|
|
beec376e10 | ||
|
|
df30f00347 | ||
|
|
dcfdade927 | ||
|
|
741ddcd8aa | ||
|
|
433db26078 | ||
|
|
fc033cb69d | ||
|
|
bd8c67bc24 | ||
|
|
a80fbc1a04 | ||
|
|
e347504616 | ||
|
|
94cbf089db | ||
|
|
cb2fb6925b | ||
|
|
b3361a473c | ||
|
|
fcb6ed7676 | ||
|
|
91f4d7f669 | ||
|
|
2e2ff60c23 | ||
|
|
13727270d4 | ||
|
|
b27f56bc00 | ||
|
|
7ad7d793d0 | ||
|
|
491bef680e | ||
|
|
e581dc818f | ||
|
|
8d0b032eb6 | ||
|
|
9cb4fd6f79 | ||
|
|
87abcae249 | ||
|
|
fe608b579e | ||
|
|
f74e25a482 | ||
|
|
1db9d25f3b | ||
|
|
f25aeefe83 | ||
|
|
1abc1b9b28 | ||
|
|
d10c8041bf | ||
|
|
c14c795474 | ||
|
|
e5937431c3 | ||
|
|
b24a688e63 | ||
|
|
10fd22f49c | ||
|
|
f1dda95847 | ||
|
|
f3f6dd171b | ||
|
|
c802212a62 | ||
|
|
afb666797d | ||
|
|
85a591c984 | ||
|
|
3edaea8102 | ||
|
|
93c39c3ecc | ||
|
|
ab2f0ef395 | ||
|
|
005ca73cce | ||
|
|
8dd8897f1f | ||
|
|
95555ed3fd | ||
|
|
11b71f7366 | ||
|
|
4537c70105 | ||
|
|
42a0cff162 | ||
|
|
527e6d4c24 | ||
|
|
2c19da2117 | ||
|
|
7ee1cc911f | ||
|
|
9fc846bd7a | ||
|
|
5b628ccbf9 | ||
|
|
5471273673 | ||
|
|
58c0c6e152 | ||
|
|
36078acaee | ||
|
|
7d62c9f575 | ||
|
|
45a64fcb03 | ||
|
|
630b099fd6 | ||
|
|
c17e47ddd3 | ||
|
|
81bf54c42d | ||
|
|
5b693e81fd | ||
|
|
00115cd707 | ||
|
|
e992844fa2 | ||
|
|
b30acaac78 | ||
|
|
46ac654224 | ||
|
|
8578e96c3a | ||
|
|
b42bdc6e6f | ||
|
|
369364f574 | ||
|
|
a5baebab3f | ||
|
|
b34e6076e4 | ||
|
|
226c5d601c | ||
|
|
cc1a12e1a2 | ||
|
|
1d342b21fd | ||
|
|
5dc67a386c | ||
|
|
6d442b9e80 | ||
|
|
2f6ddeb5f1 | ||
|
|
3d01ffee1b | ||
|
|
9c51df9159 | ||
|
|
3a29fcc3d8 | ||
|
|
b18f2ae60d | ||
|
|
ab07478e25 | ||
|
|
d6aeec933a | ||
|
|
cd5207f816 | ||
|
|
381c11ed99 | ||
|
|
62d4b365c2 | ||
|
|
524df6389a | ||
|
|
24292e771b | ||
|
|
f35d34a807 | ||
|
|
468e33eff7 | ||
|
|
600f9e4b85 | ||
|
|
9cb3da4a7f | ||
|
|
a66c7c8063 | ||
|
|
0a84dbd3a5 | ||
|
|
2fa412e574 | ||
|
|
f240416886 | ||
|
|
2a025b7977 | ||
|
|
f44d2b67e5 | ||
|
|
6b15ebac99 | ||
|
|
ff41251f17 | ||
|
|
c7c1cb79a8 | ||
|
|
fc155ccdfa | ||
|
|
dfad1a5636 | ||
|
|
6790952f86 | ||
|
|
1a28f714a1 | ||
|
|
55a55fefba | ||
|
|
fe74f7caa3 | ||
|
|
108aac0e79 | ||
|
|
008c07acc3 | ||
|
|
831a3c1b5a | ||
|
|
dc7b63d735 | ||
|
|
9267f36165 | ||
|
|
ae6d63c3ab | ||
|
|
a3214f0fa7 | ||
|
|
d4bd5313fc | ||
|
|
c69fe53ea6 | ||
|
|
d7c496847f | ||
|
|
44516648a1 | ||
|
|
fbeabc830b | ||
|
|
f370746382 | ||
|
|
e82beb861a | ||
|
|
1791d31681 | ||
|
|
784ddea34a | ||
|
|
69c93a0563 | ||
|
|
4e4d50de82 | ||
|
|
25b9edabf8 | ||
|
|
6851470547 | ||
|
|
73c1fc17b3 | ||
|
|
cba5b05c0c | ||
|
|
3f1573f1b3 | ||
|
|
93ffc93943 | ||
|
|
4214af4d56 | ||
|
|
01405dd32e | ||
|
|
047432af03 | ||
|
|
a8bd5d0068 | ||
|
|
eeb6d20e96 | ||
|
|
8bb8511bf4 | ||
|
|
563610cbcd | ||
|
|
04190b27d8 | ||
|
|
1782376e3d | ||
|
|
ef1b96bbf1 | ||
|
|
7deea5d648 | ||
|
|
c6460b006f | ||
|
|
4352667b1c | ||
|
|
a84502dc92 | ||
|
|
d7c67fb481 | ||
|
|
adc9748d4d | ||
|
|
f310c53f88 | ||
|
|
f2c2fd0d29 | ||
|
|
1b0cd0f485 | ||
|
|
48f6f2f66c | ||
|
|
85b70f8ad7 | ||
|
|
3e32f28d2e | ||
|
|
9bd1b03504 | ||
|
|
cdccc43b31 | ||
|
|
21ce614bd9 | ||
|
|
7f56ec238f | ||
|
|
e1625437d4 | ||
|
|
5b9afebd4e | ||
|
|
93afc06717 | ||
|
|
cfbf1f8995 | ||
|
|
516e5077a9 | ||
|
|
0c2ceb134b | ||
|
|
02bcb0b213 | ||
|
|
35c6ed81b5 | ||
|
|
a229aee2cc | ||
|
|
f91c6d5f9d | ||
|
|
0e93fb6f57 | ||
|
|
1f491d2031 | ||
|
|
32dd7d43d7 | ||
|
|
284efe9902 | ||
|
|
4e795c8fb1 | ||
|
|
c83eb589ea | ||
|
|
7cd6b324b9 | ||
|
|
5891fccacb | ||
|
|
59233f3307 | ||
|
|
796466a72a | ||
|
|
3f35642010 | ||
|
|
5bbfcf742d | ||
|
|
aaf79fda0d | ||
|
|
8604788d27 | ||
|
|
519a822751 | ||
|
|
fef31c399b | ||
|
|
5802e05228 | ||
|
|
da21081a12 | ||
|
|
6d739de57c | ||
|
|
edcd328743 | ||
|
|
5c9e6cac0e | ||
|
|
7ab5e2cf52 | ||
|
|
42dcdb40cf | ||
|
|
896357a943 | ||
|
|
2d96c24b13 | ||
|
|
1753f58120 | ||
|
|
7244ca8f5e | ||
|
|
ec0c989066 | ||
|
|
c801b1fecd | ||
|
|
57b50106d1 | ||
|
|
871ba63f67 | ||
|
|
f0888faf78 | ||
|
|
23fbbebc9e | ||
|
|
9951a19478 | ||
|
|
dd4ab2f38a | ||
|
|
6bcdb3e272 | ||
|
|
227bec4d8e | ||
|
|
556b4f88d2 | ||
|
|
2d12f957bc | ||
|
|
c1efe02614 | ||
|
|
f0e1979aab | ||
|
|
989db6d6b6 | ||
|
|
781096c290 | ||
|
|
536c6e3e41 | ||
|
|
de376176db | ||
|
|
e63389cfa3 | ||
|
|
1c4ca8da26 | ||
|
|
dcbd7ba4cd | ||
|
|
9fc8d385ab | ||
|
|
07e878e065 | ||
|
|
a2af4dba52 | ||
|
|
2fbafb6b10 | ||
|
|
98eb72ef1f | ||
|
|
89d127c5c5 | ||
|
|
a784c8a850 | ||
|
|
a533aaf5cf | ||
|
|
434b5bdbad | ||
|
|
d1f1f9213e | ||
|
|
d498c107a8 | ||
|
|
f12b44762e | ||
|
|
fc4da038e9 | ||
|
|
d5999ad330 | ||
|
|
146ece3bff | ||
|
|
92095acf36 | ||
|
|
279c10d555 | ||
|
|
0ae3820681 | ||
|
|
283e4d053e | ||
|
|
6dbb2f9d10 | ||
|
|
c657bb763b | ||
|
|
259cdb1abe | ||
|
|
86e96e59af | ||
|
|
9ba30dbafa | ||
|
|
2907db705c | ||
|
|
a6a0f917e0 | ||
|
|
bcdba798d9 | ||
|
|
32884372fa | ||
|
|
9b2364cfb7 | ||
|
|
c1aebf45c8 | ||
|
|
6e0c6332cc | ||
|
|
47d0d340d4 | ||
|
|
118804e139 | ||
|
|
0bef50e259 | ||
|
|
bfb876af8b | ||
|
|
84d5d3124c | ||
|
|
825d997d6d | ||
|
|
8e9e5bfddb | ||
|
|
05765682a5 | ||
|
|
2b5d56942a | ||
|
|
f097ff60aa | ||
|
|
655691a28f | ||
|
|
7ddef8d519 | ||
|
|
2fb79f0066 | ||
|
|
655d87ce0f | ||
|
|
ed7c98afa8 | ||
|
|
41bf0c9697 | ||
|
|
5eb0132660 | ||
|
|
c43695e596 | ||
|
|
9aeda25136 | ||
|
|
90e671ebf8 | ||
|
|
3ecc180d06 | ||
|
|
7ac9ec37ef | ||
|
|
e176a9f241 | ||
|
|
91bd910c40 | ||
|
|
a6c77185de | ||
|
|
b871d721db | ||
|
|
85f9bb1d34 | ||
|
|
adb60c6357 | ||
|
|
4db6593681 | ||
|
|
d75a7ca897 |
38
.github/workflows/ci.yml
vendored
Normal file
38
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
name: CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
name: Create artifacts
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# Initialization
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/setup-node@v1
|
||||
- run: npm install
|
||||
- name: Copy configuration
|
||||
run: cp config.js.example config.js
|
||||
|
||||
# Create Chrome artifacts
|
||||
- name: Create Chrome artifacts
|
||||
run: npm run build
|
||||
- uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: Chrome Extension
|
||||
path: web-ext-artifacts
|
||||
|
||||
# Create Firefox artifacts
|
||||
- name: Move manifest
|
||||
run: mv manifest.json manifest.json.original
|
||||
- name: Combine manifest for Firefox
|
||||
run: jq -s '.[0] * .[1]' manifest.json.original firefox_manifest-extra.json > manifest.json
|
||||
- name: Create Firefox artifacts
|
||||
run: npm run build
|
||||
- uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: Firefox Extension
|
||||
path: web-ext-artifacts
|
||||
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,2 +1,6 @@
|
||||
config.js
|
||||
ignored
|
||||
ignored
|
||||
.idea/
|
||||
node_modules
|
||||
web-ext-artifacts
|
||||
.vscode/
|
||||
|
||||
57
README.md
57
README.md
@@ -1,15 +1,38 @@
|
||||

|
||||
<br/><sub>Logo by [@munadikieh](https://github.com/munadikieh)</sub>
|
||||
<p align="center">
|
||||
<a href="https://sponsor.ajay.app"><img src="icons/LogoSponsorBlocker256px.png" alt="Logo"></img></a>
|
||||
|
||||
<br/>
|
||||
<sub>Logo by <a href="https://github.com/munadikieh">@munadikieh</a></sub>
|
||||
</p>
|
||||
|
||||
<h1 align="center">SponsorBlock</h1>
|
||||
|
||||
<p align="center">
|
||||
<b>Download:</b>
|
||||
<a href="https://chrome.google.com/webstore/detail/mnjggcdmjocbbbhaepdhchncahnbgone">Chrome/Chromium</a> |
|
||||
<a href="https://addons.mozilla.org/addon/sponsorblock/?src=external-github">Firefox</a> |
|
||||
<a href="https://sponsor.ajay.app">Website</a> |
|
||||
<a href="https://sponsor.ajay.app/stats">Stats</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<b>Unofficial Ports:</b>
|
||||
<a href="https://github.com/ajayyy/SponsorBlock/wiki/Unofficial-Ports#mpv-media-player">MPV</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://addons.mozilla.org/addon/sponsorblock/?src=external-github"><img src="https://img.shields.io/amo/users/sponsorblock?label=Firefox%20Users" alt="Badge"></img></a>
|
||||
<a href="https://chrome.google.com/webstore/detail/mnjggcdmjocbbbhaepdhchncahnbgone"><img src="https://img.shields.io/chrome-web-store/users/mnjggcdmjocbbbhaepdhchncahnbgone?label=Chome%20Users" alt="Badge"></img></a>
|
||||
<a href="https://sponsor.ajay.app/stats"><img src="https://img.shields.io/badge/dynamic/json?label=Sponsors%20Submitted&query=totalSubmissions&suffix=%20sponsors&url=http%3A%2F%2Fsponsor.ajay.app%2Fapi%2FgetTotalStats&color=darkred" alt="Badge"></img></a>
|
||||
<a href="https://sponsor.ajay.app/stats"><img src="https://img.shields.io/badge/dynamic/json?label=Contributing%20Users&query=userCount&url=http%3A%2F%2Fsponsor.ajay.app%2Fapi%2FgetTotalStats&color=darkblue" alt="Badge"></img></a>
|
||||
<a href="https://sponsor.ajay.app/stats"><img src="https://img.shields.io/badge/dynamic/json?label=Time%20Saved%20From%20Skips&query=daysSaved&url=http%3A%2F%2Fsponsor.ajay.app%2Fapi%2FgetDaysSavedFormatted&color=darkgreen&suffix=%20days" alt="Badge"></img></a>
|
||||
</p>
|
||||
|
||||
|
||||
# SponsorBlock
|
||||
|
||||
SponsorBlock is an extension that will skip over sponsored segments of YouTube videos. SponsorBlock is a crowdsourced browser extension that lets anyone submit the start and end times of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment.
|
||||
|
||||
# Available for Chrome and Firefox
|
||||
|
||||
Chrome: https://chrome.google.com/webstore/detail/mnjggcdmjocbbbhaepdhchncahnbgone
|
||||
|
||||
Firefox: https://addons.mozilla.org/addon/sponsorblock/
|
||||
Also support Invidio.us.
|
||||
|
||||
# Server
|
||||
|
||||
@@ -17,7 +40,7 @@ The backend server code is available here: https://github.com/ajayyy/SponsorBloc
|
||||
|
||||
It is a simple Sqlite database that will hold all the timing data.
|
||||
|
||||
To make sure that this project doesn't die, I have made the database publicly downloadable at https://sponsor.ajay.app/database.db. So, you can download a backup or get archive.org to take a backup if you do desire.
|
||||
To make sure that this project doesn't die, I have made the database publicly downloadable at https://sponsor.ajay.app/database.db. So, you can download a backup or get archive.org to take a backup for you if you want.
|
||||
|
||||
Hopefully this project can be combined with projects like [this](https://github.com/Sponsoff/sponsorship_remover) and use this data to create a neural network to predict when sponsored segments happen. That project is sadly abandoned now, so I have decided to attempt to revive this idea.
|
||||
|
||||
@@ -25,18 +48,26 @@ Hopefully this project can be combined with projects like [this](https://github.
|
||||
|
||||
You can read the API docs [here](https://github.com/ajayyy/SponsorBlockServer#api-docs).
|
||||
|
||||
# Previous extension
|
||||
|
||||
This project is partially based off of [this experimental extension](https://github.com/OfficialNoob/YTSponsorSkip), which has the basic video skipping functionality.
|
||||
|
||||
# Build Yourself
|
||||
|
||||
You can load this project as an unpacked extension. Make sure to rename the `config.js.example` file to `config.js` before installing.
|
||||
|
||||
There are also other build scripts available. Install `npm`, then run `npm install` in the repository.
|
||||
|
||||
## Developing with a clean profile
|
||||
|
||||
Run `npm run dev` to run the extension using a clean browser profile with hot reloading [(by default Firefox)](https://hacks.mozilla.org/2019/10/developing-cross-browser-extensions-with-web-ext-3-2-0/). This uses [`web-ext run`](https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#commands).
|
||||
|
||||
## Packing
|
||||
|
||||
Run `npm run build` to generate a packed extension.
|
||||
|
||||
# Credit
|
||||
|
||||
The awesome [Invidious API](https://github.com/omarroth/invidious/wiki/API) is used to grab the time the video was published.
|
||||
|
||||
Original code from [YTSponsorSkip](https://github.com/OfficialNoob/YTSponsorSkip), but not much of the code is left.
|
||||
|
||||
Some icons made by <a href="https://www.flaticon.com/authors/gregor-cresnar" title="Gregor Cresnar">Gregor Cresnar</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
|
||||
|
||||
Some icons made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
|
||||
|
||||
203
SB.js
Normal file
203
SB.js
Normal file
@@ -0,0 +1,203 @@
|
||||
SB = {
|
||||
/**
|
||||
* Callback function when an option is updated
|
||||
*
|
||||
* @type {CallableFunction}
|
||||
*/
|
||||
configListeners: []
|
||||
};
|
||||
|
||||
// Function setup
|
||||
|
||||
// Allows a map to be conveted into json form
|
||||
// Currently used for local storage
|
||||
Map.prototype.toJSON = function() {
|
||||
return Array.from(this.entries());
|
||||
};
|
||||
|
||||
// Proxy Map changes to Map in SB.localConfig
|
||||
// Saves the changes to chrome.storage in json form
|
||||
class MapIO {
|
||||
constructor(id) {
|
||||
// The name of the item in the array
|
||||
this.id = id;
|
||||
// A local copy of the map (SB.config.mapname.map)
|
||||
this.map = SB.localConfig[this.id];
|
||||
}
|
||||
set(key, value) {
|
||||
// Proxy to map
|
||||
this.map.set(key, value);
|
||||
// Store updated map locally
|
||||
chrome.storage.sync.set({
|
||||
[this.id]: encodeStoredItem(this.map)
|
||||
});
|
||||
return this.map;
|
||||
}
|
||||
|
||||
get(key) {
|
||||
return this.map.get(key);
|
||||
}
|
||||
|
||||
has(key) {
|
||||
return this.map.has(key);
|
||||
}
|
||||
|
||||
size() {
|
||||
return this.map.size;
|
||||
}
|
||||
|
||||
delete(key) {
|
||||
// Proxy to map
|
||||
this.map.delete(key);
|
||||
// Store updated map locally
|
||||
chrome.storage.sync.set({
|
||||
[this.id]: encodeStoredItem(this.map)
|
||||
});
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.map.clear();
|
||||
chrome.storage.sync.set({
|
||||
[this.id]: encodeStoredItem(this.map)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Map cannot be stored in the chrome storage.
|
||||
* This data will be encoded into an array instead as specified by the toJSON function.
|
||||
*
|
||||
* @param {*} data
|
||||
*/
|
||||
function encodeStoredItem(data) {
|
||||
// if data is Map convert to json for storing
|
||||
if(!(data instanceof Map)) return data;
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Map cannot be stored in the chrome storage.
|
||||
* This data will be decoded from the array it is stored in
|
||||
*
|
||||
* @param {*} data
|
||||
*/
|
||||
function decodeStoredItem(data) {
|
||||
if(typeof data !== "string") return data;
|
||||
|
||||
try {
|
||||
let str = JSON.parse(data);
|
||||
|
||||
if(!Array.isArray(str)) return data;
|
||||
return new Map(str);
|
||||
} catch(e) {
|
||||
|
||||
// If all else fails, return the data
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
function configProxy() {
|
||||
chrome.storage.onChanged.addListener((changes, namespace) => {
|
||||
for (const key in changes) {
|
||||
SB.localConfig[key] = decodeStoredItem(changes[key].newValue);
|
||||
}
|
||||
|
||||
for (const callback of SB.configListeners) {
|
||||
callback(changes);
|
||||
}
|
||||
});
|
||||
|
||||
var handler = {
|
||||
set(obj, prop, value) {
|
||||
SB.localConfig[prop] = value;
|
||||
|
||||
chrome.storage.sync.set({
|
||||
[prop]: encodeStoredItem(value)
|
||||
});
|
||||
},
|
||||
|
||||
get(obj, prop) {
|
||||
let data = SB.localConfig[prop];
|
||||
if(data instanceof Map) data = new MapIO(prop);
|
||||
|
||||
return obj[prop] || data;
|
||||
},
|
||||
|
||||
deleteProperty(obj, prop) {
|
||||
chrome.storage.sync.remove(prop);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return new Proxy({handler}, handler);
|
||||
}
|
||||
|
||||
function fetchConfig() {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.storage.sync.get(null, function(items) {
|
||||
SB.localConfig = items; // Data is ready
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function migrateOldFormats() { // Convert sponsorTimes format
|
||||
for (const key in SB.localConfig) {
|
||||
if (key.startsWith("sponsorTimes") && key !== "sponsorTimes" && key !== "sponsorTimesContributed") {
|
||||
SB.config.sponsorTimes.set(key.substr(12), SB.config[key]);
|
||||
delete SB.config[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function setupConfig() {
|
||||
await fetchConfig();
|
||||
addDefaults();
|
||||
convertJSON();
|
||||
SB.config = configProxy();
|
||||
migrateOldFormats();
|
||||
}
|
||||
|
||||
SB.defaults = {
|
||||
"sponsorTimes": new Map(),
|
||||
"startSponsorKeybind": ";",
|
||||
"submitKeybind": "'",
|
||||
"minutesSaved": 0,
|
||||
"skipCount": 0,
|
||||
"sponsorTimesContributed": 0,
|
||||
"disableSkipping": false,
|
||||
"disableAutoSkip": false,
|
||||
"trackViewCount": true,
|
||||
"dontShowNotice": false,
|
||||
"hideVideoPlayerControls": false,
|
||||
"hideInfoButtonPlayerControls": false,
|
||||
"hideDeleteButtonPlayerControls": false,
|
||||
"hideDiscordLaunches": 0,
|
||||
"hideDiscordLink": false,
|
||||
"invidiousInstances": ["invidio.us", "invidiou.sh", "invidious.snopyta.org"],
|
||||
"invidiousUpdateInfoShowCount": 0,
|
||||
"autoUpvote": true
|
||||
}
|
||||
|
||||
// Reset config
|
||||
function resetConfig() {
|
||||
SB.config = SB.defaults;
|
||||
};
|
||||
|
||||
function convertJSON() {
|
||||
Object.keys(SB.defaults).forEach(key => {
|
||||
SB.localConfig[key] = decodeStoredItem(SB.localConfig[key], key);
|
||||
});
|
||||
}
|
||||
|
||||
// Add defaults
|
||||
function addDefaults() {
|
||||
for (const key in SB.defaults) {
|
||||
if(!SB.localConfig.hasOwnProperty(key)) {
|
||||
SB.localConfig[key] = SB.defaults[key];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Sync config
|
||||
setupConfig();
|
||||
318
_locales/de/messages.json
Normal file
318
_locales/de/messages.json
Normal file
@@ -0,0 +1,318 @@
|
||||
{
|
||||
"Name": {
|
||||
"message": "SponsorBlock",
|
||||
"description": "Name of the extension."
|
||||
},
|
||||
"fullName": {
|
||||
"message": "SponsorBlock for YouTube - Skip Sponsorships",
|
||||
"description": "Name of the extension."
|
||||
},
|
||||
|
||||
"Description": {
|
||||
"message": "Überspringe die gesponserten Inhalte in YouTube-Videos. Melde gesponsorte Inhalte in den von dir angesehenen Videos und erspare anderen die Zeit.",
|
||||
"description": "Description of the extension."
|
||||
},
|
||||
"helpPage": {
|
||||
"message": "index_en.html"
|
||||
},
|
||||
"400": {
|
||||
"message": "Ungültige Anforderung"
|
||||
},
|
||||
"429": {
|
||||
"message": "Du hast zu viele Segmente in diesem Video eingereicht. Bist du dir sicher?"
|
||||
},
|
||||
"409": {
|
||||
"message": "Dieser Inhalt wurde bereits eingereicht."
|
||||
},
|
||||
"channelWhitelisted": {
|
||||
"message": "Kanal auf Whitelist gesetzt!"
|
||||
},
|
||||
"Sponsor": {
|
||||
"message": "Sponsor"
|
||||
},
|
||||
"Sponsors": {
|
||||
"message": "Sponsoren"
|
||||
},
|
||||
"Segment": {
|
||||
"message": "gesponsorter Inhalt"
|
||||
},
|
||||
"Segments": {
|
||||
"message": "gesponsorte Inhalte"
|
||||
},
|
||||
"noticeTitle": {
|
||||
"message": "Sponsor übersprungen"
|
||||
},
|
||||
"reportButtonTitle": {
|
||||
"message": "Melden"
|
||||
},
|
||||
"reportButtonInfo": {
|
||||
"message": "Melde dieses Segment als unzulässig."
|
||||
},
|
||||
"Dismiss": {
|
||||
"message": "Abbrechen"
|
||||
},
|
||||
"Loading": {
|
||||
"message": "Laden..."
|
||||
},
|
||||
"Mins": {
|
||||
"message": "Minuten"
|
||||
},
|
||||
"Secs": {
|
||||
"message": "Sekunden"
|
||||
},
|
||||
"Hide": {
|
||||
"message": "Verstecken"
|
||||
},
|
||||
"hitGoBack": {
|
||||
"message": "Klicke Zurück um die Aktion rückgängig zu machen."
|
||||
},
|
||||
"unskip": {
|
||||
"message": "Zurück"
|
||||
},
|
||||
"reskip": {
|
||||
"message": "Vorwärts"
|
||||
},
|
||||
"paused": {
|
||||
"message": "Pausiert"
|
||||
},
|
||||
"confirmMSG": {
|
||||
"message": "\n\nUm einzelne Werte zu löschen oder zu ändern, klicke auf den Info-Button, oder öffne die Erweiterungs-Übersicht, indem du das Erweiterungssymbol in der rechten oberen Ecke anklickst."
|
||||
},
|
||||
"clearThis": {
|
||||
"message": "Bist du sicher, dass du Folgendes löschen möchtest?\n\n"
|
||||
},
|
||||
"Unknown": {
|
||||
"message": "Deine Segmente konnten nicht gesendet werden, bitte versuche es später erneut."
|
||||
},
|
||||
"sponsorFound": {
|
||||
"message": "Die gesponsorten Inhalte dieses Videos befinden sich bereits in der Datenbank!"
|
||||
},
|
||||
"sponsor404": {
|
||||
"message": "Keine Sponsoren gefunden"
|
||||
},
|
||||
"sponsorStart": {
|
||||
"message": "Gesponserter Inhalt beginnt"
|
||||
},
|
||||
"sponsorEnd": {
|
||||
"message": "Gesponserter Inhalt endet"
|
||||
},
|
||||
"noVideoID": {
|
||||
"message": "Keine YouTube-Videos in diesem Tab gefunden. Wenn dies ein Youtube-Tab ist, schließe dieses Pop-up und öffne es erneut. Wenn das nicht hilft, versuche den Tab neu zu laden."
|
||||
},
|
||||
"success": {
|
||||
"message": "Erfolg!"
|
||||
},
|
||||
"voted": {
|
||||
"message": "Abgestimmt!"
|
||||
},
|
||||
"voteFail": {
|
||||
"message": "Du hast bereits so abgestimmt."
|
||||
},
|
||||
"serverDown": {
|
||||
"message": "Der Server ist scheinbar offline. Bitte unverzüglich dem Entwickler melden."
|
||||
},
|
||||
"connectionError": {
|
||||
"message": "Ein Verbindungsfehler ist aufgetreten. Fehlermeldung: "
|
||||
},
|
||||
"wantToSubmit": {
|
||||
"message": "Möchtest du die Segmente für die Video ID senden?"
|
||||
},
|
||||
"leftTimes": {
|
||||
"message": "Scheinbar hast du einige Segmente noch nicht gesendet. Kehre zur Seite zurück um sie zu senden (sie sind noch gespeichert)."
|
||||
},
|
||||
"clearTimes": {
|
||||
"message": "Lösche Auswahl"
|
||||
},
|
||||
"openPopup": {
|
||||
"message": "Öffne SponsorBlock-Popup"
|
||||
},
|
||||
"SubmitTimes": {
|
||||
"message": "Sende Auswahl"
|
||||
},
|
||||
"submitCheck": {
|
||||
"message": "Bist du sicher, dass die Auswahl abgeschickt werden soll?"
|
||||
},
|
||||
"whitelistChannel": {
|
||||
"message": "Kanal auf Whitelist setzen "
|
||||
},
|
||||
"removeFromWhitelist": {
|
||||
"message": "Kanal von Whitelist entfernen"
|
||||
},
|
||||
"voteOnTime": {
|
||||
"message": "Stimme für Zeiten ab"
|
||||
},
|
||||
"recordTimes": {
|
||||
"message": "Lege das Zeitfenster eines gesponsorten Inhalts fest"
|
||||
},
|
||||
"soFarUHSubmited": {
|
||||
"message": "Gemeldet wurden von dir bisher"
|
||||
},
|
||||
"savedPeopleFrom": {
|
||||
"message": "Du hast andere Benutzer bewahrt vor"
|
||||
},
|
||||
"viewLeaderboard": {
|
||||
"message": "Siehe Rangliste"
|
||||
},
|
||||
"here": {
|
||||
"message": "hier"
|
||||
},
|
||||
"recordTimesDescription": {
|
||||
"message": "Klicke den Knopf unten, wenn der gesponsorte Inhalt beginnt und endet, um aufzunehmen und\n einzusenden"
|
||||
},
|
||||
"popupHint": {
|
||||
"message": "Hinweis: In den Optionen lässt sich eine Taste für das Festlegen von Anfang/Ende des gesponsorten Inhalts, sowie für das Einsenden festlegen"
|
||||
},
|
||||
"lastTimes": {
|
||||
"message": "Letzte ausgewählte Zeitabschnitte"
|
||||
},
|
||||
"clearTimesButton": {
|
||||
"message": "Zeiten löschen"
|
||||
},
|
||||
"submitTimesButton": {
|
||||
"message": "Zeiten einsenden"
|
||||
},
|
||||
"publicStats": {
|
||||
"message": "Dies ist wichtig für die öffentliche Nutzerstatistik. Siehe"
|
||||
},
|
||||
"setUsername": {
|
||||
"message": "Alias festlegen"
|
||||
},
|
||||
"discordAdvert": {
|
||||
"message": "Tritt dem offiziellen Discord-Kanal bei und teile Anregungen und Feedback!"
|
||||
},
|
||||
"hideThis": {
|
||||
"message": "Verstecken"
|
||||
},
|
||||
"Options": {
|
||||
"message": "Optionen"
|
||||
},
|
||||
"showButtons": {
|
||||
"message": "Knöpfe in YouTube-Leiste zeigen"
|
||||
},
|
||||
"hideButtons": {
|
||||
"message": "Knöpfe in YouTube-Leiste verstecken"
|
||||
},
|
||||
"hideButtonsDescription": {
|
||||
"message": "Die Einstellung versteckt den Einsende-Knopf in der Youtube-Leiste. Ich kann verstehen, weshalb manchen diese Funktion\n an dieser Stelle stört. Stattdessen kann dafür dieses Pop-up genutzt werden. Um die transparente Benachrichtigung zu verstecken, klicke auf den \"Verstecken\"-Knopf \n der Benachrichtigung. Diese Einstellungen können wieder rückgängig gemacht werden."
|
||||
},
|
||||
"showInfoButton": {
|
||||
"message": "Zeige Info-Knopf in Youtube-Leiste"
|
||||
},
|
||||
"hideInfoButton": {
|
||||
"message": "Verstecke Info-Knopf in Youtube-Leiste"
|
||||
},
|
||||
"whatInfoButton": {
|
||||
"message": "Dieser Knopf öffnet ein Pop-up auf der Youtube-Seite."
|
||||
},
|
||||
"hideDeleteButton": {
|
||||
"message": "Verstecke Löschen-Knopf in Youtube Leiste"
|
||||
},
|
||||
"showDeleteButton": {
|
||||
"message": "Zeige Löschen-Knopf in Youtube Leiste"
|
||||
},
|
||||
"whatDeleteButton": {
|
||||
"message": "Dieser Knopf entfernt sämtlich Segmente in der Youtube-Zeitleiste."
|
||||
},
|
||||
"disableViewTracking": {
|
||||
"message": "Deaktiviere das Mitzählen übersprungener Sponsoren"
|
||||
},
|
||||
"enableViewTracking": {
|
||||
"message": "Aktiviere das Mitzählen übersprungener Sponsoren"
|
||||
},
|
||||
"whatViewTracking": {
|
||||
"message": "Diese Funktion hält fest, welche Sponsoren von dir übersprungen wurden und hilft anderen zu erfahren, was ihre Einsendungen bewirkt haben.\n Außerdem dienen die Werte zusammen mit positiven Rückmeldungen als Anti-Spam-Schutz. \n Wenn ein gesponsorter Inhalt übersprungen wird, sendet die Erweiterung eine Nachricht an den Server. \n Hoffentlich wird diese Funktion auch weiterhin genutzt, damit der Algorithmus funktioniert. :)"
|
||||
},
|
||||
"showNotice": {
|
||||
"message": "Benachrichtigung wieder zeigen"
|
||||
},
|
||||
"longDescription": {
|
||||
"message": "SponsorBlock ist eine Erweiterung, die gesponsorte Segmente in YouTube-Videos überspringt. SponsorBlock ist ein Benutzernetzwerk, bei dem jeder Anfang und Ende eines Werbeblocks einreichen kann. Sobald die Information von einem Nutzer eingereicht wurde, überspringen die Erweiterungen der anderen dieses Segment automatisch.",
|
||||
"description": "Full description of the extension on the store pages."
|
||||
},
|
||||
"website": {
|
||||
"message": "Webseite",
|
||||
"description": "Used on Firefox Store Page"
|
||||
},
|
||||
"sourceCode": {
|
||||
"message": "Quellcode",
|
||||
"description": "Used on Firefox Store Page"
|
||||
},
|
||||
"noticeUpdate": {
|
||||
"message": "Die Benachrichtigung wurde verbessert!",
|
||||
"description": "The first line of the message displayed after the notice was upgraded."
|
||||
},
|
||||
"noticeUpdate2": {
|
||||
"message": "Gefällt dir immer noch nicht? Dann klicke den Verstecken-Knopf.",
|
||||
"description": "The second line of the message displayed after the notice was upgraded."
|
||||
},
|
||||
"setStartSponsorShortcut": {
|
||||
"message": "Segment aufnehmen Taste festlegen"
|
||||
},
|
||||
"setSubmitKeybind": {
|
||||
"message": "Segment einsenden Taste festlegen"
|
||||
},
|
||||
"keybindDescription": {
|
||||
"message": "Taste drücken, um festzulegen"
|
||||
},
|
||||
"keybindDescriptionComplete": {
|
||||
"message": "Die Taste wurde festgelegt auf: "
|
||||
},
|
||||
"0": {
|
||||
"message": "Verbindungsüberschreibung. Überprüfe deine Internetverbindung. Bist du mit dem Internet verbunden, ist der Server wahrscheinlich offline."
|
||||
},
|
||||
"disableSkipping": {
|
||||
"message": "SponsorBlock ausschalten"
|
||||
},
|
||||
"enableSkipping": {
|
||||
"message": "SponsorBlock einschalten"
|
||||
},
|
||||
"yourWork": {
|
||||
"message": "Deine Statistik",
|
||||
"description": "Used to describe the section that will show you the statistics from your submissions."
|
||||
},
|
||||
"502": {
|
||||
"message": "Der Server scheint überlastet zu sein. Probiere es in ein paar Sekunden erneut."
|
||||
},
|
||||
"errorCode": {
|
||||
"message": "Fehlermeldung: "
|
||||
},
|
||||
"noticeTitleNotSkipped": {
|
||||
"message": "Sponsor überspringen?"
|
||||
},
|
||||
"skip": {
|
||||
"message": "Überspringen"
|
||||
},
|
||||
"disableAutoSkip": {
|
||||
"message": "Auto-Überspringen deaktivieren"
|
||||
},
|
||||
"enableAutoSkip": {
|
||||
"message": "Auto-Überspringen aktivieren"
|
||||
},
|
||||
"autoSkipDescription": {
|
||||
"message": "Auto-Überspringen überspringt gesponsorte Inhalte für dich. Wenn deaktiviert, fragt die Benachrichtigung, ob übersprungen werden soll."
|
||||
},
|
||||
"youHaveSkipped": {
|
||||
"message": "Du übersprangst "
|
||||
},
|
||||
"youHaveSaved": {
|
||||
"message": "Du erspartest dir "
|
||||
},
|
||||
"minLower": {
|
||||
"message": "Minute"
|
||||
},
|
||||
"minsLower": {
|
||||
"message": "Minuten"
|
||||
},
|
||||
"hourLower": {
|
||||
"message": "Stunde"
|
||||
},
|
||||
"hoursLower": {
|
||||
"message": "Stunden"
|
||||
},
|
||||
"youHaveSavedTime": {
|
||||
"message": "Du erspartest anderen"
|
||||
},
|
||||
"youHaveSavedTimeEnd": {
|
||||
"message": " ihrer Zeit."
|
||||
}
|
||||
}
|
||||
@@ -24,17 +24,14 @@
|
||||
"409": {
|
||||
"message": "This has already been submitted before"
|
||||
},
|
||||
"502": {
|
||||
"message": "It seems the server is down. Contact the dev to inform them."
|
||||
},
|
||||
"channelWhitelisted": {
|
||||
"message": "Channel Whitelisted!"
|
||||
},
|
||||
"Sponsor": {
|
||||
"message": "Sponsor"
|
||||
"message": "sponsor"
|
||||
},
|
||||
"Sponsors": {
|
||||
"message": "Sponsors"
|
||||
"message": "sponsors"
|
||||
},
|
||||
"Segment": {
|
||||
"message": "sponsor segment"
|
||||
@@ -79,7 +76,7 @@
|
||||
"message": "Paused"
|
||||
},
|
||||
"confirmMSG": {
|
||||
"message": "\n\nTo edit or delete individual values, click the info button or open the extension popup by clicking the extension icon in the top right corner."
|
||||
"message": "To edit or delete individual values, click the info button or open the extension popup by clicking the extension icon in the top right corner."
|
||||
},
|
||||
"clearThis": {
|
||||
"message": "Are you sure you want to clear this?\n\n"
|
||||
@@ -87,7 +84,6 @@
|
||||
"Unknown": {
|
||||
"message": "There was an error submitting your sponsor times, please try again later."
|
||||
},
|
||||
|
||||
"sponsorFound": {
|
||||
"message": "This video's sponsors are in the database!"
|
||||
},
|
||||
@@ -101,7 +97,7 @@
|
||||
"message": "Sponsorship Ends Now"
|
||||
},
|
||||
"noVideoID": {
|
||||
"message": "This probably isn't a YouTube tab, or you clicked too early. \n If you know this is a YouTube tab,\n close this popup and open it again."
|
||||
"message": "No YouTube video found at this tab. If you know this is a YouTube tab, close this popup and open it again. If that does not work, try reloading the tab."
|
||||
},
|
||||
"success": {
|
||||
"message": "Success!"
|
||||
@@ -123,5 +119,272 @@
|
||||
},
|
||||
"leftTimes": {
|
||||
"message": "You seem to have left some sponsor times unsubmitted. Go back to that page to submit them (they are not deleted)."
|
||||
},
|
||||
"clearTimes": {
|
||||
"message": "Clear Sponsor Times"
|
||||
},
|
||||
"openPopup": {
|
||||
"message": "Open SponsorBlock Popup"
|
||||
},
|
||||
"SubmitTimes": {
|
||||
"message": "Submit Sponsor Times"
|
||||
},
|
||||
"submitCheck": {
|
||||
"message": "Are you sure you want to submit this?"
|
||||
},
|
||||
"whitelistChannel": {
|
||||
"message": "Whitelist Channel"
|
||||
},
|
||||
"removeFromWhitelist": {
|
||||
"message": "Remove Channel From Whitelist"
|
||||
},
|
||||
"voteOnTime": {
|
||||
"message": "Vote On A Sponsor Time"
|
||||
},
|
||||
"recordTimes": {
|
||||
"message": "Record the times of a sponsorship"
|
||||
},
|
||||
"soFarUHSubmited": {
|
||||
"message": "So far, you've submitted"
|
||||
},
|
||||
"savedPeopleFrom": {
|
||||
"message": "You have saved people from "
|
||||
},
|
||||
"viewLeaderboard": {
|
||||
"message": "View the leaderboard"
|
||||
},
|
||||
"here": {
|
||||
"message": "here"
|
||||
},
|
||||
"recordTimesDescription": {
|
||||
"message": "Click the button below when the sponsorship starts and ends to record and\nsubmit it to the database."
|
||||
},
|
||||
"popupHint": {
|
||||
"message": "Hint: Press the semicolon key while focused on a video report the start/end of a sponsor and quote to submit. (This can be changed in the options)"
|
||||
},
|
||||
"lastTimes": {
|
||||
"message": "Latest Sponsor Message Times Chosen"
|
||||
},
|
||||
"clearTimesButton": {
|
||||
"message": "Clear Times"
|
||||
},
|
||||
"submitTimesButton": {
|
||||
"message": "Submit Times"
|
||||
},
|
||||
"publicStats": {
|
||||
"message": "This is used on the public stats page to show off how much you've contributed. See it"
|
||||
},
|
||||
"setUsername": {
|
||||
"message": "Set Username"
|
||||
},
|
||||
"discordAdvert": {
|
||||
"message": "Come join the official discord server to give suggestions and feedback!"
|
||||
},
|
||||
"hideThis": {
|
||||
"message": "Hide this"
|
||||
},
|
||||
"Options": {
|
||||
"message": "Options"
|
||||
},
|
||||
"showButtons": {
|
||||
"message": "Show Buttons On YouTube Player"
|
||||
},
|
||||
"hideButtons": {
|
||||
"message": "Hide Buttons On YouTube Player"
|
||||
},
|
||||
"hideButtonsDescription": {
|
||||
"message": "This hides the buttons that appear on the YouTube player to submit sponsors. I can see this being annoying for some\n people. Instead of using the button there, this popup can be used to submit sponsors. To hide the notice that appears, \n use the button that appears on the notice saying \"Don't show this again\". You can always enable these settings again later."
|
||||
},
|
||||
"showInfoButton": {
|
||||
"message": "Show Info Button On YouTube Player"
|
||||
},
|
||||
"hideInfoButton": {
|
||||
"message": "Hide Info Button On YouTube Player"
|
||||
},
|
||||
"whatInfoButton": {
|
||||
"message": "This is the button that opens up a popup in the YouTube page."
|
||||
},
|
||||
"hideDeleteButton": {
|
||||
"message": "Hide Delete Button On YouTube Player"
|
||||
},
|
||||
"showDeleteButton": {
|
||||
"message": "Show Delete Button On YouTube Player"
|
||||
},
|
||||
"whatDeleteButton": {
|
||||
"message": "This is the button that allows you to clear all sponsors on the YouTube player."
|
||||
},
|
||||
"disableViewTracking": {
|
||||
"message": "Disable Sponsor Skip Count Tracking"
|
||||
},
|
||||
"enableViewTracking": {
|
||||
"message": "Enable Sponsor Skip Count Tracking"
|
||||
},
|
||||
"whatViewTracking": {
|
||||
"message": "This feature tracks which sponsors you have skipped to let users know how much their submission has helped others and\nused as a metric along with upvotes to ensure that spam doesn't get into the database. The extension sends a message\nto the server each time you skip a sponsor. Hopefully most people don't change this setting so that the view numbers are accurate. :)"
|
||||
},
|
||||
"showNotice": {
|
||||
"message": "Show Notice Again"
|
||||
},
|
||||
"longDescription": {
|
||||
"message": "SponsorBlock is an extension that will skip over sponsored segments of YouTube videos. SponsorBlock is a crowdsourced browser extension that let's anyone submit the start and end time's of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment.",
|
||||
"description": "Full description of the extension on the store pages."
|
||||
},
|
||||
"website": {
|
||||
"message": "Website",
|
||||
"description": "Used on Firefox Store Page"
|
||||
},
|
||||
"sourceCode": {
|
||||
"message": "Source Code",
|
||||
"description": "Used on Firefox Store Page"
|
||||
},
|
||||
"noticeUpdate": {
|
||||
"message": "The notice has been upgraded!",
|
||||
"description": "The first line of the message displayed after the notice was upgraded."
|
||||
},
|
||||
"noticeUpdate2": {
|
||||
"message": "If you still don't like it, hit the never show button.",
|
||||
"description": "The second line of the message displayed after the notice was upgraded."
|
||||
},
|
||||
"setStartSponsorShortcut": {
|
||||
"message": "Set key for start sponsor keybind"
|
||||
},
|
||||
"setSubmitKeybind": {
|
||||
"message": "Set key for submission keybind"
|
||||
},
|
||||
"keybindDescription": {
|
||||
"message": "Select a key by typing it"
|
||||
},
|
||||
"keybindDescriptionComplete": {
|
||||
"message": "The keybind has been set to: "
|
||||
},
|
||||
"0": {
|
||||
"message": "Connection Timeout. Check your internet connection. If your internet is working, the server is probably overloaded or down."
|
||||
},
|
||||
"disableSkipping": {
|
||||
"message": "Disable SponsorBlock"
|
||||
},
|
||||
"enableSkipping": {
|
||||
"message": "Enable SponsorBlock"
|
||||
},
|
||||
"yourWork": {
|
||||
"message": "Your Work",
|
||||
"description": "Used to describe the section that will show you the statistics from your submissions."
|
||||
},
|
||||
"502": {
|
||||
"message": "The server seems to be overloaded. Try again in a few seconds."
|
||||
},
|
||||
"errorCode": {
|
||||
"message": "Error Code: "
|
||||
},
|
||||
"noticeTitleNotSkipped": {
|
||||
"message": "Skip Sponsor?"
|
||||
},
|
||||
"skip": {
|
||||
"message": "Skip"
|
||||
},
|
||||
"disableAutoSkip": {
|
||||
"message": "Disable Auto Skip"
|
||||
},
|
||||
"enableAutoSkip": {
|
||||
"message": "Enable Auto Skip"
|
||||
},
|
||||
"autoSkipDescription": {
|
||||
"message": "Auto skip will skip sponsors for you. If disabled, a notice will appear asking if you'd like to skip."
|
||||
},
|
||||
"youHaveSkipped": {
|
||||
"message": "You have skipped "
|
||||
},
|
||||
"youHaveSaved": {
|
||||
"message": "You have saved yourself "
|
||||
},
|
||||
"minLower": {
|
||||
"message": "minute"
|
||||
},
|
||||
"minsLower": {
|
||||
"message": "minutes"
|
||||
},
|
||||
"hourLower": {
|
||||
"message": "hour"
|
||||
},
|
||||
"hoursLower": {
|
||||
"message": "hours"
|
||||
},
|
||||
"youHaveSavedTime": {
|
||||
"message": "You have saved people"
|
||||
},
|
||||
"youHaveSavedTimeEnd": {
|
||||
"message": " of their lives."
|
||||
},
|
||||
"guildlinesSummary": {
|
||||
"message": "- Make sure your segment only contains paid promotion segment, nothing else.\n- Make sure skipping this segment will not skip valuable content\n- If the whole video is a sponsor, please do not report it. A full video reporting system will come out soon.\n- Please do not report disclaimers that could show bias (if a review video is sponsored, don't skip when they mention that)."
|
||||
},
|
||||
"statusReminder": {
|
||||
"message": "Check status.sponsor.ajay.app for server status."
|
||||
},
|
||||
"changeUserID": {
|
||||
"message": "Import/Export Your UserID"
|
||||
},
|
||||
"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."
|
||||
},
|
||||
"setUserID": {
|
||||
"message": "Set UserID"
|
||||
},
|
||||
"userIDChangeWarning": {
|
||||
"message": "Warning: Changing the UserID is permanent. Are you sure you would like to do this? Make sure to backup your old one just in case."
|
||||
},
|
||||
"createdBy": {
|
||||
"message": "Created By"
|
||||
},
|
||||
"autoSkip": {
|
||||
"message": "Auto Skip"
|
||||
},
|
||||
"showSkipNotice": {
|
||||
"message": "Show Notice After A Sponsor Is Skipped"
|
||||
},
|
||||
"keybindCurrentlySet": {
|
||||
"message": ". It is currently set to:"
|
||||
},
|
||||
"supportInvidious": {
|
||||
"message": "Support Invidious"
|
||||
},
|
||||
"supportInvidiousDescription": {
|
||||
"message": "Invidious (invidio.us) is a third party YouTube client. To enable support, you must accept the extra permissions. This does NOT work in incongnito on Chrome and other Chromium variants."
|
||||
},
|
||||
"optionsInfo": {
|
||||
"message": "Enable Invidious support, disable autoskip, hide buttons and more."
|
||||
},
|
||||
"addInvidiousInstance": {
|
||||
"message": "Add Invidious Instance"
|
||||
},
|
||||
"addInvidiousInstanceDescription": {
|
||||
"message": "Add a custom instance of Invidious. This must be formatted with JUST the domain. Example: invidious.ajay.app"
|
||||
},
|
||||
"add": {
|
||||
"message": "Add"
|
||||
},
|
||||
"addInvidiousInstanceError": {
|
||||
"message": "This is an invalid domain. This should JUST include the domain part. Example: invidious.ajay.app"
|
||||
},
|
||||
"resetInvidiousInstance": {
|
||||
"message": "Reset Invidious Instance List"
|
||||
},
|
||||
"resetInvidiousInstanceAlert": {
|
||||
"message": "You are about to reset the Invidious instance list"
|
||||
},
|
||||
"currentInstances": {
|
||||
"message": "Current Instances:"
|
||||
},
|
||||
"enableAutoUpvote": {
|
||||
"message": "Auto Upvote"
|
||||
},
|
||||
"whatAutoUpvote": {
|
||||
"message": "With this enabled, the extension will upvote all submissions you view if you do not report them. If the notice is disabled, this will not occur."
|
||||
},
|
||||
"invidiousInfo1": {
|
||||
"message": "Invidious (the 3rd party YouTube site) support has been added!"
|
||||
},
|
||||
"invidiousInfo2": {
|
||||
"message": "You MUST enable it in the options for it to work."
|
||||
}
|
||||
}
|
||||
|
||||
263
_locales/fr/messages.json
Normal file
263
_locales/fr/messages.json
Normal file
@@ -0,0 +1,263 @@
|
||||
{
|
||||
"Name": {
|
||||
"message": "SponsorBlock",
|
||||
"description": "Name of the extension."
|
||||
},
|
||||
"fullName": {
|
||||
"message": "SponsorBlock pour YouTube - Supprime les messages commerciaux et publicités intégrées",
|
||||
"description": "Name of the extension."
|
||||
},
|
||||
|
||||
"Description": {
|
||||
"message": "Passe automatiquement les messages commerciaux intégrés dans les vidéos YouTube. Soumettez les segments commerciaux dans les vidéos que vous regardez pour aidez les autres.",
|
||||
"description": "Description of the extension."
|
||||
},
|
||||
"helpPage": {
|
||||
"message": "index_en.html"
|
||||
},
|
||||
"400": {
|
||||
"message": "Soumission invalide"
|
||||
},
|
||||
"429": {
|
||||
"message": "Vous cherchez à envoyer beaucoup de segments, y en a-t-il vraiment autant ?"
|
||||
},
|
||||
"409": {
|
||||
"message": "Déja soumis"
|
||||
},
|
||||
"channelWhitelisted": {
|
||||
"message": "Cette chaîne est sur la liste blanche !"
|
||||
},
|
||||
"Sponsor": {
|
||||
"message": "message commercial"
|
||||
},
|
||||
"Sponsors": {
|
||||
"message": "messages commerciaux"
|
||||
},
|
||||
"Segment": {
|
||||
"message": "segment commercial"
|
||||
},
|
||||
"Segments": {
|
||||
"message": "segments commerciaux"
|
||||
},
|
||||
"noticeTitle": {
|
||||
"message": "Message commercial passé"
|
||||
},
|
||||
"reportButtonTitle": {
|
||||
"message": "Incorrect"
|
||||
},
|
||||
"reportButtonInfo": {
|
||||
"message": "Signaler que ce segment commercial est incorrect ou n'existe pas."
|
||||
},
|
||||
"Dismiss": {
|
||||
"message": "Fermer"
|
||||
},
|
||||
"Loading": {
|
||||
"message": "Chargement en cours..."
|
||||
},
|
||||
"Mins": {
|
||||
"message": "Minutes"
|
||||
},
|
||||
"Secs": {
|
||||
"message": "Secondes"
|
||||
},
|
||||
"Hide": {
|
||||
"message": "Ne plus montrer"
|
||||
},
|
||||
"hitGoBack": {
|
||||
"message": "Cliquez sur revenir en arrière pour revenir avant le saut du segment commercial"
|
||||
},
|
||||
"unskip": {
|
||||
"message": "Revenir en arrière"
|
||||
},
|
||||
"reskip": {
|
||||
"message": "Sauter"
|
||||
},
|
||||
"paused": {
|
||||
"message": "En pause"
|
||||
},
|
||||
"confirmMSG": {
|
||||
"message": "\n\nPour modifier ou supprimer des soumissions, cliquez sur le bouton d'info ou ouvrez la fenêtre de l'extension en cliquant sur son icône dans le coin en haut à droite."
|
||||
},
|
||||
"clearThis": {
|
||||
"message": "Êtes-vous certain(e) de vouloir supprimer vos soumissions ?\n\n"
|
||||
},
|
||||
"Unknown": {
|
||||
"message": "Une erreur s'est produite lors de la soumission, veuillez ré-essayer plus tard."
|
||||
},
|
||||
"sponsorFound": {
|
||||
"message": "Les messages commerciaux sont déjà dans notre base de donnée pour cette vidéo !"
|
||||
},
|
||||
"sponsor404": {
|
||||
"message": "Pas de messages commerciaux trouvés"
|
||||
},
|
||||
"sponsorStart": {
|
||||
"message": "Début du message commercial"
|
||||
},
|
||||
"sponsorEnd": {
|
||||
"message": "Fin du message commercial"
|
||||
},
|
||||
"noVideoID": {
|
||||
"message": "Ceci n'est pas un onglet YouTube, ou vous avez cliqué trop tôt. \n Si vous êtes sûr(e) que c'est un onglet YouTube, fermez cette fenêtre et réessayez."
|
||||
},
|
||||
"success": {
|
||||
"message": "Succès !"
|
||||
},
|
||||
"voted": {
|
||||
"message": "A voté !"
|
||||
},
|
||||
"voteFail": {
|
||||
"message": "Vous avez déjà voté pour ce choix."
|
||||
},
|
||||
"serverDown": {
|
||||
"message": "Le serveur ne fonctionne pas. Contactez le développeur."
|
||||
},
|
||||
"connectionError": {
|
||||
"message": "Erreur de connexion. Code d'erreur : "
|
||||
},
|
||||
"wantToSubmit": {
|
||||
"message": "Voulez-vous soumettre les segments commerciaux pour cette vidéo"
|
||||
},
|
||||
"leftTimes": {
|
||||
"message": "Vous avez laissé des segments commerciaux non soumis. Retournez sur la vidéo pour les soumettre (ils ont été conservés)."
|
||||
},
|
||||
"clearTimes": {
|
||||
"message": "Supprimer les segments commerciaux"
|
||||
},
|
||||
"openPopup": {
|
||||
"message": "Ouvrir l'encart SponsorBlock"
|
||||
},
|
||||
"SubmitTimes": {
|
||||
"message": "Soumettre les segments commerciaux"
|
||||
},
|
||||
"submitCheck": {
|
||||
"message": "Êtes-vous sûr de vouloir soumettre ces segments?"
|
||||
},
|
||||
"whitelistChannel": {
|
||||
"message": "Ajouter la chaîne à la liste blanche"
|
||||
},
|
||||
"removeFromWhitelist": {
|
||||
"message": "Supprimer la chaîne de la liste blanche"
|
||||
},
|
||||
"whitelistDescription": {
|
||||
"message": "Ajouter à la liste blanche les chaînes qui publient des messages commerciaux de façon éthique pour encourager les bons comportements, ou qui publient des messages commerciaux divertissants ou drôles. Ou pas, c'est votre choix."
|
||||
},
|
||||
"voteOnTime": {
|
||||
"message": "Voter sur un segment commercial"
|
||||
},
|
||||
"recordTimes": {
|
||||
"message": "Enregistrer un segment commercial"
|
||||
},
|
||||
"soFarUHSubmited": {
|
||||
"message": "Vous avez soumis jusqu'à présent"
|
||||
},
|
||||
"savedPeopleFrom": {
|
||||
"message": "Vous avez fait gagner aux autres "
|
||||
},
|
||||
"viewLeaderboard": {
|
||||
"message": "Consulter le classement"
|
||||
},
|
||||
"here": {
|
||||
"message": "ici"
|
||||
},
|
||||
"recordTimesDescription": {
|
||||
"message": "Cliquez sur le bouton ci-dessous quand le segment commercial commence puis \nse termine pour l'enregistrer et le soumettre à la base de données."
|
||||
},
|
||||
"popupHint": {
|
||||
"message": "Astuce : utilisez la touche point-virgule lorsque la vidéo est sélectionnée pour enregistrer le début et la fin d'un segment commercial; utilisez la touche guillemet pour le soumettre. (Les touches peuvent être modifiées dans les options)"
|
||||
},
|
||||
"lastTimes": {
|
||||
"message": "Derniers temps choisis pour le segment commercial"
|
||||
},
|
||||
"clearTimesButton": {
|
||||
"message": "Supprimer les temps"
|
||||
},
|
||||
"submitTimesButton": {
|
||||
"message": "Soumettre les temps"
|
||||
},
|
||||
"publicStats": {
|
||||
"message": "Affiché sur le classement public pour montrer vos contributions. Voir sur"
|
||||
},
|
||||
"setUsername": {
|
||||
"message": "Choisir pseudo"
|
||||
},
|
||||
"discordAdvert": {
|
||||
"message": "Rejoignez le serveur Discord officiel pour toutes suggestions ou remarques!"
|
||||
},
|
||||
"hideThis": {
|
||||
"message": "Cacher"
|
||||
},
|
||||
"Options": {
|
||||
"message": "Options"
|
||||
},
|
||||
"showButtons": {
|
||||
"message": "Montrer les boutons sur le lecteur YouTube"
|
||||
},
|
||||
"hideButtons": {
|
||||
"message": "Cacher les boutons sur le lecteur YouTube"
|
||||
},
|
||||
"hideButtonsDescription": {
|
||||
"message": "Cela permet de cacher du lecteur YouTube les boutons utilisés pour soumettre des segments commerciaux. Je peux \ncomprendre que certaines personnes les trouvent perturbants. Au lieu d'utiliser ces boutons, cette fenêtre peut être utilisée \npour soumettre des segments commerciaux. Pour cacher la notification, utilisez le bouton \"Ne plus montrer\" sur la notification. Vous pouvez toujours réactiver ces paramètres plus tard."
|
||||
},
|
||||
"showInfoButton": {
|
||||
"message": "Montrer le bouton Info sur le lecteur YouTube"
|
||||
},
|
||||
"hideInfoButton": {
|
||||
"message": "Cacher le bouton Info sur le lecteur YouTube"
|
||||
},
|
||||
"whatInfoButton": {
|
||||
"message": "Il s'agit du bouton qui ouvre l'encart sur la page YouTube."
|
||||
},
|
||||
"hideDeleteButton": {
|
||||
"message": "Cacher le bouton Supprimer sur le lecteur YouTube"
|
||||
},
|
||||
"showDeleteButton": {
|
||||
"message": "Montrer le bouton Supprimer sur le lecteur YouTube"
|
||||
},
|
||||
"whatDeleteButton": {
|
||||
"message": "Il s'agit du bouton qui permet de supprimer tous les segments commerciaux depuis le lecteur YouTube."
|
||||
},
|
||||
"disableViewTracking": {
|
||||
"message": "Désactiver le suivi des vues de segments commerciaux"
|
||||
},
|
||||
"enableViewTracking": {
|
||||
"message": "Activer le suivi des vues de segments commerciaux"
|
||||
},
|
||||
"whatViewTracking": {
|
||||
"message": "Cette fonctionnalité suit quels segments commerciaux vous avez sautés afin de calculer le bénéfice des soumissions des \nautres utilisateurs. Elle est également utilisée comme métrique, avec les haut-votes, afin de s'assurer que les spams \nsont ignorés. L'extension envoie un message au serveur à chauqe fois qu'un segment commercial est sauté. Avec un peu de chance, peu de personnes désactiveront cette fonctionnalité afin d'obtenir des nombres de vues exacts. :)"
|
||||
},
|
||||
"showNotice": {
|
||||
"message": "Afficher la notification"
|
||||
},
|
||||
"longDescription": {
|
||||
"message": "SponsorBlock est une extension qui permet de passer les messages commerciaux des vidéos YouTube. SponsorBlock est une extension pour navigateur basée sur le crowdsourcing permettant à n'importe qui de soumettre le début et la fin des segments commerciaux sur les vidéos YouTube. Dès qu'une personne a soumis ces informations, les autres utilisateurs de l'extension en bénéficieront et verront les messages commerciaux automatiquement sautés.",
|
||||
"description": "Full description of the extension on the store pages."
|
||||
},
|
||||
"website": {
|
||||
"message": "Site web",
|
||||
"description": "Used on Firefox Store Page"
|
||||
},
|
||||
"sourceCode": {
|
||||
"message": "Code source",
|
||||
"description": "Used on Firefox Store Page"
|
||||
},
|
||||
"noticeUpdate": {
|
||||
"message": "La notification a été mise à jour !",
|
||||
"description": "The first line of the message displayed after the notice was upgraded."
|
||||
},
|
||||
"noticeUpdate2": {
|
||||
"message": "Si elle ne vous plaît pas, cliquez sur le bouton \"Ne plus montrer\"",
|
||||
"description": "The second line of the message displayed after the notice was upgraded."
|
||||
},
|
||||
"setStartSponsorShortcut": {
|
||||
"message": "Changer le raccourci pour enregistrer un segment"
|
||||
},
|
||||
"setSubmitKeybind": {
|
||||
"message": "Changer le raccourci pour soumettre les segments"
|
||||
},
|
||||
"keybindDescription": {
|
||||
"message": "Appuyez sur une touche"
|
||||
},
|
||||
"keybindDescriptionComplete": {
|
||||
"message": "Le raccourci choisi est : "
|
||||
}
|
||||
}
|
||||
244
_locales/it/messages.json
Normal file
244
_locales/it/messages.json
Normal file
@@ -0,0 +1,244 @@
|
||||
{
|
||||
"Name": {
|
||||
"message": "SponsorBlock",
|
||||
"description": "Name of the extension."
|
||||
},
|
||||
"fullName": {
|
||||
"message": "SponsorBlock per YouTube - Salta gli sponsor",
|
||||
"description": "Name of the extension."
|
||||
},
|
||||
|
||||
"Description": {
|
||||
"message": "Salta i contenuti sponsorizzati nei video di YouTube. Segnala gli annunci incorporati nei video che guardi per far risparmiare tempo agli altri.",
|
||||
"description": "Description of the extension."
|
||||
},
|
||||
"helpPage": {
|
||||
"message": "index_en.html"
|
||||
},
|
||||
"400": {
|
||||
"message": "Richiesta non valida"
|
||||
},
|
||||
"429": {
|
||||
"message": "Stai inviando troppi spezzoni per questo video, sei sicuro che ce ne siano così tanti?"
|
||||
},
|
||||
"409": {
|
||||
"message": "Questo spezzone è già stato inviato"
|
||||
},
|
||||
"channelWhitelisted": {
|
||||
"message": "Canale aggiunto alla whitelist!"
|
||||
},
|
||||
"Sponsor": {
|
||||
"message": "sponsorizzazione"
|
||||
},
|
||||
"Sponsors": {
|
||||
"message": "sponsorizzazioni"
|
||||
},
|
||||
"Segment": {
|
||||
"message": "spezzone sponsorizzato"
|
||||
},
|
||||
"Segments": {
|
||||
"message": "spezzoni sponsorizzati"
|
||||
},
|
||||
"noticeTitle": {
|
||||
"message": "Sponsorizzazione Saltata"
|
||||
},
|
||||
"reportButtonTitle": {
|
||||
"message": "Segnala"
|
||||
},
|
||||
"reportButtonInfo": {
|
||||
"message": "Segnala questo spezzone come non corretto."
|
||||
},
|
||||
"Dismiss": {
|
||||
"message": "Chiudi"
|
||||
},
|
||||
"Loading": {
|
||||
"message": "Caricamento..."
|
||||
},
|
||||
"Mins": {
|
||||
"message": "Minuti"
|
||||
},
|
||||
"Secs": {
|
||||
"message": "Secondi"
|
||||
},
|
||||
"Hide": {
|
||||
"message": "Non mostrare più"
|
||||
},
|
||||
"hitGoBack": {
|
||||
"message": "Premi non saltare per tornare da dove sei venuto."
|
||||
},
|
||||
"unskip": {
|
||||
"message": "Non saltare"
|
||||
},
|
||||
"reskip": {
|
||||
"message": "Salta ancora"
|
||||
},
|
||||
"paused": {
|
||||
"message": "In pausa"
|
||||
},
|
||||
"confirmMSG": {
|
||||
"message": "\n\nPer modificare o eliminare valori specifici, premi il pulsante delle informazioni o apri il popup cliccando l'icona dell'estensione nell'angolo in alto a destra."
|
||||
},
|
||||
"clearThis": {
|
||||
"message": "Sei sicuro di volerlo cancellare?\n\n"
|
||||
},
|
||||
"Unknown": {
|
||||
"message": "Si è verificato un errore durante l'invio dello spezzone sponsorizzato, per favore riprova più tardi."
|
||||
},
|
||||
|
||||
"sponsorFound": {
|
||||
"message": "I contenuti sponsorizzati di questo video sono nel database!"
|
||||
},
|
||||
"sponsor404": {
|
||||
"message": "Nessuna sponsorizzazione trovata"
|
||||
},
|
||||
"sponsorStart": {
|
||||
"message": "La sponsorizzazione inizia adesso"
|
||||
},
|
||||
"sponsorEnd": {
|
||||
"message": "La sponsorizzazione finisce adesso"
|
||||
},
|
||||
"noVideoID": {
|
||||
"message": "Probabilmente questa non è una scheda di YouTube, oppure hai cliccato troppo presto. \nSe sei sicuro di essere in una scheda di YouTube,\n riapri questo popup."
|
||||
},
|
||||
"success": {
|
||||
"message": "Successo!"
|
||||
},
|
||||
"voted": {
|
||||
"message": "Votato!"
|
||||
},
|
||||
"voteFail": {
|
||||
"message": "Hai già votato."
|
||||
},
|
||||
"serverDown": {
|
||||
"message": "Sembra che il server non funzioni. Contatta subito lo sviluppatore."
|
||||
},
|
||||
"connectionError": {
|
||||
"message": "Si è verificato un errore durante la connessione. Codice errore: "
|
||||
},
|
||||
"wantToSubmit": {
|
||||
"message": "Vuoi inviare gli spezzoni sponsorizzati per il video con id"
|
||||
},
|
||||
"leftTimes": {
|
||||
"message": "Sembra che tu non abbia inviato alcuni spezzoni sponsorizzati. Ritorna alla pagina precedente per inviarli (non sono stati eliminati)."
|
||||
},
|
||||
"clearTimes": {
|
||||
"message": "Cancella gli Spezzoni Sponsorizzati"
|
||||
},
|
||||
"openPopup": {
|
||||
"message": "Apri il Popup di SponsorBlock"
|
||||
},
|
||||
"SubmitTimes": {
|
||||
"message": "Invia gli Spezzoni Sponsorizzati"
|
||||
},
|
||||
"submitCheck": {
|
||||
"message": "Sei sicuro di volerlo inviare?"
|
||||
},
|
||||
"whitelistChannel": {
|
||||
"message": "Aggiungi Canale alla Whitelist"
|
||||
},
|
||||
"removeFromWhitelist": {
|
||||
"message": "Rimuovi Canale dalla Whitelist"
|
||||
},
|
||||
"whitelistDescription": {
|
||||
"message": "Aggiungi alla whitelist i canali che sponsorizzano eticamente per incoraggiare ad un comportamento corretto, oppure se sono semplicemente intrattenenti e divertenti. Oppure non farlo, decidi tu."
|
||||
},
|
||||
"voteOnTime": {
|
||||
"message": "Vota uno Spezzone Sponsorizzato"
|
||||
},
|
||||
"recordTimes": {
|
||||
"message": "Registra uno Spezzone Sponsorizzato"
|
||||
},
|
||||
"soFarUHSubmited": {
|
||||
"message": "Fino ad ora hai inviato"
|
||||
},
|
||||
"savedPeopleFrom": {
|
||||
"message": "Hai salvato le persone da "
|
||||
},
|
||||
"viewLeaderboard": {
|
||||
"message": "Guarda la classifica"
|
||||
},
|
||||
"here": {
|
||||
"message": "qui"
|
||||
},
|
||||
"recordTimesDescription": {
|
||||
"message": "Premi il pulsante qui sotto quando inizia e finisce la sponsorizzazione per registrarla e\ninviarla al database."
|
||||
},
|
||||
"popupHint": {
|
||||
"message": "Suggerimento: Premi il tasto punto e virgola mentre il video è attivo per segnalare l'inizio/fine di una sponsorizzazione e virgolette per inviare."
|
||||
},
|
||||
"lastTimes": {
|
||||
"message": "Ultimi minutaggi sponsorizzati scelti"
|
||||
},
|
||||
"clearTimesButton": {
|
||||
"message": "Cancella Minutaggi"
|
||||
},
|
||||
"submitTimesButton": {
|
||||
"message": "Invia Minutaggi"
|
||||
},
|
||||
"publicStats": {
|
||||
"message": "Viene utilizzato nelle pagine delle statistiche pubbliche che mostrano quanto hai contribuito. Vedi"
|
||||
},
|
||||
"setUsername": {
|
||||
"message": "Imposta Username"
|
||||
},
|
||||
"discordAdvert": {
|
||||
"message": "Entra nel server Discord ufficiale per darci suggerimenti e feedback!"
|
||||
},
|
||||
"hideThis": {
|
||||
"message": "Nascondi"
|
||||
},
|
||||
"Options": {
|
||||
"message": "Opzioni"
|
||||
},
|
||||
"showButtons": {
|
||||
"message": "Mostra i Pulsanti nel Lettore di YouTube"
|
||||
},
|
||||
"hideButtons": {
|
||||
"message": "Nascondi i Pulsanti nel Lettore di YouTube"
|
||||
},
|
||||
"hideButtonsDescription": {
|
||||
"message": "Nasconde i pulsanti che appaiono nel lettore di YouTube per inviare spezzoni sponsorizzati. Capisco che può essere fastidioso per alcune\n persone. Invece di utilizzare quei pulsanti, è possibile utilizzare questo popup per inviare gli spezzoni sponsorizzati. Per nascondere l'avviso che appare, \nusa il bottone \"Non mostrare più\" nell'avviso. Potrai sempre abilitare nuovamente queste impostazioni in futuro."
|
||||
},
|
||||
"showInfoButton": {
|
||||
"message": "Mostra il Pulsante Informazioni nel Lettore di YouTube"
|
||||
},
|
||||
"hideInfoButton": {
|
||||
"message": "Nascondi il Pulsante Informazioni nel Lettore di YouTube"
|
||||
},
|
||||
"whatInfoButton": {
|
||||
"message": "Questo è il pulsante che apre un popup nella pagina YouTube."
|
||||
},
|
||||
"hideDeleteButton": {
|
||||
"message": "Nascondi il Pulsante Elimina nel Lettore di YouTube"
|
||||
},
|
||||
"showDeleteButton": {
|
||||
"message": "Mostra il Pulsante Elimina nel Lettore di YouTube"
|
||||
},
|
||||
"whatDeleteButton": {
|
||||
"message": "Questo è il pulsante che ti permette di cancellare tutti gli spezzoni sponsorizzati nel lettore di YouTube."
|
||||
},
|
||||
"disableViewTracking": {
|
||||
"message": "Disattiva il Monitoraggio delle Sponsorizzazioni"
|
||||
},
|
||||
"enableViewTracking": {
|
||||
"message": "Disattiva il Monitoraggio delle Sponsorizzazioni"
|
||||
},
|
||||
"whatViewTracking": {
|
||||
"message": "Questa funzione tiene traccia di quali sponsorizzazioni hai saltato per far sapere agli utenti quanto è stato d'aiuto agli altri il loro contributo e\nviene utilizzato come metrica assieme ai voti positivi per filtrare lo spam dal database. L'estensione invia un messaggio\nal server ogni volta che salti una sponsorizzazione. Si spera che la maggior parte delle persone non modifichi questa impostazione così i numeri sono accurati. :)"
|
||||
},
|
||||
"showNotice": {
|
||||
"message": "Mostra di Nuovo l'Avviso"
|
||||
},
|
||||
"longDescription": {
|
||||
"message": "SponsorBlock è un'estensione che salta gli spezzoni con contenuti sponsorizzati nei video di YouTube. SponsorBlock è un'estensione crowdsourced per i browser che permette a chiunque di inviare i minutaggi degli spezzoni sponsorizzati nei video di YouTube. Quando una persona avrà inviato questa informazione, tutti gli utenti che utilizzano questa estensione potranno saltare lo spezzone sponsorizzato.",
|
||||
"description": "Full description of the extension on the store pages."
|
||||
},
|
||||
"website": {
|
||||
"message": "Sito Web",
|
||||
"description": "Used on Firefox Store Page"
|
||||
},
|
||||
"sourceCode": {
|
||||
"message": "Codice Sorgente",
|
||||
"description": "Used on Firefox Store Page"
|
||||
}
|
||||
}
|
||||
390
_locales/pl_PL/messages.json
Normal file
390
_locales/pl_PL/messages.json
Normal file
@@ -0,0 +1,390 @@
|
||||
{
|
||||
"Name": {
|
||||
"message": "SponsorBlock",
|
||||
"description": "Nazwa rozszerzenia."
|
||||
},
|
||||
"fullName": {
|
||||
"message": "SponsorBlock na YouTube - Omiń reklamy sponsorów",
|
||||
"description": "Nazwa rozszerzenia."
|
||||
},
|
||||
|
||||
"Description": {
|
||||
"message": "Przewijaj reklamy sponsorów w filmach na YouTube. Zgłaszaj reklamy w nagraniach żeby nie marnować czasu innych.",
|
||||
"description": "Opis rozszerzenia."
|
||||
},
|
||||
"helpPage": {
|
||||
"message": "index_en.html"
|
||||
},
|
||||
"400": {
|
||||
"message": "Serwer odpowiedział, że to zapytanie jest niepoprawne"
|
||||
},
|
||||
"429": {
|
||||
"message": "Zgłosiłeś bardzo dużo segmentów reklamowych dla tego jednego nagrania, jesteś pewien, że jest ich tak dużo?"
|
||||
},
|
||||
"409": {
|
||||
"message": "Treść została już wcześniej zgłoszona"
|
||||
},
|
||||
"channelWhitelisted": {
|
||||
"message": "Kanał dodany do wyjątków!"
|
||||
},
|
||||
"Sponsor": {
|
||||
"message": "sponsor"
|
||||
},
|
||||
"Sponsors": {
|
||||
"message": "sponsorzy"
|
||||
},
|
||||
"Segment": {
|
||||
"message": "segmet sponsorowany"
|
||||
},
|
||||
"Segments": {
|
||||
"message": "segmenty sponsorowane"
|
||||
},
|
||||
"noticeTitle": {
|
||||
"message": "Segment przewinięty"
|
||||
},
|
||||
"reportButtonTitle": {
|
||||
"message": "Zgłoś"
|
||||
},
|
||||
"reportButtonInfo": {
|
||||
"message": "Zgłoś ten segment reklamowy jako nieprawidłowy."
|
||||
},
|
||||
"Dismiss": {
|
||||
"message": "Odrzuć"
|
||||
},
|
||||
"Loading": {
|
||||
"message": "Ładowanie..."
|
||||
},
|
||||
"Mins": {
|
||||
"message": "Minuty"
|
||||
},
|
||||
"Secs": {
|
||||
"message": "Sekundy"
|
||||
},
|
||||
"Hide": {
|
||||
"message": "Nigdy nie pokazuj"
|
||||
},
|
||||
"hitGoBack": {
|
||||
"message": "Kliknij cofnij aby przenieść się do miejsca przed przewinięciem."
|
||||
},
|
||||
"unskip": {
|
||||
"message": "Cofnij"
|
||||
},
|
||||
"reskip": {
|
||||
"message": "Przewiń"
|
||||
},
|
||||
"paused": {
|
||||
"message": "Zatrzymany"
|
||||
},
|
||||
"confirmMSG": {
|
||||
"message": "Żeby zmienić lub usunąć wartości, kliknij na guzik informacji lub otwórz okienko rozszerzenia klikając w ikonę rozszerzenia znajdującą się w prawym górnym rogu."
|
||||
},
|
||||
"clearThis": {
|
||||
"message": "Jesteś pewien, że chcesz to usunąć?\n\n"
|
||||
},
|
||||
"Unknown": {
|
||||
"message": "Wystąpił błąd podczas przesyłania twojego zgłoszenia, proszę spróbować ponownie później."
|
||||
},
|
||||
"sponsorFound": {
|
||||
"message": "Segmenty reklamowe dla tego nagrania są już w bazie!"
|
||||
},
|
||||
"sponsor404": {
|
||||
"message": "Nie znaleziono segmentów reklamowych"
|
||||
},
|
||||
"sponsorStart": {
|
||||
"message": "Reklama zaczyna się teraz"
|
||||
},
|
||||
"sponsorEnd": {
|
||||
"message": "Reklama kończy się teraz"
|
||||
},
|
||||
"noVideoID": {
|
||||
"message": "Nie znaleziono nagrania wideo w tej karcie. Jeśli wiesz, że to karta YouTube'a, zamknij to okienko i otwórz je ponownie. Jeśli to nie zadziała spróbuj przeładować stronę."
|
||||
},
|
||||
"success": {
|
||||
"message": "Sukces!"
|
||||
},
|
||||
"voted": {
|
||||
"message": "Zagłosowano!"
|
||||
},
|
||||
"voteFail": {
|
||||
"message": "Już na to głosowałeś."
|
||||
},
|
||||
"serverDown": {
|
||||
"message": "Wygląda na to, że serwer nie działa. Skontaktuj się z dewloperem."
|
||||
},
|
||||
"connectionError": {
|
||||
"message": "Błąd z połączeniem. Kod błędu: "
|
||||
},
|
||||
"wantToSubmit": {
|
||||
"message": "Chcesz zgłosić segment sponsorowany dla nagrania z id"
|
||||
},
|
||||
"leftTimes": {
|
||||
"message": "Wygląda na to, że masz nie wysłane segmenty reklamowe. Cofnij się do tej strony i zgłoś je (nie zostały usunięte)."
|
||||
},
|
||||
"clearTimes": {
|
||||
"message": "Wyczyść segmenty reklamowe"
|
||||
},
|
||||
"openPopup": {
|
||||
"message": "Otwórz okienko SponsorBlock"
|
||||
},
|
||||
"SubmitTimes": {
|
||||
"message": "Zgłoś segmenty reklamowe"
|
||||
},
|
||||
"submitCheck": {
|
||||
"message": "Jesteś pewien, że chcesz to zgłosić?"
|
||||
},
|
||||
"whitelistChannel": {
|
||||
"message": "Dodaj kanał do wyjątków"
|
||||
},
|
||||
"removeFromWhitelist": {
|
||||
"message": "Usuń kanał z listy wyjątków"
|
||||
},
|
||||
"voteOnTime": {
|
||||
"message": "Głosuj na segment reklamowy"
|
||||
},
|
||||
"recordTimes": {
|
||||
"message": "Nagraj czasy segmentów reklamowych"
|
||||
},
|
||||
"soFarUHSubmited": {
|
||||
"message": "Jak na razie zgłosiłeś:"
|
||||
},
|
||||
"savedPeopleFrom": {
|
||||
"message": "Ocaliłeś ludzi przed "
|
||||
},
|
||||
"viewLeaderboard": {
|
||||
"message": "Zobacz ranking użytkowników"
|
||||
},
|
||||
"here": {
|
||||
"message": "tutaj"
|
||||
},
|
||||
"recordTimesDescription": {
|
||||
"message": "Kliknij guzik poniżej kiedy segment reklamowy się zaczyna i kończy żeby go oznaczyć i wysłać do bazy danych."
|
||||
},
|
||||
"popupHint": {
|
||||
"message": "Podpowiedź: Klikając średnik kiedy zaznaczone jest zgłaszanie wideo możesz oznaczyć początek reklamy, znakiem cytatu oznaczysz jej koniec. (Klawisze można zmienić w opcjach)"
|
||||
},
|
||||
"lastTimes": {
|
||||
"message": "Ostanie wybrane czasy reklam"
|
||||
},
|
||||
"clearTimesButton": {
|
||||
"message": "Usuń czasy"
|
||||
},
|
||||
"submitTimesButton": {
|
||||
"message": "Zgłoś czasy"
|
||||
},
|
||||
"publicStats": {
|
||||
"message": "Ten dane są używane na naszej stronie żeby pokazać twój wkład. Zobacz to"
|
||||
},
|
||||
"setUsername": {
|
||||
"message": "Ustaw nazwę użytkownika"
|
||||
},
|
||||
"discordAdvert": {
|
||||
"message": "Dołącz do oficjalnego serwera na discordzie i podziel się wrażeniami i sugestiami!"
|
||||
},
|
||||
"hideThis": {
|
||||
"message": "Ukryj to"
|
||||
},
|
||||
"Options": {
|
||||
"message": "Opcje"
|
||||
},
|
||||
"showButtons": {
|
||||
"message": "Pokaż guziki w odtwarzaczu YouTube"
|
||||
},
|
||||
"hideButtons": {
|
||||
"message": "Ukryj guziki w odtwarzaczu YouTube"
|
||||
},
|
||||
"hideButtonsDescription": {
|
||||
"message": "Ta opcja ukrywa guziki zgłaszania reklamy w odtwarzaczu. Wiem, że mogą one irytować niektórych. Zamiast zgłaszania bezpośrednio w odtwarzaczu możesz to zrobić w tym okienku. Zawsze możesz zmienić te opcje później."
|
||||
},
|
||||
"showInfoButton": {
|
||||
"message": "Pokaż guzik informacyjny w odtwarzaczu YouTube"
|
||||
},
|
||||
"hideInfoButton": {
|
||||
"message": "Ukryj guzik informacyjny w odtwarzaczu YouTube"
|
||||
},
|
||||
"whatInfoButton": {
|
||||
"message": "Jest to guzik otwierający popup na stronie YouTube."
|
||||
},
|
||||
"hideDeleteButton": {
|
||||
"message": "Ukryj guzik usuwania w odtwarzaczu YouTube"
|
||||
},
|
||||
"showDeleteButton": {
|
||||
"message": "Pokaż guzik usuwania w odtwarzaczu YouTube"
|
||||
},
|
||||
"whatDeleteButton": {
|
||||
"message": "Ten guzik pozwala ci wyczyścić wszystkie segmenty reklamowe w odtwarzaczu YouTube."
|
||||
},
|
||||
"disableViewTracking": {
|
||||
"message": "Wyłącz licznik przewinięć"
|
||||
},
|
||||
"enableViewTracking": {
|
||||
"message": "Włącz licznik przewinięć"
|
||||
},
|
||||
"whatViewTracking": {
|
||||
"message": "Ta opcja śledzi które segmenty pominąłeś i informuje zgłaszających ile czasu Ci zaoszczędzili, też wraz systemem głosowania pomaga wykrywać spam w zgłoszeniach. Rozszerzenie wysyła zapytanie do serwera za każdym razem kiedy przewinąłeś segment reklamowy. Miejmy nadzieję, że większość ludzi tego nie wyłączy i licznik wyświetleń będzie rzetelny. :)"
|
||||
},
|
||||
"showNotice": {
|
||||
"message": "Pokaż informacje ponownie"
|
||||
},
|
||||
"longDescription": {
|
||||
"message": "SponsorBlock jest rozszerzeniem które przewinie segmenty sponsorów w filmach na YouTube. SponsorBlock jest opartym na crowdsourcing rozszerzeniem które pozwala każdemu zgłaszać początek i koniec segmentu reklamowego w filmach na YouTube. Kiedy ktoś zgłosi taki fragment zostanie on pominięty przez innych użytkowników rozszerzenia.",
|
||||
"description": "Pełny opis rozszerzenia na stronie w sklepie."
|
||||
},
|
||||
"website": {
|
||||
"message": "Strona",
|
||||
"description": "Używane w sklepie Firefoxa"
|
||||
},
|
||||
"sourceCode": {
|
||||
"message": "Kod źródłowy",
|
||||
"description": "Używane w sklepie Firefoxa"
|
||||
},
|
||||
"noticeUpdate": {
|
||||
"message": "Informacje zostały zaktualizowane!",
|
||||
"description": "Pierwsza linia po aktualizacji informacji."
|
||||
},
|
||||
"noticeUpdate2": {
|
||||
"message": "Jeśli nadal jej nie lubisz wybierz opcje nie pokazuj więcej.",
|
||||
"description": "Druga linia po aktualizacji informacji."
|
||||
},
|
||||
"setStartSponsorShortcut": {
|
||||
"message": "Ustaw klawisz do oznaczania początku reklamy"
|
||||
},
|
||||
"setSubmitKeybind": {
|
||||
"message": "Ustaw klawisz do wysyłania czasów"
|
||||
},
|
||||
"keybindDescription": {
|
||||
"message": "Wybierz klawisz klikając go na klawiaturze"
|
||||
},
|
||||
"keybindDescriptionComplete": {
|
||||
"message": "Ustawiony klawisz to: "
|
||||
},
|
||||
"0": {
|
||||
"message": "Połączenie przerwane z powodu braku odpowiedzi. Sprawdź swoje połączenie z internetem. Jeśli wszystko z nim w porządku oznacza to, że serwer jest prawdopodobnie przeciążony lub nie działa."
|
||||
},
|
||||
"disableSkipping": {
|
||||
"message": "Wyłącz SponsorBlock"
|
||||
},
|
||||
"enableSkipping": {
|
||||
"message": "Włącz SponsorBlock"
|
||||
},
|
||||
"yourWork": {
|
||||
"message": "Twój wkład",
|
||||
"description": "Nagłowek sekcji ze statystykami użytkownika."
|
||||
},
|
||||
"502": {
|
||||
"message": "Serwer jest prawdopodobnie przeciążony, spróbuj ponownie za kilka sekund."
|
||||
},
|
||||
"errorCode": {
|
||||
"message": "Kod błędu: "
|
||||
},
|
||||
"noticeTitleNotSkipped": {
|
||||
"message": "Przewinąć reklamę?"
|
||||
},
|
||||
"skip": {
|
||||
"message": "Przewiń"
|
||||
},
|
||||
"disableAutoSkip": {
|
||||
"message": "Wyłącz auto przewijanie"
|
||||
},
|
||||
"enableAutoSkip": {
|
||||
"message": "Włącz auto przewijanie"
|
||||
},
|
||||
"autoSkipDescription": {
|
||||
"message": "Auto przewijanie przewinie segment za ciebie, wyłączone wyświetli komunikat z pytaniem czy chcesz przewinąć reklamę."
|
||||
},
|
||||
"youHaveSkipped": {
|
||||
"message": "Przewinąłeś "
|
||||
},
|
||||
"youHaveSaved": {
|
||||
"message": "Oszczędziłeś sobie "
|
||||
},
|
||||
"minLower": {
|
||||
"message": "minuta"
|
||||
},
|
||||
"minsLower": {
|
||||
"message": "minuty"
|
||||
},
|
||||
"hourLower": {
|
||||
"message": "godzina"
|
||||
},
|
||||
"hoursLower": {
|
||||
"message": "godziny"
|
||||
},
|
||||
"youHaveSavedTime": {
|
||||
"message": "Oszczędziłeś ludziom"
|
||||
},
|
||||
"youHaveSavedTimeEnd": {
|
||||
"message": " czasu."
|
||||
},
|
||||
"guildlinesSummary": {
|
||||
"message": "- Upewnij się, że zgłaszany fragment zawiera tylko reklamę i nic więcej.\n- Upewnij się, że nie zostanie przewinięta wartościowa treść\n- Jeśli całe nagranie to reklama, proszę nie zgłaszaj go. Blokowanie całych nagrań pojawi się wkrótce.\n- Nie ukrywaj treści które są istotne dla użytkownika (nie ukrywaj informacji, że recenzja produktu została opłacona przez producenta)"
|
||||
},
|
||||
"statusReminder": {
|
||||
"message": "Wejdź na status.sponsor.ajay.app żeby sprawdzić czy serwer działa."
|
||||
},
|
||||
"changeUserID": {
|
||||
"message": "Zaimportuj/Wyeksportuj swój UserID"
|
||||
},
|
||||
"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": {
|
||||
"message": "Ustaw UserID"
|
||||
},
|
||||
"userIDChangeWarning": {
|
||||
"message": "Ostrzeżenie: Zmiana UserID jest nieodwracalna. Jesteś pewien, że chcesz to zrobić? Skopiuj obecny UserID na wszelki wypadek."
|
||||
},
|
||||
"createdBy": {
|
||||
"message": "Stworzony przez"
|
||||
},
|
||||
"autoSkip": {
|
||||
"message": "Auto przewijanie"
|
||||
},
|
||||
"showSkipNotice": {
|
||||
"message": "Pokaż informację po przewiniętym fragmencie"
|
||||
},
|
||||
"keybindCurrentlySet": {
|
||||
"message": ". Jest obecnie ustawione jako:"
|
||||
},
|
||||
"supportInvidious": {
|
||||
"message": "Wesprzyj Invidious"
|
||||
},
|
||||
"supportInvidiousDescription": {
|
||||
"message": "Invidious (invidio.us) to nieoficjalny klient YouTube. Aby go wesprzeć musisz przyznać dodatkowe uprawnienia rozszerzeniowi. Ta opcja nie działa w incognito i innych wersjach Chromium."
|
||||
},
|
||||
"optionsInfo": {
|
||||
"message": "Wesprzyj Invidious, wyłącz auto przewijanie, ukryj guziki i więcej."
|
||||
},
|
||||
"addInvidiousInstance": {
|
||||
"message": "Dodaj instancje Invidious"
|
||||
},
|
||||
"addInvidiousInstanceDescription": {
|
||||
"message": "Dodaj niestandardową instancje Invidious. W formie domeny. Na przykład: invidious.ajay.app"
|
||||
},
|
||||
"add": {
|
||||
"message": "Dodaj"
|
||||
},
|
||||
"addInvidiousInstanceError": {
|
||||
"message": "Ta domena jest nieprawidłowa. Wartość powinna zawierać TYLKO domenę. Na przykład: invidious.ajay.app"
|
||||
},
|
||||
"resetInvidiousInstance": {
|
||||
"message": "Zresetuj listę instancji Invidious"
|
||||
},
|
||||
"resetInvidiousInstanceAlert": {
|
||||
"message": "Zresetujesz listę instancji Invidious"
|
||||
},
|
||||
"currentInstances": {
|
||||
"message": "Obecne instancje:"
|
||||
},
|
||||
"enableAutoUpvote": {
|
||||
"message": "Auto potwierdzanie"
|
||||
},
|
||||
"whatAutoUpvote": {
|
||||
"message": "To ustawienie sprawia, że wszystkie przewinięte przez ciebie a nie zgłoszone jako błąd segmenty reklamowe zostaną potwierdzone jako prawidłowe. Ta opcja nie działa jeśli okienko z informacją o przewinięciu jest ukryte."
|
||||
},
|
||||
"invidiousInfo1": {
|
||||
"message": "Invidious (nieoficjalny klient YouTube) została dodana do wspieranych!"
|
||||
},
|
||||
"invidiousInfo2": {
|
||||
"message": "Musisz odblokować to w opcjach aby móc to zrobić."
|
||||
}
|
||||
}
|
||||
244
_locales/pt_BR/messages.json
Normal file
244
_locales/pt_BR/messages.json
Normal file
@@ -0,0 +1,244 @@
|
||||
{
|
||||
"Name": {
|
||||
"message": "SponsorBlock",
|
||||
"description": "Nome da extensão."
|
||||
},
|
||||
"fullName": {
|
||||
"message": "SponsorBlock para YouTube - Pule patrocínios",
|
||||
"description": "Nome da extensão."
|
||||
},
|
||||
|
||||
"Description": {
|
||||
"message": "Pule patrocinadores em vídeos do YouTube. Reporte patrocinadores em videos que você assiste para salvar o tempo dos outros.",
|
||||
"description": "Descrição da extensão."
|
||||
},
|
||||
"helpPage": {
|
||||
"message": "index_en.html"
|
||||
},
|
||||
"400": {
|
||||
"message": "O servidor disse que esse pedido foi inválido"
|
||||
},
|
||||
"429": {
|
||||
"message": "Você enviou muitos segmentos para esse vídeo, tem certeza que tem tantos assim?"
|
||||
},
|
||||
"409": {
|
||||
"message": "Isso já foi enviado antes"
|
||||
},
|
||||
"channelWhitelisted": {
|
||||
"message": "Canal adicionado à lista branca!"
|
||||
},
|
||||
"Sponsor": {
|
||||
"message": "patrocinador"
|
||||
},
|
||||
"Sponsors": {
|
||||
"message": "patrocinadores"
|
||||
},
|
||||
"Segment": {
|
||||
"message": "segmento de patrocinador"
|
||||
},
|
||||
"Segments": {
|
||||
"message": "segmentos de patrocinadores"
|
||||
},
|
||||
"noticeTitle": {
|
||||
"message": "Patrocinador pulado"
|
||||
},
|
||||
"reportButtonTitle": {
|
||||
"message": "Reportar"
|
||||
},
|
||||
"reportButtonInfo": {
|
||||
"message": "Reportar essa subimissão como inválida."
|
||||
},
|
||||
"Dismiss": {
|
||||
"message": "Ignorar"
|
||||
},
|
||||
"Loading": {
|
||||
"message": "Carregando..."
|
||||
},
|
||||
"Mins": {
|
||||
"message": "Minutos"
|
||||
},
|
||||
"Secs": {
|
||||
"message": "Segundos"
|
||||
},
|
||||
"Hide": {
|
||||
"message": "Nunca mostrar"
|
||||
},
|
||||
"hitGoBack": {
|
||||
"message": "Aperta reverter pulo para voltar onde estava"
|
||||
},
|
||||
"unskip": {
|
||||
"message": "Reverter pulo"
|
||||
},
|
||||
"reskip": {
|
||||
"message": "Pular novamente"
|
||||
},
|
||||
"paused": {
|
||||
"message": "Pausado"
|
||||
},
|
||||
"confirmMSG": {
|
||||
"message": "\n\nPara editar ou remover linhas individuais, clique com o botão direito ou abra o popup da extensão pelo icone no canto superior direito."
|
||||
},
|
||||
"clearThis": {
|
||||
"message": "Tem certeza que quer limpar isso?\n\n"
|
||||
},
|
||||
"Unknown": {
|
||||
"message": "Teve um erro ao enviar seus segmentos, tente novamente depois."
|
||||
},
|
||||
|
||||
"sponsorFound": {
|
||||
"message": "Os patrocinadores desse vídeo estão no banco de dados!"
|
||||
},
|
||||
"sponsor404": {
|
||||
"message": "Nenhum patrocinador encontrado"
|
||||
},
|
||||
"sponsorStart": {
|
||||
"message": "Patrocínio começa agora"
|
||||
},
|
||||
"sponsorEnd": {
|
||||
"message": "Patrocínio termina agora"
|
||||
},
|
||||
"noVideoID": {
|
||||
"message": "Isso provavelmente não é uma tab do YouTube, ou você clicou muito cedo. \n Se sabe que é uma tab do YouTube,\n feche esse popup e abra de novo."
|
||||
},
|
||||
"success": {
|
||||
"message": "Sucesso!"
|
||||
},
|
||||
"voted": {
|
||||
"message": "Votado!"
|
||||
},
|
||||
"voteFail": {
|
||||
"message": "Você já votou antes."
|
||||
},
|
||||
"serverDown": {
|
||||
"message": "Parece que o servidor caiu. Contate o desenvolvedor o quanto antes."
|
||||
},
|
||||
"connectionError": {
|
||||
"message": "Um erro de conexão aconteceu: Código: "
|
||||
},
|
||||
"wantToSubmit": {
|
||||
"message": "Quer enviar os segmentos para o vídeo de ID"
|
||||
},
|
||||
"leftTimes": {
|
||||
"message": "Parece que você se esqueceu de enviar alguns segmentos. Volta pra página para os enviar (não foram deletados)."
|
||||
},
|
||||
"clearTimes": {
|
||||
"message": "Apagar intervalos dos patrocínios"
|
||||
},
|
||||
"openPopup": {
|
||||
"message": "Abrir o Popup SponsorBlock"
|
||||
},
|
||||
"SubmitTimes": {
|
||||
"message": "Submeter intervalos dos patrocínios"
|
||||
},
|
||||
"submitCheck": {
|
||||
"message": "Tem a certeza que pretende submeter?"
|
||||
},
|
||||
"whitelistChannel": {
|
||||
"message": "Meter canal na Whitelist"
|
||||
},
|
||||
"removeFromWhitelist": {
|
||||
"message": "Remover canal da Whitelist"
|
||||
},
|
||||
"whitelistDescription": {
|
||||
"message": "Colocar na Whitelist canais com patrocínios éticos que encoragem boas atitude, ou simplesmente canais com patrocínios engraçados. Ou não, é consigo."
|
||||
},
|
||||
"voteOnTime": {
|
||||
"message": "Vote num intervalo de patrocínio"
|
||||
},
|
||||
"recordTimes": {
|
||||
"message": "Registe um intervalo de patrocínio"
|
||||
},
|
||||
"soFarUHSubmited": {
|
||||
"message": "Até agora submeteu"
|
||||
},
|
||||
"savedPeopleFrom": {
|
||||
"message": "Poupaste a outros de "
|
||||
},
|
||||
"viewLeaderboard": {
|
||||
"message": "Ver a leaderboard"
|
||||
},
|
||||
"here": {
|
||||
"message": "aqui"
|
||||
},
|
||||
"recordTimesDescription": {
|
||||
"message": "Carregue neste botão abaixo quando o patrocínio começar e quando\n acabar para registar e submetê-lo à base de dados"
|
||||
},
|
||||
"popupHint": {
|
||||
"message": "Dica: Carregue na tecla ; enquanto num vídeo para registar o começo/fim de um patrocínio e \" para submeter"
|
||||
},
|
||||
"lastTimes": {
|
||||
"message": "Intervalos de Patrocínios Escolhidos mais Recentemente"
|
||||
},
|
||||
"clearTimesButton": {
|
||||
"message": "Limpar Intervalos"
|
||||
},
|
||||
"submitTimesButton": {
|
||||
"message": "Submeter Intervalos"
|
||||
},
|
||||
"publicStats": {
|
||||
"message": "Isto é usado na página pública de estatísticas que mostra o quanto já contríbuíu. Veje-a"
|
||||
},
|
||||
"setUsername": {
|
||||
"message": "Criar nomde de utilizador"
|
||||
},
|
||||
"discordAdvert": {
|
||||
"message": "Junte-se ao discord oficial para sugerir dicas e sugestões!"
|
||||
},
|
||||
"hideThis": {
|
||||
"message": "Esconder isto"
|
||||
},
|
||||
"Options": {
|
||||
"message": "Opções"
|
||||
},
|
||||
"showButtons": {
|
||||
"message": "Mostrar botões no player do Youtube"
|
||||
},
|
||||
"hideButtons": {
|
||||
"message": "Esconder botões no player do Youtube"
|
||||
},
|
||||
"hideButtonsDescription": {
|
||||
"message": "Isto esconde os botões que aparecem no player do Youtube para submeter patrocínios. Entendemos que possa ser\n incómodo a algumas pessoas. Em vez de usar esses botões pode usar os do popup. Para esconder a mensagem que aparece, \n ususe o botão na mesma que diz \"Don't show this again\". Pode sempre reactivar estas definições novamente."
|
||||
},
|
||||
"showInfoButton": {
|
||||
"message": "Mostrar botão de Informações no player do Youtube"
|
||||
},
|
||||
"hideInfoButton": {
|
||||
"message": "Esconder botão de Informações no player do Youtube"
|
||||
},
|
||||
"whatInfoButton": {
|
||||
"message": "Este é o botão que abre o popup na pagina do Youtube."
|
||||
},
|
||||
"hideDeleteButton": {
|
||||
"message": "Esconder botão de Apagar no player do Youtube"
|
||||
},
|
||||
"showDeleteButton": {
|
||||
"message": "Mostrar botão de Apagar no player do Youtube"
|
||||
},
|
||||
"whatDeleteButton": {
|
||||
"message": "Este é o botão que lhe permite saltar todos os patrocínios do player do Youtube."
|
||||
},
|
||||
"disableViewTracking": {
|
||||
"message": "Desactivar registo de visualização de patrocínios"
|
||||
},
|
||||
"enableViewTracking": {
|
||||
"message": "Activar registo de visualização de patrocínios"
|
||||
},
|
||||
"whatViewTracking": {
|
||||
"message": "Esta funcionalidade regista que patrocínios tem saltado para que outros utilizadores saibam o quanto as suas submições têm ajudado outros\n e é usado como métrica de votos para evitar spam na base de dados. A extenção \n envia uma notificação ao servidor sempre que salta um patrocínio. Quanto menos pessoas desactivarem esta funcionalidade mais precisas serão as estimativas :)"
|
||||
},
|
||||
"showNotice": {
|
||||
"message": "Mostrar notificação outra vez"
|
||||
},
|
||||
"longDescription": {
|
||||
"message": "SponsorBlock é uma extensão que salta segmentos patrocinados em vídeos do YouTube. SponsorBlock é uma extenção crowdfunded que permite a qualquer um submeter o início e o fim de segmentos patrocinados. Assim que uma pessoa submete essa informação todos com a extenção poderam saltar automaticamete o patrocínio.",
|
||||
"description": "Descrição completa da extençao nas lojas dos browsers."
|
||||
},
|
||||
"website": {
|
||||
"message": "Site",
|
||||
"description": "Usado na pagina da loja do Firefox"
|
||||
},
|
||||
"sourceCode": {
|
||||
"message": "Código fonte",
|
||||
"description": "Usado na pagina da loja do Firefox"
|
||||
}
|
||||
}
|
||||
243
_locales/pt_pt/messages.json
Normal file
243
_locales/pt_pt/messages.json
Normal file
@@ -0,0 +1,243 @@
|
||||
{
|
||||
"Name": {
|
||||
"message": "SponsorBlock",
|
||||
"description": "Nome da extensão."
|
||||
},
|
||||
"fullName": {
|
||||
"message": "SponsorBlock para o YouTube - Salte patrocínios",
|
||||
"description": "Nome da extensão."
|
||||
},
|
||||
|
||||
"Description": {
|
||||
"message": "Salte patrocinadores em vídeos do YouTube. Reporte patrocinadores em vídeos que assista para poupar tempo a outros.",
|
||||
"description": "Descrição da extensão."
|
||||
},
|
||||
"helpPage": {
|
||||
"message": "index_en.html"
|
||||
},
|
||||
"400": {
|
||||
"message": "O servidor disse que este pedido foi inválido"
|
||||
},
|
||||
"429": {
|
||||
"message": "Enviou muitos segmentos para este vídeo, tem certeza que tem assim tantos?"
|
||||
},
|
||||
"409": {
|
||||
"message": "Isso já foi enviado antes"
|
||||
},
|
||||
"channelWhitelisted": {
|
||||
"message": "Canal adicionado à whitelist!"
|
||||
},
|
||||
"Sponsor": {
|
||||
"message": "patrocinador"
|
||||
},
|
||||
"Sponsors": {
|
||||
"message": "patrocinadores"
|
||||
},
|
||||
"Segment": {
|
||||
"message": "segmento de patrocínio"
|
||||
},
|
||||
"Segments": {
|
||||
"message": "segmentos de patrocínio"
|
||||
},
|
||||
"noticeTitle": {
|
||||
"message": "Patrocínio saltado"
|
||||
},
|
||||
"reportButtonTitle": {
|
||||
"message": "Reportar"
|
||||
},
|
||||
"reportButtonInfo": {
|
||||
"message": "Reportar subimissão como inválida."
|
||||
},
|
||||
"Dismiss": {
|
||||
"message": "Ignorar"
|
||||
},
|
||||
"Loading": {
|
||||
"message": "A carregar..."
|
||||
},
|
||||
"Mins": {
|
||||
"message": "Minutos"
|
||||
},
|
||||
"Secs": {
|
||||
"message": "Segundos"
|
||||
},
|
||||
"Hide": {
|
||||
"message": "Nunca mostrar"
|
||||
},
|
||||
"hitGoBack": {
|
||||
"message": "Carregue em reverter salto para voltar a onde estava"
|
||||
},
|
||||
"unskip": {
|
||||
"message": "Reverter salto"
|
||||
},
|
||||
"reskip": {
|
||||
"message": "Saltar novamente"
|
||||
},
|
||||
"paused": {
|
||||
"message": "Pausado"
|
||||
},
|
||||
"confirmMSG": {
|
||||
"message": "\n\nPara editar ou remover linhas individuais, carregue com o botão direito ou abra o popup da extensão pelo icone no canto superior direito."
|
||||
},
|
||||
"clearThis": {
|
||||
"message": "Tem certeza que deseja limpar isto?\n\n"
|
||||
},
|
||||
"Unknown": {
|
||||
"message": "Erro ao enviar os seus segmentos, tente novamente mais tarde."
|
||||
},
|
||||
"sponsorFound": {
|
||||
"message": "Os patrocinadores desse vídeo estão no banco de dados!"
|
||||
},
|
||||
"sponsor404": {
|
||||
"message": "Nenhum patrocinador encontrado"
|
||||
},
|
||||
"sponsorStart": {
|
||||
"message": "Patrocínio começa agora"
|
||||
},
|
||||
"sponsorEnd": {
|
||||
"message": "Patrocínio termina agora"
|
||||
},
|
||||
"noVideoID": {
|
||||
"message": "Isto provavelmente não é uma tab do YouTube, ou pode ter clicado muito cedo. \n Se sabe que é uma tab do YouTube,\n feche este popup e abra de novo."
|
||||
},
|
||||
"success": {
|
||||
"message": "Sucesso!"
|
||||
},
|
||||
"voted": {
|
||||
"message": "Votado!"
|
||||
},
|
||||
"voteFail": {
|
||||
"message": "Já votou antes."
|
||||
},
|
||||
"serverDown": {
|
||||
"message": "Parece que o servidor caiu. Contacte o desenvolvedor o quanto antes."
|
||||
},
|
||||
"connectionError": {
|
||||
"message": "Deu-se um erro de conecção: Código: "
|
||||
},
|
||||
"wantToSubmit": {
|
||||
"message": "Quer enviar os segmentos para o vídeo de ID"
|
||||
},
|
||||
"leftTimes": {
|
||||
"message": "Parece que se esqueceu de enviar alguns segmentos. Retorne à página para os enviar (não foram apagados)."
|
||||
},
|
||||
"clearTimes": {
|
||||
"message": "Apagar intervalos dos patrocínios"
|
||||
},
|
||||
"openPopup": {
|
||||
"message": "Abrir o Popup SponsorBlock"
|
||||
},
|
||||
"SubmitTimes": {
|
||||
"message": "Submeter intervalos dos patrocínios"
|
||||
},
|
||||
"submitCheck": {
|
||||
"message": "Tem a certeza que pretende submeter?"
|
||||
},
|
||||
"whitelistChannel": {
|
||||
"message": "Meter canal na Whitelist"
|
||||
},
|
||||
"removeFromWhitelist": {
|
||||
"message": "Remover canal da Whitelist"
|
||||
},
|
||||
"whitelistDescription": {
|
||||
"message": "Colocar na Whitelist canais com patrocínios éticos que encoragem boas atitude, ou simplesmente canais com patrocínios engraçados. Ou não, é consigo."
|
||||
},
|
||||
"voteOnTime": {
|
||||
"message": "Vote num intervalo de patrocínio"
|
||||
},
|
||||
"recordTimes": {
|
||||
"message": "Registe um intervalo de patrocínio"
|
||||
},
|
||||
"soFarUHSubmited": {
|
||||
"message": "Até agora submeteu"
|
||||
},
|
||||
"savedPeopleFrom": {
|
||||
"message": "Poupaste a outros de "
|
||||
},
|
||||
"viewLeaderboard": {
|
||||
"message": "Ver a leaderboard"
|
||||
},
|
||||
"here": {
|
||||
"message": "aqui"
|
||||
},
|
||||
"recordTimesDescription": {
|
||||
"message": "Carregue neste botão abaixo quando o patrocínio começar e quando\n acabar para registar e submetê-lo à base de dados"
|
||||
},
|
||||
"popupHint": {
|
||||
"message": "Dica: Carregue na tecla ; enquanto num vídeo para registar o começo/fim de um patrocínio e \" para submeter"
|
||||
},
|
||||
"lastTimes": {
|
||||
"message": "Intervalos de Patrocínios Escolhidos mais Recentemente"
|
||||
},
|
||||
"clearTimesButton": {
|
||||
"message": "Limpar Intervalos"
|
||||
},
|
||||
"submitTimesButton": {
|
||||
"message": "Submeter Intervalos"
|
||||
},
|
||||
"publicStats": {
|
||||
"message": "Isto é usado na página pública de estatísticas que mostra o quanto já contríbuíu. Veje-a"
|
||||
},
|
||||
"setUsername": {
|
||||
"message": "Criar nomde de utilizador"
|
||||
},
|
||||
"discordAdvert": {
|
||||
"message": "Junte-se ao discord oficial para sugerir dicas e sugestões!"
|
||||
},
|
||||
"hideThis": {
|
||||
"message": "Esconder isto"
|
||||
},
|
||||
"Options": {
|
||||
"message": "Opções"
|
||||
},
|
||||
"showButtons": {
|
||||
"message": "Mostrar botões no player do Youtube"
|
||||
},
|
||||
"hideButtons": {
|
||||
"message": "Esconder botões no player do Youtube"
|
||||
},
|
||||
"hideButtonsDescription": {
|
||||
"message": "Isto esconde os botões que aparecem no player do Youtube para submeter patrocínios. Entendemos que possa ser\n incómodo a algumas pessoas. Em vez de usar esses botões pode usar os do popup. Para esconder a mensagem que aparece, \n ususe o botão na mesma que diz \"Don't show this again\". Pode sempre reactivar estas definições novamente."
|
||||
},
|
||||
"showInfoButton": {
|
||||
"message": "Mostrar botão de Informações no player do Youtube"
|
||||
},
|
||||
"hideInfoButton": {
|
||||
"message": "Esconder botão de Informações no player do Youtube"
|
||||
},
|
||||
"whatInfoButton": {
|
||||
"message": "Este é o botão que abre o popup na pagina do Youtube."
|
||||
},
|
||||
"hideDeleteButton": {
|
||||
"message": "Esconder botão de Apagar no player do Youtube"
|
||||
},
|
||||
"showDeleteButton": {
|
||||
"message": "Mostrar botão de Apagar no player do Youtube"
|
||||
},
|
||||
"whatDeleteButton": {
|
||||
"message": "Este é o botão que lhe permite saltar todos os patrocínios do player do Youtube."
|
||||
},
|
||||
"disableViewTracking": {
|
||||
"message": "Desactivar registo de visualização de patrocínios"
|
||||
},
|
||||
"enableViewTracking": {
|
||||
"message": "Activar registo de visualização de patrocínios"
|
||||
},
|
||||
"whatViewTracking": {
|
||||
"message": "Esta funcionalidade regista que patrocínios tem saltado para que outros utilizadores saibam o quanto as suas submições têm ajudado outros\n e é usado como métrica de votos para evitar spam na base de dados. A extenção \n envia uma notificação ao servidor sempre que salta um patrocínio. Quanto menos pessoas desactivarem esta funcionalidade mais precisas serão as estimativas :)"
|
||||
},
|
||||
"showNotice": {
|
||||
"message": "Mostrar notificação outra vez"
|
||||
},
|
||||
"longDescription": {
|
||||
"message": "SponsorBlock é uma extensão que salta segmentos patrocinados em vídeos do YouTube. SponsorBlock é uma extenção crowdfunded que permite a qualquer um submeter o início e o fim de segmentos patrocinados. Assim que uma pessoa submete essa informação todos com a extenção poderam saltar automaticamete o patrocínio.",
|
||||
"description": "Descrição completa da extençao nas lojas dos browsers."
|
||||
},
|
||||
"website": {
|
||||
"message": "Site",
|
||||
"description": "Usado na pagina da loja do Firefox"
|
||||
},
|
||||
"sourceCode": {
|
||||
"message": "Código fonte",
|
||||
"description": "Usado na pagina da loja do Firefox"
|
||||
}
|
||||
}
|
||||
127
_locales/ru/messages.json
Normal file
127
_locales/ru/messages.json
Normal file
@@ -0,0 +1,127 @@
|
||||
{
|
||||
"Name": {
|
||||
"message": "SponsorBlock",
|
||||
"description": "Название расширения, не переводится."
|
||||
},
|
||||
"fullName": {
|
||||
"message": "SponsorBlock для YouTube - Пропускайте спонсорские вставки",
|
||||
"description": "Название расширения."
|
||||
},
|
||||
|
||||
"Description": {
|
||||
"message": "Пропускайте спонсорские вставки в видео на YouTube. Сообщайте о спонсорских вставках в видео, которые Вы смотрите, чтобы сэкономить время других пользователей.",
|
||||
"description": "Описание раширения."
|
||||
},
|
||||
"helpPage": {
|
||||
"message": "index_en.html"
|
||||
},
|
||||
"400": {
|
||||
"message": "Сервер отклонил этот запрос."
|
||||
},
|
||||
"429": {
|
||||
"message": "Вы отправили слишком много спонсоров для этого видео. Вы уверены, что их так много?"
|
||||
},
|
||||
"409": {
|
||||
"message": "Этот запрос был отправлен ранее."
|
||||
},
|
||||
"channelWhitelisted": {
|
||||
"message": "Канал добавлен в белый список!"
|
||||
},
|
||||
"Sponsor": {
|
||||
"message": "Спонсор"
|
||||
},
|
||||
"Sponsors": {
|
||||
"message": "Спонсоры"
|
||||
},
|
||||
"Segment": {
|
||||
"message": "спонсорская вставка"
|
||||
},
|
||||
"Segments": {
|
||||
"message": "спонсорские вставки"
|
||||
},
|
||||
"noticeTitle": {
|
||||
"message": "Спонсор пропущен"
|
||||
},
|
||||
"reportButtonTitle": {
|
||||
"message": "Ошибка"
|
||||
},
|
||||
"reportButtonInfo": {
|
||||
"message": "Сообщить, что информация об этом спонсорском сегменте ошибочна."
|
||||
},
|
||||
"Dismiss": {
|
||||
"message": "Закрыть"
|
||||
},
|
||||
"Loading": {
|
||||
"message": "Загрузка..."
|
||||
},
|
||||
"Mins": {
|
||||
"message": "мин"
|
||||
},
|
||||
"Secs": {
|
||||
"message": "сек"
|
||||
},
|
||||
"Hide": {
|
||||
"message": "Не показывать"
|
||||
},
|
||||
"hitGoBack": {
|
||||
"message": "Нажмите «Назад», чтобы вернуться обратно."
|
||||
},
|
||||
"unskip": {
|
||||
"message": "Назад"
|
||||
},
|
||||
"reskip": {
|
||||
"message": "Пропустить"
|
||||
},
|
||||
"paused": {
|
||||
"message": "Пауза"
|
||||
},
|
||||
"confirmMSG": {
|
||||
"message": "\n\nЧтобы изменить или удалить отдельные значения, нажмите кнопку «Информация» или откройте всплывающее окно расширения, щелкнув значок расширения в правом верхнем углу."
|
||||
},
|
||||
"clearThis": {
|
||||
"message": "Вы уверены, что хотите удалить эту информацию?\n\n"
|
||||
},
|
||||
"Unknown": {
|
||||
"message": "При отправке отчета о спонсорском сегменте произошла ошибка. Попытайтесь отправить его позже."
|
||||
},
|
||||
|
||||
"sponsorFound": {
|
||||
"message": "Спонсоры этого видео уже находятся в базе данных!"
|
||||
},
|
||||
"sponsor404": {
|
||||
"message": "Спонсорские вставки не найдены"
|
||||
},
|
||||
"sponsorStart": {
|
||||
"message": "Спонсорская вставка начинается сейчас"
|
||||
},
|
||||
"sponsorEnd": {
|
||||
"message": "Спонсорская вставка оканчивается сейчас"
|
||||
},
|
||||
"noVideoID": {
|
||||
"message": "Возможно, это не вкладка YouTube, или Вы нажали слишком рано. \n Если это вкладка YouTube,\n закройте это всплывающее окно и откройте его снова."
|
||||
},
|
||||
"success": {
|
||||
"message": "Успех!"
|
||||
},
|
||||
"voted": {
|
||||
"message": "Голос засчитан!"
|
||||
},
|
||||
"voteFail": {
|
||||
"message": "Вы уже проголосовали таким образом раньше."
|
||||
},
|
||||
"serverDown": {
|
||||
"message": "Кажется, сервер не работает. Свяжитесь с разработчиком."
|
||||
},
|
||||
"connectionError": {
|
||||
"message": "Ошибка соединения. Код ошибки: "
|
||||
},
|
||||
"wantToSubmit": {
|
||||
"message": "Вы точно хотите отправить отчёт о спонсорских вставках в видео с идентификатором"
|
||||
},
|
||||
"leftTimes": {
|
||||
"message": "Вы ещё не отправили отчёты о некоторых спонсорских вставках. Хотите вернуться на эту страницу, чтобы отправить их (они не удаляются)."
|
||||
},
|
||||
"submitCheck": {
|
||||
"message": "Вы уверены, что хотите отправить эту информацию?"
|
||||
}
|
||||
}
|
||||
319
background.js
319
background.js
@@ -1,96 +1,121 @@
|
||||
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
|
||||
isBackgroundScript = true;
|
||||
|
||||
// Used only on Firefox, which does not support non persistent background pages.
|
||||
var contentScriptRegistrations = {};
|
||||
|
||||
// Register content script if needed
|
||||
if (isFirefox()) {
|
||||
wait(() => SB.config !== undefined).then(function() {
|
||||
if (SB.config.supportInvidious) setupExtraSiteContentScripts();
|
||||
});
|
||||
}
|
||||
|
||||
chrome.tabs.onUpdated.addListener(function(tabId) {
|
||||
chrome.tabs.sendMessage(tabId, {
|
||||
message: 'update',
|
||||
});
|
||||
message: 'update',
|
||||
}, () => void chrome.runtime.lastError ); // Suppress error on Firefox
|
||||
});
|
||||
|
||||
chrome.runtime.onMessage.addListener(function (request, sender, callback) {
|
||||
switch(request.message) {
|
||||
case "submitTimes":
|
||||
submitTimes(request.videoID, callback);
|
||||
case "openConfig":
|
||||
chrome.runtime.openOptionsPage();
|
||||
return
|
||||
case "submitTimes":
|
||||
submitTimes(request.videoID, callback);
|
||||
|
||||
//this allows the callback to be called later by the submitTimes function
|
||||
return true;
|
||||
case "addSponsorTime":
|
||||
addSponsorTime(request.time, request.videoID, callback);
|
||||
//this allows the callback to be called later by the submitTimes function
|
||||
return true;
|
||||
case "addSponsorTime":
|
||||
addSponsorTime(request.time, request.videoID, callback);
|
||||
|
||||
//this allows the callback to be called later
|
||||
return true;
|
||||
case "getSponsorTimes":
|
||||
getSponsorTimes(request.videoID, function(sponsorTimes) {
|
||||
callback({
|
||||
sponsorTimes: sponsorTimes
|
||||
})
|
||||
});
|
||||
//this allows the callback to be called later
|
||||
return true;
|
||||
|
||||
//this allows the callback to be called later
|
||||
return true;
|
||||
case "submitVote":
|
||||
submitVote(request.type, request.UUID, callback);
|
||||
case "getSponsorTimes":
|
||||
getSponsorTimes(request.videoID, function(sponsorTimes) {
|
||||
callback({
|
||||
sponsorTimes: sponsorTimes
|
||||
})
|
||||
});
|
||||
|
||||
//this allows the callback to be called later
|
||||
return true;
|
||||
case "alertPrevious":
|
||||
chrome.notifications.create("stillThere" + Math.random(), {
|
||||
type: "basic",
|
||||
title: "Do you want to submit the sponsor times for video id " + request.previousVideoID + "?",
|
||||
message: "You seem to have left some sponsor times unsubmitted. Go back to that page to submit them (they are not deleted).",
|
||||
iconUrl: "./icons/LogoSponsorBlocker256px.png"
|
||||
});
|
||||
//this allows the callback to be called later
|
||||
return true;
|
||||
case "submitVote":
|
||||
submitVote(request.type, request.UUID, callback);
|
||||
|
||||
//this allows the callback to be called later
|
||||
return true;
|
||||
case "alertPrevious":
|
||||
chrome.notifications.create("stillThere" + Math.random(), {
|
||||
type: "basic",
|
||||
title: chrome.i18n.getMessage("wantToSubmit") + " " + request.previousVideoID + "?",
|
||||
message: chrome.i18n.getMessage("leftTimes"),
|
||||
iconUrl: "./icons/LogoSponsorBlocker256px.png"
|
||||
});
|
||||
case "registerContentScript":
|
||||
registerFirefoxContentScript(request);
|
||||
return false;
|
||||
case "unregisterContentScript":
|
||||
contentScriptRegistrations[request.id].unregister();
|
||||
delete contentScriptRegistrations[request.id];
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
//add help page on install
|
||||
chrome.runtime.onInstalled.addListener(function (object) {
|
||||
// TODO (shownInstallPage): remove shownInstallPage logic after sufficient amount of time,
|
||||
// so that people have time to upgrade and move to shownInstallPage-free code.
|
||||
chrome.storage.sync.get(["userID", "shownInstallPage"], function(result) {
|
||||
const userID = result.userID;
|
||||
// TODO (shownInstallPage): delete row below
|
||||
const shownInstallPage = result.shownInstallPage;
|
||||
// This let's the config sync to run fully before checking.
|
||||
// This is required on Firefox
|
||||
setTimeout(function() {
|
||||
const userID = SB.config.userID;
|
||||
|
||||
// If there is no userID, then it is the first install.
|
||||
if (!userID){
|
||||
// Show install page, if there is no user id
|
||||
// and there is no shownInstallPage.
|
||||
// TODO (shownInstallPage): remove this if statement, but leave contents
|
||||
if (!shownInstallPage){
|
||||
//open up the install page
|
||||
|
||||
chrome.tabs.create({url: chrome.extension.getURL("/help/"+chrome.i18n.getMessage("helpPage"))});
|
||||
}
|
||||
|
||||
// TODO (shownInstallPage): delete if statement and contents
|
||||
// If shownInstallPage is set, remove it.
|
||||
if (!!shownInstallPage){
|
||||
chrome.storage.sync.remove("shownInstallPage");
|
||||
}
|
||||
//open up the install page
|
||||
chrome.tabs.create({url: chrome.extension.getURL("/help/index_en.html")});
|
||||
|
||||
//generate a userID
|
||||
const newUserID = generateUUID();
|
||||
const newUserID = generateUserID();
|
||||
//save this UUID
|
||||
chrome.storage.sync.set({
|
||||
"userID": newUserID,
|
||||
//the last video id loaded, to make sure it is a video id change
|
||||
"sponsorVideoID": null,
|
||||
"previousVideoID": null
|
||||
});
|
||||
SB.config.userID = newUserID;
|
||||
|
||||
//TODO: Remove when invidious support is old
|
||||
// Don't show this to new users
|
||||
SB.config.invidiousUpdateInfoShowCount = 6;
|
||||
}
|
||||
});
|
||||
}, 1500);
|
||||
});
|
||||
|
||||
/**
|
||||
* Only works on Firefox.
|
||||
* Firefox requires that it be applied after every extension restart.
|
||||
*
|
||||
* @param {JSON} options
|
||||
*/
|
||||
function registerFirefoxContentScript(options) {
|
||||
let oldRegistration = contentScriptRegistrations[options.id];
|
||||
if (oldRegistration) oldRegistration.unregister();
|
||||
|
||||
browser.contentScripts.register({
|
||||
allFrames: options.allFrames,
|
||||
js: options.js,
|
||||
css: options.css,
|
||||
matches: options.matches
|
||||
}).then((registration) => void (contentScriptRegistrations[options.id] = registration));
|
||||
}
|
||||
|
||||
//gets the sponsor times from memory
|
||||
function getSponsorTimes(videoID, callback) {
|
||||
let sponsorTimes = [];
|
||||
let sponsorTimeKey = "sponsorTimes" + videoID;
|
||||
chrome.storage.sync.get([sponsorTimeKey], function(result) {
|
||||
let sponsorTimesStorage = result[sponsorTimeKey];
|
||||
if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
|
||||
sponsorTimes = sponsorTimesStorage;
|
||||
}
|
||||
|
||||
callback(sponsorTimes)
|
||||
});
|
||||
let sponsorTimesStorage = SB.config.sponsorTimes.get(videoID);
|
||||
|
||||
if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
|
||||
sponsorTimes = sponsorTimesStorage;
|
||||
}
|
||||
|
||||
callback(sponsorTimes);
|
||||
}
|
||||
|
||||
function addSponsorTime(time, videoID, callback) {
|
||||
@@ -108,78 +133,97 @@ function addSponsorTime(time, videoID, callback) {
|
||||
}
|
||||
|
||||
//save this info
|
||||
let sponsorTimeKey = "sponsorTimes" + videoID;
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes}, callback);
|
||||
SB.config.sponsorTimes.set(videoID, sponsorTimes);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
function submitVote(type, UUID, callback) {
|
||||
chrome.storage.sync.get(["userID"], function(result) {
|
||||
let userID = result.userID;
|
||||
let userID = SB.config.userID;
|
||||
|
||||
//publish this vote
|
||||
sendRequestToServer("GET", "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + "&type=" + type, function(xmlhttp, error) {
|
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||
callback({
|
||||
successType: 1
|
||||
});
|
||||
} else if (xmlhttp.readyState == 4 && xmlhttp.status == 405) {
|
||||
//duplicate vote
|
||||
callback({
|
||||
successType: 0,
|
||||
statusCode: xmlhttp.status
|
||||
});
|
||||
} else if (error) {
|
||||
//error while connect
|
||||
callback({
|
||||
successType: -1,
|
||||
statusCode: xmlhttp.status
|
||||
});
|
||||
}
|
||||
})
|
||||
})
|
||||
if (userID == undefined || userID === "undefined") {
|
||||
//generate one
|
||||
userID = generateUserID();
|
||||
SB.config.userID = userID;
|
||||
}
|
||||
|
||||
//publish this vote
|
||||
sendRequestToServer("POST", "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + "&type=" + type, function(xmlhttp, error) {
|
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||
callback({
|
||||
successType: 1
|
||||
});
|
||||
} else if (xmlhttp.readyState == 4 && xmlhttp.status == 405) {
|
||||
//duplicate vote
|
||||
callback({
|
||||
successType: 0,
|
||||
statusCode: xmlhttp.status
|
||||
});
|
||||
} else if (error) {
|
||||
//error while connect
|
||||
callback({
|
||||
successType: -1,
|
||||
statusCode: xmlhttp.status
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function submitTimes(videoID, callback) {
|
||||
async function submitTimes(videoID, callback) {
|
||||
//get the video times from storage
|
||||
let sponsorTimeKey = 'sponsorTimes' + videoID;
|
||||
chrome.storage.sync.get([sponsorTimeKey, "userID"], function(result) {
|
||||
let sponsorTimes = result[sponsorTimeKey];
|
||||
let userID = result.userID;
|
||||
let sponsorTimes = SB.config.sponsorTimes.get(videoID);
|
||||
let userID = SB.config.userID;
|
||||
|
||||
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
|
||||
let durationResult = await new Promise((resolve, reject) => {
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "getVideoDuration"
|
||||
}, (response) => resolve(response));
|
||||
});
|
||||
});
|
||||
|
||||
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
|
||||
//submit these times
|
||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||
//submit the sponsorTime
|
||||
sendRequestToServer("GET", "/api/postVideoSponsorTimes?videoID=" + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1]
|
||||
+ "&userID=" + userID, function(xmlhttp, error) {
|
||||
if (xmlhttp.readyState == 4 && !error) {
|
||||
callback({
|
||||
statusCode: xmlhttp.status
|
||||
});
|
||||
|
||||
if (xmlhttp.status == 200) {
|
||||
//add these to the storage log
|
||||
chrome.storage.sync.get(["sponsorTimesContributed"], function(result) {
|
||||
let currentContributionAmount = 0;
|
||||
if (result.sponsorTimesContributed != undefined) {
|
||||
//current contribution amount is known
|
||||
currentContributionAmount = result.sponsorTimesContributed;
|
||||
}
|
||||
|
||||
//save the amount contributed
|
||||
chrome.storage.sync.set({"sponsorTimesContributed": currentContributionAmount + sponsorTimes.length});
|
||||
});
|
||||
}
|
||||
} else if (error) {
|
||||
callback({
|
||||
statusCode: -1
|
||||
});
|
||||
}
|
||||
});
|
||||
//check if a sponsor exceeds the duration of the video
|
||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||
if (sponsorTimes[i][1] > durationResult.duration) {
|
||||
sponsorTimes[i][1] = durationResult.duration;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//submit these times
|
||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||
//to prevent it from happeneing twice
|
||||
let increasedContributionAmount = false;
|
||||
|
||||
//submit the sponsorTime
|
||||
sendRequestToServer("GET", "/api/postVideoSponsorTimes?videoID=" + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1]
|
||||
+ "&userID=" + userID, function(xmlhttp, error) {
|
||||
if (xmlhttp.readyState == 4 && !error) {
|
||||
callback({
|
||||
statusCode: xmlhttp.status
|
||||
});
|
||||
|
||||
if (xmlhttp.status == 200) {
|
||||
//add these to the storage log
|
||||
currentContributionAmount = SB.config.sponsorTimesContributed;
|
||||
//save the amount contributed
|
||||
if (!increasedContributionAmount) {
|
||||
increasedContributionAmount = true;
|
||||
SB.config.sponsorTimesContributed = currentContributionAmount + sponsorTimes.length;
|
||||
}
|
||||
}
|
||||
} else if (error) {
|
||||
callback({
|
||||
statusCode: -1
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sendRequestToServer(type, address, callback) {
|
||||
@@ -200,22 +244,3 @@ function sendRequestToServer(type, address, callback) {
|
||||
//submit this request
|
||||
xmlhttp.send();
|
||||
}
|
||||
|
||||
function generateUUID(length = 36) {
|
||||
let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
let result = "";
|
||||
let isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
|
||||
if (window.crypto && window.crypto.getRandomValues) {
|
||||
values = new Uint32Array(length);
|
||||
window.crypto.getRandomValues(values);
|
||||
for (i = 0; i < length; i++) {
|
||||
result += charset[values[i] % charset.length];
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
for (let i = 0; i < length; i++) {
|
||||
result += charset[Math.floor(Math.random() * charset.length)];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
}
|
||||
|
||||
.sponsorSkipNotice {
|
||||
min-width: 280px;
|
||||
min-width: 350px;
|
||||
background-color: rgba(28, 28, 28, 0.9);
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
|
||||
874
content.js
874
content.js
File diff suppressed because it is too large
Load Diff
10
crowdin.yml
Normal file
10
crowdin.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
files:
|
||||
- source: /_locales/en/*
|
||||
translation: /_locales/%two_letters_code%/%original_file_name%
|
||||
languages_mapping:
|
||||
two_letters_code:
|
||||
pl-PL: "pl_PL"
|
||||
pr-BR: "pt_BR"
|
||||
pr-PT: "pt_PT"
|
||||
zh-CN: "zh_CH"
|
||||
zh-TW: "zh_TW"
|
||||
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"id": "sponsorBlocker@ajay.app",
|
||||
"strict_min_version": "57.0"
|
||||
"id": "sponsorBlocker@ajay.app"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<title> SponsorBlock </title>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<link href="styles.css" rel="stylesheet"/>
|
||||
</head>
|
||||
@@ -11,9 +14,9 @@
|
||||
SponsorBlock
|
||||
</div>
|
||||
|
||||
<center>
|
||||
<div class="container">
|
||||
|
||||
<p class="createdBy">Created By <a href="https://ajay.app">Ajay Ramachandran</a></p>
|
||||
<p class="createdBy">Created By <a href="https://ajay.app">Ajay Ramachandran</a> <img src="https://ajay.app/newprofilepic.jpg" height="30" class="profilepiccircle"/></p>
|
||||
|
||||
<p>
|
||||
Thanks for installing SponsorBlock. Here are some quick tips for getting started. Please join the Discord if you have any questions or suggestions.
|
||||
@@ -27,6 +30,12 @@
|
||||
Come contribute, make some suggestions and help out in the Discord: <a href="https://discord.gg/QnmVMpU">https://discord.gg/QnmVMpU</a>
|
||||
</p>
|
||||
|
||||
<a class="bigText" href="/options/options.html">Enable Invidious Support</a>
|
||||
|
||||
<p>
|
||||
Invidious is a third-party YouTube viewer. SponsorBlock now supports invidious along with YouTube. Please visit the options page to make sure everything is how you want it to be.
|
||||
</p>
|
||||
|
||||
<h1>How skipping works</h1>
|
||||
|
||||
<p class="projectPreview">
|
||||
@@ -39,10 +48,10 @@
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
Whenever you skip a video, you will get a notice report that submission. If the timing seems wrong, report it! You can also vote in the popup. The extension auto upvotes it if you don't report it, so make sure to report when necessary.
|
||||
Whenever you skip a video, you will get a notice report that submission. If the timing seems wrong, report it! You can also vote in the popup. The extension auto upvotes it if you don't report it, so make sure to report when necessary (this can be disabled in the options).
|
||||
</p>
|
||||
|
||||
<center><img height="120px" src="https://user-images.githubusercontent.com/12688112/63067735-5a638700-bede-11e9-8147-f321b57527ec.gif"></center>
|
||||
<div class="center"><img height="120px" src="https://user-images.githubusercontent.com/12688112/63067735-5a638700-bede-11e9-8147-f321b57527ec.gif"></div>
|
||||
|
||||
<h1>Submitting</h1>
|
||||
|
||||
@@ -100,7 +109,7 @@
|
||||
Ask on Discord or make an Issue on GitHub. I am happy to hear suggestions or improvements you want. You may also contribute code or graphics if you would like.
|
||||
</p>
|
||||
|
||||
<h1>Where can I get the source code</h1>
|
||||
<h1>Where can I get the source code?</h1>
|
||||
|
||||
<h4 style="display: inline">Client:</h4>
|
||||
<!-- Github logo -->
|
||||
@@ -110,7 +119,7 @@
|
||||
<!-- Github logo -->
|
||||
<a href="https://github.com/ajayyy/SponsorBlockServer"><svg aria-hidden="true" version="1.1" viewBox="0 0 16 16" height="58px" style="padding-left: 15px"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg></a>
|
||||
|
||||
<h1>Credit</h1>
|
||||
<h1>Credits</h1>
|
||||
|
||||
<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>
|
||||
|
||||
@@ -118,6 +127,6 @@
|
||||
|
||||
<p>Some icons made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></p>
|
||||
|
||||
</center>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
:not(.hljs-keyword):not(.hljs-comment):not(.hljs-number):not(.hljs-string):not(pre):not(code) {
|
||||
.bigText {
|
||||
font-size: 50px;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #333333;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 60%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.projectPreview {
|
||||
@@ -8,24 +22,24 @@
|
||||
|
||||
.projectPreviewImage {
|
||||
position: absolute;
|
||||
left: -90;
|
||||
width: 80;
|
||||
left: -90px;
|
||||
width: 80px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.projectPreviewImageLarge {
|
||||
position: absolute;
|
||||
left: -210;
|
||||
width: 200;
|
||||
left: -210px;
|
||||
width: 200px;
|
||||
top: 50%;
|
||||
transform: translateY(-20%);
|
||||
}
|
||||
|
||||
.projectPreviewImageLargeRight {
|
||||
position: absolute;
|
||||
right: -210;
|
||||
width: 200;
|
||||
right: -210px;
|
||||
width: 200px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
@@ -43,37 +57,27 @@
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
|
||||
font-family: sans-serif;
|
||||
font-size: 50;
|
||||
font-size: 50px;
|
||||
color: #212121;
|
||||
|
||||
/* height: 100; */
|
||||
|
||||
padding: 20;
|
||||
padding: 20px;
|
||||
|
||||
text-decoration: none;
|
||||
|
||||
transition: font-size 1s;
|
||||
}
|
||||
|
||||
#title:hover {
|
||||
font-size: 60;
|
||||
|
||||
transition: font-size 1s;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-family: sans-serif;
|
||||
font-size: 40;
|
||||
font-size: 40px;
|
||||
color: #dad8d8;
|
||||
|
||||
padding-top: 10;
|
||||
padding-top: 10px;
|
||||
|
||||
transition: font-size 0.4s;
|
||||
}
|
||||
|
||||
.subtitle:hover {
|
||||
font-size: 45;
|
||||
font-size: 45px;
|
||||
|
||||
transition: font-size 0.4s;
|
||||
}
|
||||
@@ -83,13 +87,19 @@
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.profilepiccircle {
|
||||
vertical-align: middle;
|
||||
overflow: hidden;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.link {
|
||||
padding: 20;
|
||||
padding: 20px;
|
||||
|
||||
height: 80px;
|
||||
|
||||
@@ -103,29 +113,24 @@ a {
|
||||
}
|
||||
|
||||
#contact,.smalllink {
|
||||
font-family: sans-serif;
|
||||
font-size: 25;
|
||||
font-size: 25px;
|
||||
color: #e8e8e8;
|
||||
|
||||
text-align: center;
|
||||
|
||||
padding: 10;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#contact {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
p,li {
|
||||
font-family: sans-serif;
|
||||
font-size: 20;
|
||||
p,li,a {
|
||||
font-size: 20px;
|
||||
color: #c4c4c4;
|
||||
|
||||
padding: 10;
|
||||
}
|
||||
|
||||
p,li,code,a {
|
||||
max-width: 60%;
|
||||
text-align: left;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
@@ -137,7 +142,7 @@ p,li,code,a {
|
||||
|
||||
.projectPreviewImage {
|
||||
position: unset;
|
||||
width: 130;
|
||||
width: 130px;
|
||||
display: block;
|
||||
margin: auto;
|
||||
transform: none;
|
||||
@@ -155,20 +160,18 @@ img {
|
||||
}
|
||||
|
||||
#recentPostTitle {
|
||||
font-family: sans-serif;
|
||||
font-size: 30;
|
||||
font-size: 30px;
|
||||
color: #dad8d8;
|
||||
}
|
||||
|
||||
#recentPostDate {
|
||||
font-family: sans-serif;
|
||||
font-size: 15;
|
||||
font-size: 15px;
|
||||
color: #dad8d8;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6 {
|
||||
font-family: sans-serif;
|
||||
color: #dad8d8;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
svg {
|
||||
|
||||
BIN
icons/newprofilepic.jpg
Normal file
BIN
icons/newprofilepic.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
@@ -1,17 +1,20 @@
|
||||
{
|
||||
"name": "__MSG_fullName__",
|
||||
"short_name": "__MSG_Name__",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.5",
|
||||
"default_locale": "en",
|
||||
"description": "__MSG_Description__",
|
||||
"content_scripts": [
|
||||
{
|
||||
"run_at": "document_start",
|
||||
"matches": [
|
||||
"https://*.youtube.com/*"
|
||||
"https://*.youtube.com/*",
|
||||
"https://www.youtube-nocookie.com/embed/*"
|
||||
],
|
||||
"all_frames": true,
|
||||
"js": [
|
||||
"config.js",
|
||||
"SB.js",
|
||||
"utils/previewBar.js",
|
||||
"utils/skipNotice.js",
|
||||
"utils.js",
|
||||
@@ -45,14 +48,19 @@
|
||||
"notifications",
|
||||
"https://sponsor.ajay.app/*"
|
||||
],
|
||||
"optional_permissions": [
|
||||
"*://*/*",
|
||||
"declarativeContent"
|
||||
],
|
||||
"browser_action": {
|
||||
"default_title": "__MSG_Name__",
|
||||
"default_popup": "popup.html"
|
||||
},
|
||||
"background": {
|
||||
"scripts":[
|
||||
"utils.js",
|
||||
"config.js",
|
||||
"SB.js",
|
||||
"utils.js",
|
||||
"background.js"
|
||||
],
|
||||
"persistent": false
|
||||
@@ -64,5 +72,9 @@
|
||||
"128": "icons/LogoSponsorBlocker128px.png",
|
||||
"256": "icons/LogoSponsorBlocker256px.png"
|
||||
},
|
||||
"options_ui": {
|
||||
"page": "options/options.html",
|
||||
"open_in_tab": true
|
||||
},
|
||||
"manifest_version": 2
|
||||
}
|
||||
|
||||
312
options/options.css
Normal file
312
options/options.css
Normal file
@@ -0,0 +1,312 @@
|
||||
/* Options page CSS */
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.inline {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.keybind-status {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.small-description {
|
||||
color: white;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.medium-description {
|
||||
color: white;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.option-text-box {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.option-button {
|
||||
cursor: pointer;
|
||||
|
||||
background-color: #c00000;
|
||||
padding: 10px;
|
||||
color: white;
|
||||
border-radius: 5px;
|
||||
font-size: 14px;
|
||||
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.option-button:hover {
|
||||
background-color: #fc0303;
|
||||
}
|
||||
|
||||
.option-button.disabled {
|
||||
cursor: default;
|
||||
|
||||
background-color: #520000;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
#options {
|
||||
max-width: 60%;
|
||||
text-align: left;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch-container:after {
|
||||
content: attr(label-name);
|
||||
position: absolute;
|
||||
padding: 4px;
|
||||
width: max-content;
|
||||
|
||||
font-size: 14px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 40px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #707070;
|
||||
}
|
||||
|
||||
.animated * {
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
left: 4px;
|
||||
bottom: 4px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.animated .slider:before {
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
input:checked + .slider {
|
||||
background-color: #fc0303;
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
-webkit-transform: translateX(16px);
|
||||
-ms-transform: translateX(16px);
|
||||
transform: translateX(16px);
|
||||
}
|
||||
|
||||
/* Rounded sliders */
|
||||
.slider.round {
|
||||
border-radius: 34px;
|
||||
}
|
||||
|
||||
.slider.round:before {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
|
||||
/* Boilerplate CSS from https://ajay.app */
|
||||
|
||||
body {
|
||||
background-color: #333333;
|
||||
}
|
||||
|
||||
.projectPreview {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.projectPreviewImage {
|
||||
position: absolute;
|
||||
left: -90px;
|
||||
width: 80px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.projectPreviewImageLarge {
|
||||
position: absolute;
|
||||
left: -210px;
|
||||
width: 200px;
|
||||
top: 50%;
|
||||
transform: translateY(-20%);
|
||||
}
|
||||
|
||||
.projectPreviewImageLargeRight {
|
||||
position: absolute;
|
||||
right: -210px;
|
||||
width: 200px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.createdBy {
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#title {
|
||||
background-color: #636363;
|
||||
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
|
||||
font-size: 50px;
|
||||
color: #212121;
|
||||
|
||||
padding: 20px;
|
||||
|
||||
text-decoration: none;
|
||||
|
||||
transition: font-size 1s;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 40px;
|
||||
color: #dad8d8;
|
||||
|
||||
padding-top: 10px;
|
||||
|
||||
transition: font-size 0.4s;
|
||||
}
|
||||
|
||||
.subtitle:hover {
|
||||
font-size: 45px;
|
||||
|
||||
transition: font-size 0.4s;
|
||||
}
|
||||
|
||||
.profilepic {
|
||||
background-color: #636363 !important;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.profilepiccircle {
|
||||
vertical-align: middle;
|
||||
overflow: hidden;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.link {
|
||||
padding: 20px;
|
||||
|
||||
height: 80px;
|
||||
|
||||
transition: height 0.2s;
|
||||
}
|
||||
|
||||
.link:hover {
|
||||
height: 95px;
|
||||
|
||||
transition: height 0.2s;
|
||||
}
|
||||
|
||||
#contact,.smalllink {
|
||||
font-size: 25px;
|
||||
color: #e8e8e8;
|
||||
|
||||
text-align: center;
|
||||
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#contact {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
p,li {
|
||||
font-size: 20px;
|
||||
color: #c4c4c4;
|
||||
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
p,li,code,a {
|
||||
max-width: 60%;
|
||||
text-align: left;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
@media screen and (orientation:portrait) {
|
||||
p,li,code,a {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.projectPreviewImage {
|
||||
position: unset;
|
||||
width: 130px;
|
||||
display: block;
|
||||
margin: auto;
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
.previewImage {
|
||||
max-height: 200px;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#recentPostTitle {
|
||||
font-size: 30px;
|
||||
color: #dad8d8;
|
||||
}
|
||||
|
||||
#recentPostDate {
|
||||
font-size: 15px;
|
||||
color: #dad8d8;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6 {
|
||||
color: #dad8d8;
|
||||
}
|
||||
|
||||
svg {
|
||||
text-decoration: none;
|
||||
}
|
||||
263
options/options.html
Normal file
263
options/options.html
Normal file
@@ -0,0 +1,263 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<title>Options - SponsorBlock</title>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<link href="options.css" rel="stylesheet"/>
|
||||
|
||||
<script src="../utils.js"></script>
|
||||
<script src="../SB.js"></script>
|
||||
<script src="options.js"></script>
|
||||
</head>
|
||||
|
||||
<body class="sponsorBlockPageBody">
|
||||
|
||||
<div id="title">
|
||||
<img src="../icons/LogoSponsorBlocker256px.png" height="80" class="profilepic"/>
|
||||
SponsorBlock
|
||||
</div>
|
||||
|
||||
<div class="center">
|
||||
<p class="createdBy">__MSG_createdBy__ <a href="https://ajay.app">Ajay Ramachandran</a> <img src="../icons/newprofilepic.jpg" height="30" class="profilepiccircle"/></p>
|
||||
|
||||
<h1>__MSG_Options__</h1>
|
||||
|
||||
<div id="options" class="hidden">
|
||||
|
||||
<div id="support-invidious" option-type="toggle" sync-option="supportInvidious">
|
||||
<label class="switch-container" label-name="__MSG_supportInvidious__">
|
||||
<label class="switch">
|
||||
<input type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</label>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div class="small-description">__MSG_supportInvidiousDescription__</div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div option-type="text-change" sync-option="invidiousInstances">
|
||||
<div class="option-button trigger-button">
|
||||
__MSG_addInvidiousInstance__
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
|
||||
<div class="small-description">__MSG_addInvidiousInstanceDescription__</div>
|
||||
|
||||
<div class="option-hidden-section hidden">
|
||||
<br/>
|
||||
|
||||
<input class="option-text-box" type="text">
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div class="option-button text-change-set inline">
|
||||
__MSG_add__
|
||||
</div>
|
||||
|
||||
<div class="option-button invidious-instance-reset inline">
|
||||
__MSG_resetInvidiousInstance__
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<span class="small-description">__MSG_currentInstances__</span>
|
||||
<span class="small-description" option-type="display" sync-option="invidiousInstances"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div option-type="toggle" toggle-type="reverse" sync-option="disableAutoSkip">
|
||||
<label class="switch-container" label-name="__MSG_autoSkip__">
|
||||
<label class="switch">
|
||||
<input type="checkbox" checked>
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</label>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div class="small-description">__MSG_autoSkipDescription__</div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div option-type="keybind-change" sync-option="startSponsorKeybind">
|
||||
<div class="option-button trigger-button">
|
||||
__MSG_setStartSponsorShortcut__
|
||||
</div>
|
||||
|
||||
<div class="option-hidden-section hidden">
|
||||
<br/>
|
||||
|
||||
<div class="medium-description keybind-status">
|
||||
__MSG_keybindDescription__
|
||||
</div>
|
||||
|
||||
<span class="medium-description bold keybind-status-key">
|
||||
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div option-type="keybind-change" sync-option="submitKeybind">
|
||||
<div class="option-button trigger-button">
|
||||
__MSG_setSubmitKeybind__
|
||||
</div>
|
||||
|
||||
<div class="option-hidden-section hidden">
|
||||
<br/>
|
||||
|
||||
<div class="medium-description keybind-status">
|
||||
__MSG_keybindDescription__
|
||||
</div>
|
||||
|
||||
<span class="medium-description bold keybind-status-key">
|
||||
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div option-type="toggle" toggle-type="reverse" sync-option="hideVideoPlayerControls">
|
||||
<label class="switch-container" label-name="__MSG_showButtons__">
|
||||
<label class="switch">
|
||||
<input type="checkbox" checked>
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</label>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div class="small-description">__MSG_hideButtonsDescription__</div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div option-type="toggle" toggle-type="reverse" sync-option="hideInfoButtonPlayerControls">
|
||||
<label class="switch-container" label-name="__MSG_showInfoButton__">
|
||||
<label class="switch">
|
||||
<input type="checkbox" checked>
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</label>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div class="small-description">__MSG_whatInfoButton__</div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div option-type="toggle" toggle-type="reverse" sync-option="hideDeleteButtonPlayerControls">
|
||||
<label class="switch-container" label-name="__MSG_showDeleteButton__">
|
||||
<label class="switch">
|
||||
<input type="checkbox" checked>
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</label>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div class="small-description">__MSG_whatDeleteButton__</div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div option-type="toggle" sync-option="autoUpvote">
|
||||
<label class="switch-container" label-name="__MSG_enableAutoUpvote__">
|
||||
<label class="switch">
|
||||
<input type="checkbox" checked>
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</label>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div class="small-description">__MSG_whatAutoUpvote__</div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div option-type="toggle" sync-option="trackViewCount">
|
||||
<label class="switch-container" label-name="__MSG_enableViewTracking__">
|
||||
<label class="switch">
|
||||
<input type="checkbox" checked>
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</label>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div class="small-description">__MSG_whatViewTracking__</div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div option-type="text-change" sync-option="userID" confirm-message="userIDChangeWarning">
|
||||
<div class="option-button trigger-button">
|
||||
__MSG_changeUserID__
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
|
||||
<div class="small-description">__MSG_whatChangeUserID__</div>
|
||||
|
||||
<div class="option-hidden-section hidden">
|
||||
<br/>
|
||||
|
||||
<input class="option-text-box" type="text">
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div class="option-button text-change-set">
|
||||
__MSG_setUserID__
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div option-type="toggle" toggle-type="reverse" sync-option="dontShowNotice">
|
||||
<label class="switch-container" label-name="__MSG_showSkipNotice__">
|
||||
<label class="switch">
|
||||
<input type="checkbox" checked>
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
292
options/options.js
Normal file
292
options/options.js
Normal file
@@ -0,0 +1,292 @@
|
||||
window.addEventListener('DOMContentLoaded', init);
|
||||
|
||||
async function init() {
|
||||
localizeHtmlPage();
|
||||
|
||||
if (!SB.configListeners.includes(optionsConfigUpdateListener)) {
|
||||
SB.configListeners.push(optionsConfigUpdateListener);
|
||||
}
|
||||
|
||||
await wait(() => SB.config !== undefined);
|
||||
|
||||
// Set all of the toggle options to the correct option
|
||||
let optionsContainer = document.getElementById("options");
|
||||
let optionsElements = optionsContainer.querySelectorAll("*");
|
||||
|
||||
for (let i = 0; i < optionsElements.length; i++) {
|
||||
switch (optionsElements[i].getAttribute("option-type")) {
|
||||
case "toggle":
|
||||
let option = optionsElements[i].getAttribute("sync-option");
|
||||
let optionResult = SB.config[option];
|
||||
|
||||
let checkbox = optionsElements[i].querySelector("input");
|
||||
let reverse = optionsElements[i].getAttribute("toggle-type") === "reverse";
|
||||
|
||||
if (optionResult != undefined) {
|
||||
checkbox.checked = optionResult;
|
||||
|
||||
if (reverse) {
|
||||
optionsElements[i].querySelector("input").checked = !optionResult;
|
||||
}
|
||||
}
|
||||
|
||||
// See if anything extra should be run first time
|
||||
switch (option) {
|
||||
case "supportInvidious":
|
||||
invidiousInit(checkbox, option);
|
||||
break;
|
||||
}
|
||||
|
||||
// Add click listener
|
||||
checkbox.addEventListener("click", () => {
|
||||
SB.config[option] = reverse ? !checkbox.checked : checkbox.checked;
|
||||
|
||||
// See if anything extra must be run
|
||||
switch (option) {
|
||||
case "supportInvidious":
|
||||
invidiousOnClick(checkbox, option);
|
||||
break;
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "text-change":
|
||||
let button = optionsElements[i].querySelector(".trigger-button");
|
||||
button.addEventListener("click", () => activateTextChange(optionsElements[i]));
|
||||
|
||||
let textChangeOption = optionsElements[i].getAttribute("sync-option");
|
||||
// See if anything extra must be done
|
||||
switch (textChangeOption) {
|
||||
case "invidiousInstances":
|
||||
invidiousInstanceAddInit(optionsElements[i], textChangeOption);
|
||||
}
|
||||
|
||||
break;
|
||||
case "keybind-change":
|
||||
let keybindButton = optionsElements[i].querySelector(".trigger-button");
|
||||
keybindButton.addEventListener("click", () => activateKeybindChange(optionsElements[i]));
|
||||
|
||||
break;
|
||||
case "display":
|
||||
updateDisplayElement(optionsElements[i])
|
||||
}
|
||||
}
|
||||
|
||||
optionsContainer.classList.remove("hidden");
|
||||
optionsContainer.classList.add("animated");
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the config is updated
|
||||
*
|
||||
* @param {String} element
|
||||
*/
|
||||
function optionsConfigUpdateListener(changes) {
|
||||
let optionsContainer = document.getElementById("options");
|
||||
let optionsElements = optionsContainer.querySelectorAll("*");
|
||||
|
||||
for (let i = 0; i < optionsElements.length; i++) {
|
||||
switch (optionsElements[i].getAttribute("option-type")) {
|
||||
case "display":
|
||||
updateDisplayElement(optionsElements[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Will set display elements to the proper text
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
*/
|
||||
function updateDisplayElement(element) {
|
||||
let displayOption = element.getAttribute("sync-option")
|
||||
let displayText = SB.config[displayOption];
|
||||
element.innerText = displayText;
|
||||
|
||||
// See if anything extra must be run
|
||||
switch (displayOption) {
|
||||
case "invidiousInstances":
|
||||
element.innerText = displayText.join(', ');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the option to add Invidious instances
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @param {String} option
|
||||
*/
|
||||
function invidiousInstanceAddInit(element, option) {
|
||||
let textBox = element.querySelector(".option-text-box");
|
||||
let button = element.querySelector(".trigger-button");
|
||||
|
||||
let setButton = element.querySelector(".text-change-set");
|
||||
setButton.addEventListener("click", async function(e) {
|
||||
if (textBox.value == "" || textBox.value.includes("/") || textBox.value.includes("http") || textBox.value.includes(":")) {
|
||||
alert(chrome.i18n.getMessage("addInvidiousInstanceError"));
|
||||
} else {
|
||||
// Add this
|
||||
let instanceList = SB.config[option];
|
||||
if (!instanceList) instanceList = [];
|
||||
|
||||
instanceList.push(textBox.value);
|
||||
|
||||
SB.config[option] = instanceList;
|
||||
|
||||
let checkbox = document.querySelector("#support-invidious input");
|
||||
checkbox.checked = true;
|
||||
|
||||
invidiousOnClick(checkbox, "supportInvidious");
|
||||
|
||||
textBox.value = "";
|
||||
|
||||
// Hide this section again
|
||||
element.querySelector(".option-hidden-section").classList.add("hidden");
|
||||
button.classList.remove("disabled");
|
||||
}
|
||||
});
|
||||
|
||||
let resetButton = element.querySelector(".invidious-instance-reset");
|
||||
resetButton.addEventListener("click", function(e) {
|
||||
if (confirm(chrome.i18n.getMessage("resetInvidiousInstanceAlert"))) {
|
||||
// Set to a clone of the default
|
||||
SB.config[option] = SB.defaults[option].slice(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Run when the invidious button is being initialized
|
||||
*
|
||||
* @param {HTMLElement} checkbox
|
||||
* @param {string} option
|
||||
*/
|
||||
function invidiousInit(checkbox, option) {
|
||||
let permissions = ["declarativeContent"];
|
||||
if (isFirefox()) permissions = [];
|
||||
|
||||
chrome.permissions.contains({
|
||||
origins: getInvidiousInstancesRegex(),
|
||||
permissions: permissions
|
||||
}, function (result) {
|
||||
if (result != checkbox.checked) {
|
||||
SB.config[option] = result;
|
||||
|
||||
checkbox.checked = result;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Run whenever the invidious checkbox is clicked
|
||||
*
|
||||
* @param {HTMLElement} checkbox
|
||||
* @param {string} option
|
||||
*/
|
||||
function invidiousOnClick(checkbox, option) {
|
||||
if (checkbox.checked) {
|
||||
setupExtraSitePermissions(function (granted) {
|
||||
if (!granted) {
|
||||
SB.config[option] = false;
|
||||
checkbox.checked = false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
removeExtraSiteRegistration();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger the container to ask the user for a keybind.
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
*/
|
||||
function activateKeybindChange(element) {
|
||||
let button = element.querySelector(".trigger-button");
|
||||
if (button.classList.contains("disabled")) return;
|
||||
|
||||
button.classList.add("disabled");
|
||||
|
||||
let option = element.getAttribute("sync-option");
|
||||
|
||||
let currentlySet = SB.config[option] !== null ? chrome.i18n.getMessage("keybindCurrentlySet") : "";
|
||||
|
||||
let status = element.querySelector(".option-hidden-section > .keybind-status");
|
||||
status.innerText = chrome.i18n.getMessage("keybindDescription") + currentlySet;
|
||||
|
||||
if (SB.config[option] !== null) {
|
||||
let statusKey = element.querySelector(".option-hidden-section > .keybind-status-key");
|
||||
statusKey.innerText = SB.config[option];
|
||||
}
|
||||
|
||||
element.querySelector(".option-hidden-section").classList.remove("hidden");
|
||||
|
||||
document.addEventListener("keydown", (e) => keybindKeyPressed(element, e), {once: true});
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a key is pressed in an activiated keybind change option.
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @param {KeyboardEvent} e
|
||||
*/
|
||||
function keybindKeyPressed(element, e) {
|
||||
e = e || window.event;
|
||||
var key = e.key;
|
||||
|
||||
let button = element.querySelector(".trigger-button");
|
||||
|
||||
// cancel setting a keybind
|
||||
if (key === "Escape") {
|
||||
element.querySelector(".option-hidden-section").classList.add("hidden");
|
||||
button.classList.remove("disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
let option = element.getAttribute("sync-option");
|
||||
|
||||
SB.config[option] = key;
|
||||
|
||||
let status = element.querySelector(".option-hidden-section > .keybind-status");
|
||||
status.innerText = chrome.i18n.getMessage("keybindDescriptionComplete");
|
||||
|
||||
let statusKey = element.querySelector(".option-hidden-section > .keybind-status-key");
|
||||
statusKey.innerText = key;
|
||||
|
||||
button.classList.remove("disabled");
|
||||
}
|
||||
|
||||
/**
|
||||
* Will trigger the textbox to appear to be able to change an option's text.
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
*/
|
||||
function activateTextChange(element) {
|
||||
let button = element.querySelector(".trigger-button");
|
||||
if (button.classList.contains("disabled")) return;
|
||||
|
||||
button.classList.add("disabled");
|
||||
|
||||
let textBox = element.querySelector(".option-text-box");
|
||||
let option = element.getAttribute("sync-option");
|
||||
|
||||
// See if anything extra must be done
|
||||
switch (option) {
|
||||
case "invidiousInstances":
|
||||
element.querySelector(".option-hidden-section").classList.remove("hidden");
|
||||
return;
|
||||
}
|
||||
|
||||
textBox.value = SB.config[option];
|
||||
|
||||
let setButton = element.querySelector(".text-change-set");
|
||||
setButton.addEventListener("click", () => {
|
||||
let confirmMessage = element.getAttribute("confirm-message");
|
||||
|
||||
if (confirmMessage === null || confirm(chrome.i18n.getMessage(confirmMessage))) {
|
||||
SB.config[option] = textBox.value;
|
||||
}
|
||||
});
|
||||
|
||||
element.querySelector(".option-hidden-section").classList.remove("hidden");
|
||||
}
|
||||
7588
package-lock.json
generated
Normal file
7588
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
22
package.json
Normal file
22
package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "sponsorblock",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "background.js",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"web-ext": "^4.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"dev": "web-ext run --start-url https://chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm",
|
||||
"build": "web-ext build --overwrite-dest -i \"*(package-lock.json|README.md|package.json|config.js.example|firefox_manifest-extra.json|manifest.json.original|ignored|crowdin.yml)\""
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/ajayyy/SponsorBlock.git"
|
||||
},
|
||||
"author": "Ajay Ramachandran",
|
||||
"license": "GPL-3.0-only",
|
||||
"private": true
|
||||
}
|
||||
@@ -35,6 +35,10 @@ sub.popupElement {
|
||||
}
|
||||
/* end reset */
|
||||
|
||||
#sponsorBlockPopupLogo {
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.popupElement {
|
||||
font-family: 'Source Sans Pro', sans-serif;
|
||||
|
||||
@@ -43,12 +47,13 @@ sub.popupElement {
|
||||
|
||||
h1.popupElement {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.popupBody {
|
||||
font-size: 14px;
|
||||
background-color: #ffd9d9;
|
||||
padding: 5px;
|
||||
padding: 0px 5px;
|
||||
}
|
||||
|
||||
.discreteLink.popupElement {
|
||||
|
||||
295
popup.html
295
popup.html
@@ -1,97 +1,45 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>SponsorBlock Popup</title>
|
||||
<title>__MSG_openPopup__</title>
|
||||
<script src="SB.js"></script>
|
||||
<link id="sponorBlockPopupFont" rel="stylesheet" type="text/css" href="/libs/Source+Sans+Pro.css"/>
|
||||
<link id="sponorBlockStyleSheet" rel="stylesheet" type="text/css" href="popup.css"/>
|
||||
</head>
|
||||
|
||||
<body class="popupBody">
|
||||
<center>
|
||||
<div id="app" class="popupBody">
|
||||
<img src="icons/LogoSponsorBlocker256px.png" height="64px" id="sponsorBlockPopupLogo"/>
|
||||
|
||||
<h1 class="popupElement">SponsorBlock</h1>
|
||||
<div id="app" class="popupBody sponsorBlockPageBody">
|
||||
<h1 class="popupElement">
|
||||
<img src="icons/IconSponsorBlocker256px.png" height="32px" id="sponsorBlockPopupLogo"/>
|
||||
__MSG_Name__
|
||||
</h1>
|
||||
|
||||
<!-- Loading text -->
|
||||
<p id="loadingIndicator" class="popupElement">Loading...</p>
|
||||
|
||||
<p id="loadingIndicator" class="popupElement">__MSG_noVideoID__</p>
|
||||
|
||||
<!-- Hidden until loading complete -->
|
||||
<div id="mainControls" class="main popupElement" style="display: none">
|
||||
<!-- If the video was found in the database -->
|
||||
<div id="videoFound">
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="downloadedSponsorMessageTimes" class="popupElement">
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
|
||||
<div>
|
||||
<button id="whitelistChannel" class="whitelistButton popupElement">Whitelist Channel</button>
|
||||
<button id="unwhitelistChannel" class="whitelistButton popupElement" style="display: none">Remove Channel From Whitelist</button>
|
||||
</div>
|
||||
<sub class="popupElement">
|
||||
Whitelist the channels who do sponsorships ethically to encourage good behavior, or maybe if they are just entertaining and funny. Or don't, that's your call.
|
||||
</sub>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<button id="reportAnIssue" class="dangerButton popupElement">Vote On A Sponsor Time</button>
|
||||
|
||||
<div id="issueReporterContainer" class="popupElement" style="display: none">
|
||||
|
||||
<h3 style="margin-top: 0px" class="popupElement">Vote On A Sponsor Time</h3>
|
||||
|
||||
<div id="issueReporterTimeButtons" class="popupElement">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<h2 class="recordingSubtitle popupElement">Record the times of a sponsorship</h2>
|
||||
|
||||
<p class="popupElement">
|
||||
<span id=sponsorTimesContributionsContainer class="popupElement" style="display: none">
|
||||
So far, you've submitted
|
||||
<span id="sponsorTimesContributionsDisplay" class="popupElement">
|
||||
0
|
||||
</span>
|
||||
<span id="sponsorTimesContributionsDisplayEndWord" class="popupElement">
|
||||
sponsors.
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span id=sponsorTimesViewsContainer class="popupElement" style="display: none">
|
||||
You have saved people from
|
||||
<span id="sponsorTimesViewsDisplay" class="popupElement">
|
||||
0
|
||||
</span>
|
||||
<span id="sponsorTimesViewsDisplayEndWord" class="popupElement">
|
||||
sponsor segments.
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<div class="popupElement">
|
||||
View the leaderboard <a class="popupElement discreteLink" href="https://sponsor.ajay.app/stats" target="_blank">here</a>.
|
||||
</div>
|
||||
</p>
|
||||
|
||||
<p class="popupElement">
|
||||
Click the button below when the sponsorship starts and ends to record and
|
||||
submit it to the database.
|
||||
__MSG_recordTimesDescription__
|
||||
</p>
|
||||
|
||||
|
||||
<div>
|
||||
<button id="sponsorStart" class="greenButton popupElement">Sponsorship Starts Now</button>
|
||||
<button id="sponsorStart" class="greenButton popupElement">__MSG_sponsorStart__</button>
|
||||
</div>
|
||||
|
||||
<sub class="popupElement">__MSG_popupHint__</sub>
|
||||
|
||||
<sub class="popupElement">Hint: Press the semicolon key while focused on a video report the start/end of a sponsor and quote to submit.</sub>
|
||||
|
||||
<div id="submissionSection" class="popupElement" style="display: none">
|
||||
<h3 class="popupElement">Latest Sponsor Message Times Chosen</h3>
|
||||
<h3 class="popupElement">__MSG_lastTimes__</h3>
|
||||
<b>
|
||||
<div id="sponsorMessageTimes" class="popupElement">
|
||||
|
||||
@@ -100,13 +48,14 @@
|
||||
|
||||
<br/>
|
||||
|
||||
<button id="clearTimes" class="smallButton popupElement">Clear Times</button>
|
||||
<button id="clearTimes" class="smallButton popupElement">__MSG_clearTimesButton__</button>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div id="submitTimesContainer" class="popupElement" style="display: none">
|
||||
<button id="submitTimes" class="smallButton popupElement">Submit Times</button>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<button id="submitTimes" class="smallButton popupElement">__MSG_submitTimesButton__</button>
|
||||
|
||||
<div id="submitTimesInfoMessageContainer" class="popupElement" style="display: none">
|
||||
<h3 id="submitTimesInfoMessage" class="popupElement">
|
||||
@@ -115,36 +64,7 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="setUsernameContainer" class="popupElement">
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<button id="setUsernameButton" class="warningButton popupElement">Set Username</button>
|
||||
<br/>
|
||||
<sub class="popupElement">
|
||||
This is used on the public stats page to show off how much you've contributed. See it <a class="popupElement discreteLink" href="https://sponsor.ajay.app/stats" target="_blank">here</a>.
|
||||
</sub>
|
||||
</div>
|
||||
|
||||
<div id="setUsername" class="popupElement" style="display: none">
|
||||
<br/>
|
||||
|
||||
<h3>Set Username</h3>
|
||||
|
||||
<div id="setUsernameStatusContainer" style="display: none">
|
||||
<h2 id="setUsernameStatus"></h2>
|
||||
</div>
|
||||
|
||||
|
||||
<input id="usernameInput" hint="Username"></input>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<button id="submitUsername" class="warningButton popupElement">Submit Username</button>
|
||||
</div>
|
||||
|
||||
<div id="discordButtonContainer" class="popupElement" style="display: none">
|
||||
@@ -154,74 +74,137 @@
|
||||
|
||||
<br/>
|
||||
|
||||
Come join the official discord server to give suggestions and feedback!
|
||||
__MSG_discordAdvert__
|
||||
|
||||
<br/>
|
||||
|
||||
<span id="hideDiscordButton" class="smallLink popupElement">Hide this</span>
|
||||
<span id="hideDiscordButton" class="smallLink popupElement">__MSG_hideThis__</span>
|
||||
</div>
|
||||
|
||||
<div id="optionsButtonContainer" class="popupElement">
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<button id="optionsButton" class="dangerButton popupElement">Options</button>
|
||||
<div>
|
||||
<br/>
|
||||
|
||||
<button id="whitelistChannel" class="whitelistButton popupElement">__MSG_whitelistChannel__</button>
|
||||
<button id="unwhitelistChannel" class="whitelistButton popupElement" style="display: none">__MSG_removeFromWhitelist__</button>
|
||||
</div>
|
||||
|
||||
<div id="options" class="popupElement" style="display: none">
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<h3>Options</h3>
|
||||
|
||||
<button id="hideVideoPlayerControls" class="warningButton popupElement">Hide Buttons On YouTube Player</button>
|
||||
<button id="showVideoPlayerControls" style="display: none" class="warningButton popupElement">Show Buttons On YouTube Player</button>
|
||||
<br/>
|
||||
<sub class="popupElement">
|
||||
This hides the buttons that appear on the YouTube player to submit sponsors. I can see this being annoying for some
|
||||
people. Instead of using the button there, this popup can be used to submit sponsors. To hide the notice that appears,
|
||||
use the button that appears on the notice saying "Don't show this again". You can always enable these settings again
|
||||
later.
|
||||
</sub>
|
||||
<button id="reportAnIssue" class="dangerButton popupElement">__MSG_voteOnTime__</button>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
<div id="issueReporterContainer" class="popupElement" style="display: none">
|
||||
|
||||
<button id="hideInfoButtonPlayerControls" class="warningButton popupElement">Hide Info Button On YouTube Player</button>
|
||||
<button id="showInfoButtonPlayerControls" style="display: none" class="warningButton popupElement">Show Info Button On YouTube Player</button>
|
||||
<br/>
|
||||
<sub class="popupElement">
|
||||
This is the button that opens up a popup in the YouTube page.
|
||||
</sub>
|
||||
<h3 style="margin-top: 0px" class="popupElement">__MSG_voteOnTime__</h3>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
<div id="issueReporterTimeButtons" class="popupElement">
|
||||
|
||||
<button id="hideDeleteButtonPlayerControls" class="warningButton popupElement">Hide Delete Button On YouTube Player</button>
|
||||
<button id="showDeleteButtonPlayerControls" style="display: none" class="warningButton popupElement">Show Delete Button On YouTube Player</button>
|
||||
<br/>
|
||||
<sub class="popupElement">
|
||||
This is the button that allows you to clear all sponsors on the YouTube player.
|
||||
</sub>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<button id="disableSponsorViewTracking" class="warningButton popupElement">Disable Sponsor View Tracking</button>
|
||||
<button id="enableSponsorViewTracking" style="display: none" class="warningButton popupElement">Enable Sponsor View Tracking</button>
|
||||
<br/>
|
||||
<sub class="popupElement">
|
||||
This feature tracks which sponsors you have skipped to let users know how much their submission has helped others and
|
||||
used as a metric along with upvotes to ensure that spam doesn't get into the database. The extension sends a message
|
||||
to the server each time you skip a sponsor. Hopefully most people don't change this setting so that the view numbers
|
||||
are accurate. :)
|
||||
</sub>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<button id="showNoticeAgain" style="display: none" class="dangerButton popupElement">Show Notice Again</button>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button id="disableSkipping" class="greenButton popupElement">__MSG_disableSkipping__</button>
|
||||
<button id="enableSkipping" class="whitelistButton popupElement" style="display: none">__MSG_enableSkipping__</button>
|
||||
</div>
|
||||
|
||||
<h2 class="recordingSubtitle popupElement">__MSG_yourWork__</h2>
|
||||
|
||||
<p class="popupElement">
|
||||
<span id="sponsorTimesContributionsContainer" class="popupElement" style="display: none">
|
||||
__MSG_soFarUHSubmited__
|
||||
<span id="sponsorTimesContributionsDisplay" class="popupElement">
|
||||
0
|
||||
</span>
|
||||
<span id="sponsorTimesContributionsDisplayEndWord" class="popupElement">__MSG_Sponsors__</span>.
|
||||
</span>
|
||||
|
||||
<span id="sponsorTimesViewsContainer" class="popupElement" style="display: none">
|
||||
__MSG_savedPeopleFrom__
|
||||
<span id="sponsorTimesViewsDisplay" class="popupElement">
|
||||
0
|
||||
</span>
|
||||
<span id="sponsorTimesViewsDisplayEndWord" class="popupElement">__MSG_Segments__</span>.
|
||||
</span>
|
||||
|
||||
<span id="sponsorTimesOthersTimeSavedContainer" class="popupElement" style="display: none">
|
||||
__MSG_youHaveSavedTime__
|
||||
<span id="sponsorTimesOthersTimeSavedDisplay" class="popupElement">
|
||||
0
|
||||
</span>
|
||||
<span id="sponsorTimesOthersTimeSavedEndWord" class="popupElement">__MSG_minsLower__</span>
|
||||
|
||||
<span class="popupElement">__MSG_youHaveSavedTimeEnd__</span>
|
||||
</span>
|
||||
|
||||
<div id="sponsorTimesSkipsDoneContainer" class="popupElement" style="display: none">
|
||||
__MSG_youHaveSkipped__
|
||||
<span id="sponsorTimesSkipsDoneDisplay" class="popupElement">
|
||||
0
|
||||
</span>
|
||||
<span id="sponsorTimesSkipsDoneEndWord" class="popupElement">__MSG_Segments__</span> since December 5th.
|
||||
</div>
|
||||
|
||||
<div id="sponsorTimeSavedContainer" class="popupElement" style="display: none">
|
||||
__MSG_youHaveSaved__
|
||||
<span id="sponsorTimeSavedDisplay" class="popupElement">
|
||||
0
|
||||
</span>
|
||||
<span id="sponsorTimeSavedEndWord" class="popupElement">__MSG_minsLower__</span> since December 5th.
|
||||
|
||||
</br/>
|
||||
</br/>
|
||||
</div>
|
||||
|
||||
<div class="popupElement">
|
||||
__MSG_viewLeaderboard__ <a class="popupElement discreteLink" href="https://sponsor.ajay.app/stats" target="_blank">__MSG_here__</a>.
|
||||
</div>
|
||||
</p>
|
||||
|
||||
<div id="setUsernameContainer" class="popupElement">
|
||||
|
||||
<button id="setUsernameButton" class="warningButton popupElement">__MSG_setUsername__</button>
|
||||
<br/>
|
||||
<sub class="popupElement">
|
||||
__MSG_publicStats__ <a class="popupElement discreteLink" href="https://sponsor.ajay.app/stats" target="_blank">__MSG_here__</a>.
|
||||
</sub>
|
||||
</div>
|
||||
|
||||
<div id="setUsername" class="popupElement" style="display: none">
|
||||
<h3>__MSG_setUsername__</h3>
|
||||
|
||||
<div id="setUsernameStatusContainer" style="display: none">
|
||||
<h2 id="setUsernameStatus"></h2>
|
||||
</div>
|
||||
|
||||
<input id="usernameInput" hint="Username"></input>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<button id="submitUsername" class="warningButton popupElement">__MSG_setUsername__</button>
|
||||
</div>
|
||||
|
||||
<div id="optionsButtonContainer" class="popupElement">
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<button id="optionsButton" class="dangerButton popupElement">__MSG_Options__</button>
|
||||
|
||||
<br/>
|
||||
|
||||
<sub class="popupElement">
|
||||
__MSG_optionsInfo__
|
||||
</sub>
|
||||
|
||||
<br/>
|
||||
</div>
|
||||
|
||||
<button id="showNoticeAgain" style="display: none" class="dangerButton popupElement">__MSG_showNotice__</button>
|
||||
</div>
|
||||
</center>
|
||||
</body>
|
||||
|
||||
596
popup.js
596
popup.js
@@ -1,44 +1,40 @@
|
||||
|
||||
//make this a function to allow this to run on the content page
|
||||
function runThePopup() {
|
||||
|
||||
async function runThePopup() {
|
||||
localizeHtmlPage();
|
||||
//is it in the popup or content script
|
||||
var inPopup = true;
|
||||
if (chrome.tabs == undefined) {
|
||||
//this is on the content script, use direct communication
|
||||
chrome.tabs = {};
|
||||
chrome.tabs.sendMessage = function(id, request, callback) {
|
||||
messageListener(request, null, callback);
|
||||
}
|
||||
|
||||
//add a dummy query method
|
||||
chrome.tabs.query = function(config, callback) {
|
||||
callback([{
|
||||
url: document.URL,
|
||||
id: -1
|
||||
}]);
|
||||
}
|
||||
|
||||
inPopup = false;
|
||||
//this is on the content script, use direct communication
|
||||
chrome.tabs = {};
|
||||
chrome.tabs.sendMessage = function(id, request, callback) {
|
||||
messageListener(request, null, callback);
|
||||
}
|
||||
|
||||
//add a dummy query method
|
||||
chrome.tabs.query = function(config, callback) {
|
||||
callback([{
|
||||
url: document.URL,
|
||||
id: -1
|
||||
}]);
|
||||
}
|
||||
|
||||
inPopup = false;
|
||||
}
|
||||
|
||||
var SB = {};
|
||||
|
||||
await wait(() => SB.config !== undefined);
|
||||
|
||||
["sponsorStart",
|
||||
// Top toggles
|
||||
"whitelistChannel",
|
||||
"unwhitelistChannel",
|
||||
"disableSkipping",
|
||||
"enableSkipping",
|
||||
// Options
|
||||
"showNoticeAgain",
|
||||
"optionsButton",
|
||||
// More controls
|
||||
"clearTimes",
|
||||
"submitTimes",
|
||||
"showNoticeAgain",
|
||||
"hideVideoPlayerControls",
|
||||
"showVideoPlayerControls",
|
||||
"hideInfoButtonPlayerControls",
|
||||
"showInfoButtonPlayerControls",
|
||||
"hideDeleteButtonPlayerControls",
|
||||
"showDeleteButtonPlayerControls",
|
||||
"disableSponsorViewTracking",
|
||||
"enableSponsorViewTracking",
|
||||
"optionsButton",
|
||||
"reportAnIssue",
|
||||
// sponsorTimesContributions
|
||||
"sponsorTimesContributionsContainer",
|
||||
@@ -48,6 +44,18 @@ function runThePopup() {
|
||||
"sponsorTimesViewsContainer",
|
||||
"sponsorTimesViewsDisplay",
|
||||
"sponsorTimesViewsDisplayEndWord",
|
||||
// sponsorTimesOthersTimeSaved
|
||||
"sponsorTimesOthersTimeSavedContainer",
|
||||
"sponsorTimesOthersTimeSavedDisplay",
|
||||
"sponsorTimesOthersTimeSavedEndWord",
|
||||
// sponsorTimesSkipsDone
|
||||
"sponsorTimesSkipsDoneContainer",
|
||||
"sponsorTimesSkipsDoneDisplay",
|
||||
"sponsorTimesSkipsDoneEndWord",
|
||||
// sponsorTimeSaved
|
||||
"sponsorTimeSavedContainer",
|
||||
"sponsorTimeSavedDisplay",
|
||||
"sponsorTimeSavedEndWord",
|
||||
// discordButtons
|
||||
"discordButtonContainer",
|
||||
"hideDiscordButton",
|
||||
@@ -75,23 +83,17 @@ function runThePopup() {
|
||||
SB.sponsorStart.addEventListener("click", sendSponsorStartMessage);
|
||||
SB.whitelistChannel.addEventListener("click", whitelistChannel);
|
||||
SB.unwhitelistChannel.addEventListener("click", unwhitelistChannel);
|
||||
SB.disableSkipping.addEventListener("click", () => toggleSkipping(true));
|
||||
SB.enableSkipping.addEventListener("click", () => toggleSkipping(false));
|
||||
SB.clearTimes.addEventListener("click", clearTimes);
|
||||
SB.submitTimes.addEventListener("click", submitTimes);
|
||||
SB.showNoticeAgain.addEventListener("click", showNoticeAgain);
|
||||
SB.hideVideoPlayerControls.addEventListener("click", hideVideoPlayerControls);
|
||||
SB.showVideoPlayerControls.addEventListener("click", showVideoPlayerControls);
|
||||
SB.hideInfoButtonPlayerControls.addEventListener("click", hideInfoButtonPlayerControls);
|
||||
SB.showInfoButtonPlayerControls.addEventListener("click", showInfoButtonPlayerControls);
|
||||
SB.hideDeleteButtonPlayerControls.addEventListener("click", hideDeleteButtonPlayerControls);
|
||||
SB.showDeleteButtonPlayerControls.addEventListener("click", showDeleteButtonPlayerControls);
|
||||
SB.disableSponsorViewTracking.addEventListener("click", disableSponsorViewTracking);
|
||||
SB.enableSponsorViewTracking.addEventListener("click", enableSponsorViewTracking);
|
||||
SB.setUsernameButton.addEventListener("click", setUsernameButton);
|
||||
SB.submitUsername.addEventListener("click", submitUsername);
|
||||
SB.optionsButton.addEventListener("click", openOptions);
|
||||
SB.reportAnIssue.addEventListener("click", reportAnIssue);
|
||||
SB.hideDiscordButton.addEventListener("click", hideDiscordButton);
|
||||
|
||||
|
||||
//if true, the button now selects the end time
|
||||
let startTimeChosen = false;
|
||||
|
||||
@@ -101,112 +103,114 @@ function runThePopup() {
|
||||
//current video ID of this tab
|
||||
let currentVideoID = null;
|
||||
|
||||
//is this a YouTube tab?
|
||||
let isYouTubeTab = false;
|
||||
|
||||
//see if discord link can be shown
|
||||
chrome.storage.sync.get(["hideDiscordLink"], function(result) {
|
||||
let hideDiscordLink = result.hideDiscordLink;
|
||||
if (hideDiscordLink == undefined || !hideDiscordLink) {
|
||||
chrome.storage.sync.get(["hideDiscordLaunches"], function(result) {
|
||||
let hideDiscordLaunches = result.hideDiscordLaunches;
|
||||
//only if less than 5 launches
|
||||
if (hideDiscordLaunches == undefined || hideDiscordLaunches < 10) {
|
||||
SB.discordButtonContainer.style.display = null;
|
||||
|
||||
if (hideDiscordLaunches == undefined) {
|
||||
hideDiscordButton = 1;
|
||||
}
|
||||
|
||||
chrome.storage.sync.set({"hideDiscordLaunches": hideDiscordButton + 1});
|
||||
let hideDiscordLink = SB.config.hideDiscordLink;
|
||||
if (hideDiscordLink == undefined || !hideDiscordLink) {
|
||||
let hideDiscordLaunches = SB.config.hideDiscordLaunches;
|
||||
//only if less than 10 launches
|
||||
if (hideDiscordLaunches == undefined || hideDiscordLaunches < 10) {
|
||||
SB.discordButtonContainer.style.display = null;
|
||||
|
||||
if (hideDiscordLaunches == undefined) {
|
||||
hideDiscordLaunches = 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//if the don't show notice again letiable is true, an option to
|
||||
// disable should be available
|
||||
chrome.storage.sync.get(["dontShowNoticeAgain"], function(result) {
|
||||
let dontShowNoticeAgain = result.dontShowNoticeAgain;
|
||||
if (dontShowNoticeAgain != undefined && dontShowNoticeAgain) {
|
||||
SB.showNoticeAgain.style.display = "unset";
|
||||
}
|
||||
});
|
||||
|
||||
//show proper video player controls options
|
||||
chrome.storage.sync.get(["hideVideoPlayerControls"], function(result) {
|
||||
let hideVideoPlayerControls = result.hideVideoPlayerControls;
|
||||
if (hideVideoPlayerControls != undefined && hideVideoPlayerControls) {
|
||||
SB.hideVideoPlayerControls.style.display = "none";
|
||||
SB.showVideoPlayerControls.style.display = "unset";
|
||||
}
|
||||
});
|
||||
chrome.storage.sync.get(["hideInfoButtonPlayerControls"], function(result) {
|
||||
let hideInfoButtonPlayerControls = result.hideInfoButtonPlayerControls;
|
||||
if (hideInfoButtonPlayerControls != undefined && hideInfoButtonPlayerControls) {
|
||||
SB.hideInfoButtonPlayerControls.style.display = "none";
|
||||
SB.showInfoButtonPlayerControls.style.display = "unset";
|
||||
}
|
||||
});
|
||||
chrome.storage.sync.get(["hideDeleteButtonPlayerControls"], function(result) {
|
||||
let hideDeleteButtonPlayerControls = result.hideDeleteButtonPlayerControls;
|
||||
if (hideDeleteButtonPlayerControls != undefined && hideDeleteButtonPlayerControls) {
|
||||
SB.hideDeleteButtonPlayerControls.style.display = "none";
|
||||
SB.showDeleteButtonPlayerControls.style.display = "unset";
|
||||
}
|
||||
});
|
||||
|
||||
//show proper tracking option
|
||||
chrome.storage.sync.get(["trackViewCount"], function(result) {
|
||||
let trackViewCount = result.trackViewCount;
|
||||
if (trackViewCount != undefined && !trackViewCount) {
|
||||
SB.disableSponsorViewTracking.style.display = "none";
|
||||
SB.enableSponsorViewTracking.style.display = "unset";
|
||||
}
|
||||
});
|
||||
|
||||
//get the amount of times this user has contributed and display it to thank them
|
||||
chrome.storage.sync.get(["sponsorTimesContributed"], function(result) {
|
||||
if (result.sponsorTimesContributed != undefined) {
|
||||
if (result.sponsorTimesContributed > 1) {
|
||||
SB.sponsorTimesContributionsDisplayEndWord.innerText = chrome.i18n.getMessage("Sponsors");
|
||||
} else {
|
||||
SB.sponsorTimesContributionsDisplayEndWord.innerText = chrome.i18n.getMessage("Sponsor");
|
||||
SB.config.hideDiscordLaunches = hideDiscordLaunches + 1;
|
||||
}
|
||||
SB.sponsorTimesContributionsDisplay.innerText = result.sponsorTimesContributed;
|
||||
SB.sponsorTimesContributionsContainer.style.display = "unset";
|
||||
|
||||
//get the userID
|
||||
chrome.storage.sync.get(["userID"], function(result) {
|
||||
let userID = result.userID;
|
||||
if (userID != undefined) {
|
||||
//there are probably some views on these submissions then
|
||||
//get the amount of views from the sponsors submitted
|
||||
sendRequestToServer("GET", "/api/getViewsForUser?userID=" + userID, function(xmlhttp) {
|
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||
let viewCount = JSON.parse(xmlhttp.responseText).viewCount;
|
||||
if (viewCount != 0) {
|
||||
if (viewCount > 1) {
|
||||
SB.sponsorTimesViewsDisplayEndWord.innerText = chrome.i18n.getMessage("Segments");
|
||||
} else {
|
||||
SB.sponsorTimesViewsDisplayEndWord.innerText = chrome.i18n.getMessage("Segment");
|
||||
}
|
||||
}
|
||||
|
||||
SB.sponsorTimesViewsDisplay.innerText = viewCount;
|
||||
SB.sponsorTimesViewsContainer.style.display = "unset";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
//show proper disable skipping button
|
||||
let disableSkipping = SB.config.disableSkipping;
|
||||
if (disableSkipping != undefined && disableSkipping) {
|
||||
SB.disableSkipping.style.display = "none";
|
||||
SB.enableSkipping.style.display = "unset";
|
||||
}
|
||||
|
||||
//if the don't show notice again variable is true, an option to
|
||||
// disable should be available
|
||||
let dontShowNotice = SB.config.dontShowNotice;
|
||||
if (dontShowNotice != undefined && dontShowNotice) {
|
||||
SB.showNoticeAgain.style.display = "unset";
|
||||
}
|
||||
|
||||
//get the amount of times this user has contributed and display it to thank them
|
||||
if (SB.config.sponsorTimesContributed != undefined) {
|
||||
if (SB.config.sponsorTimesContributed > 1) {
|
||||
SB.sponsorTimesContributionsDisplayEndWord.innerText = chrome.i18n.getMessage("Sponsors");
|
||||
} else {
|
||||
SB.sponsorTimesContributionsDisplayEndWord.innerText = chrome.i18n.getMessage("Sponsor");
|
||||
}
|
||||
});
|
||||
SB.sponsorTimesContributionsDisplay.innerText = SB.config.sponsorTimesContributed;
|
||||
SB.sponsorTimesContributionsContainer.style.display = "unset";
|
||||
|
||||
//get the userID
|
||||
let userID = SB.config.userID;
|
||||
if (userID != undefined) {
|
||||
//there are probably some views on these submissions then
|
||||
//get the amount of views from the sponsors submitted
|
||||
sendRequestToServer("GET", "/api/getViewsForUser?userID=" + userID, function(xmlhttp) {
|
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||
let viewCount = JSON.parse(xmlhttp.responseText).viewCount;
|
||||
if (viewCount != 0) {
|
||||
if (viewCount > 1) {
|
||||
SB.sponsorTimesViewsDisplayEndWord.innerText = chrome.i18n.getMessage("Segments");
|
||||
} else {
|
||||
SB.sponsorTimesViewsDisplayEndWord.innerText = chrome.i18n.getMessage("Segment");
|
||||
}
|
||||
|
||||
SB.sponsorTimesViewsDisplay.innerText = viewCount;
|
||||
SB.sponsorTimesViewsContainer.style.display = "unset";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//get this time in minutes
|
||||
sendRequestToServer("GET", "/api/getSavedTimeForUser?userID=" + userID, function(xmlhttp) {
|
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||
let minutesSaved = JSON.parse(xmlhttp.responseText).timeSaved;
|
||||
if (minutesSaved != 0) {
|
||||
if (minutesSaved != 1) {
|
||||
SB.sponsorTimesOthersTimeSavedEndWord.innerText = chrome.i18n.getMessage("minsLower");
|
||||
} else {
|
||||
SB.sponsorTimesOthersTimeSavedEndWord.innerText = chrome.i18n.getMessage("minLower");
|
||||
}
|
||||
|
||||
SB.sponsorTimesOthersTimeSavedDisplay.innerText = getFormattedHours(minutesSaved);
|
||||
SB.sponsorTimesOthersTimeSavedContainer.style.display = "unset";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//get the amount of times this user has skipped a sponsor
|
||||
if (SB.config.skipCount != undefined) {
|
||||
if (SB.config.skipCount != 1) {
|
||||
SB.sponsorTimesSkipsDoneEndWord.innerText = chrome.i18n.getMessage("Sponsors");
|
||||
} else {
|
||||
SB.sponsorTimesSkipsDoneEndWord.innerText = chrome.i18n.getMessage("Sponsor");
|
||||
}
|
||||
|
||||
SB.sponsorTimesSkipsDoneDisplay.innerText = SB.config.skipCount;
|
||||
SB.sponsorTimesSkipsDoneContainer.style.display = "unset";
|
||||
}
|
||||
|
||||
//get the amount of time this user has saved.
|
||||
if (SB.config.minutesSaved != undefined) {
|
||||
if (SB.config.minutesSaved != 1) {
|
||||
SB.sponsorTimeSavedEndWord.innerText = chrome.i18n.getMessage("minsLower");
|
||||
} else {
|
||||
SB.sponsorTimeSavedEndWord.innerText = chrome.i18n.getMessage("minLower");
|
||||
}
|
||||
|
||||
SB.sponsorTimeSavedDisplay.innerText = getFormattedHours(SB.config.minutesSaved);
|
||||
SB.sponsorTimeSavedContainer.style.display = "unset";
|
||||
}
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, onTabs);
|
||||
|
||||
|
||||
function onTabs(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {message: 'getVideoID'}, function(result) {
|
||||
if (result != undefined && result.videoID) {
|
||||
@@ -227,25 +231,22 @@ function runThePopup() {
|
||||
}
|
||||
|
||||
//load video times for this video
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.sync.get([sponsorTimeKey], function(result) {
|
||||
let sponsorTimesStorage = result[sponsorTimeKey];
|
||||
if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
|
||||
if (sponsorTimesStorage[sponsorTimesStorage.length - 1] != undefined && sponsorTimesStorage[sponsorTimesStorage.length - 1].length < 2) {
|
||||
startTimeChosen = true;
|
||||
SB.sponsorStart.innerHTML = chrome.i18n.getMessage("sponsorEnd");
|
||||
}
|
||||
|
||||
sponsorTimes = sponsorTimesStorage;
|
||||
|
||||
displaySponsorTimes();
|
||||
|
||||
//show submission section
|
||||
SB.submissionSection.style.display = "unset";
|
||||
|
||||
showSubmitTimesIfNecessary();
|
||||
let sponsorTimesStorage = SB.config.sponsorTimes.get(currentVideoID);
|
||||
if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
|
||||
if (sponsorTimesStorage[sponsorTimesStorage.length - 1] != undefined && sponsorTimesStorage[sponsorTimesStorage.length - 1].length < 2) {
|
||||
startTimeChosen = true;
|
||||
SB.sponsorStart.innerHTML = chrome.i18n.getMessage("sponsorEnd");
|
||||
}
|
||||
});
|
||||
|
||||
sponsorTimes = sponsorTimesStorage;
|
||||
|
||||
displaySponsorTimes();
|
||||
|
||||
//show submission section
|
||||
SB.submissionSection.style.display = "unset";
|
||||
|
||||
showSubmitTimesIfNecessary();
|
||||
}
|
||||
|
||||
//check if this video's sponsors are known
|
||||
chrome.tabs.sendMessage(
|
||||
@@ -270,7 +271,7 @@ function runThePopup() {
|
||||
|
||||
//remove loading text
|
||||
SB.mainControls.style.display = "unset"
|
||||
SB.loadingIndicator.innerHTML = "";
|
||||
SB.loadingIndicator.style.display = "none";
|
||||
|
||||
if (request.found) {
|
||||
SB.videoFound.innerHTML = chrome.i18n.getMessage("sponsorFound");
|
||||
@@ -294,7 +295,7 @@ function runThePopup() {
|
||||
SB.whitelistChannel.style.display = "none";
|
||||
SB.unwhitelistChannel.style.display = "unset";
|
||||
|
||||
SB.downloadedSponsorMessageTimes.innerText = "Channel Whitelisted!";
|
||||
SB.downloadedSponsorMessageTimes.innerText = chrome.i18n.getMessage("channelWhitelisted");
|
||||
SB.downloadedSponsorMessageTimes.style.fontWeight = "bold";
|
||||
}
|
||||
});
|
||||
@@ -302,13 +303,6 @@ function runThePopup() {
|
||||
);
|
||||
}
|
||||
|
||||
function setVideoID(request) {
|
||||
//if request is undefined, then the page currently being browsed is not YouTube
|
||||
if (request != undefined) {
|
||||
videoID = request.videoID;
|
||||
}
|
||||
}
|
||||
|
||||
function sendSponsorStartMessage() {
|
||||
//the content script will get the message if a YouTube page is open
|
||||
chrome.tabs.query({
|
||||
@@ -331,10 +325,9 @@ function runThePopup() {
|
||||
}
|
||||
|
||||
sponsorTimes[sponsorTimesIndex][startTimeChosen ? 1 : 0] = response.time;
|
||||
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
|
||||
let localStartTimeChosen = startTimeChosen;
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes}, function() {
|
||||
SB.config.sponsorTimes.set(currentVideoID, sponsorTimes);
|
||||
//send a message to the client script
|
||||
if (localStartTimeChosen) {
|
||||
chrome.tabs.query({
|
||||
@@ -347,7 +340,6 @@ function runThePopup() {
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
updateStartTimeChosen();
|
||||
|
||||
@@ -644,8 +636,8 @@ function runThePopup() {
|
||||
tabs[0].id,
|
||||
{message: "getCurrentTime"},
|
||||
function (response) {
|
||||
let minutes = document.getElementById(idStartName + chrome.i18n.getMessage("Mins") + index);
|
||||
let seconds = document.getElementById(idStartName + chrome.i18n.getMessage("Secs") + index);
|
||||
let minutes = document.getElementById(idStartName + "Minutes" + index);
|
||||
let seconds = document.getElementById(idStartName + "Seconds" + index);
|
||||
|
||||
minutes.value = getTimeInMinutes(response.currentTime);
|
||||
seconds.value = getTimeInFormattedSeconds(response.currentTime);
|
||||
@@ -656,8 +648,8 @@ function runThePopup() {
|
||||
//id start name is whether it is the startTime or endTime
|
||||
//gives back the time in seconds
|
||||
function getSponsorTimeEditTimes(idStartName, index) {
|
||||
let minutes = document.getElementById(idStartName + chrome.i18n.getMessage("Mins") + index);
|
||||
let seconds = document.getElementById(idStartName + chrome.i18n.getMessage("Secs") + index);
|
||||
let minutes = document.getElementById(idStartName + "Minutes" + index);
|
||||
let seconds = document.getElementById(idStartName + "Seconds" + index);
|
||||
|
||||
return parseInt(minutes.value) * 60 + parseFloat(seconds.value);
|
||||
}
|
||||
@@ -667,8 +659,7 @@ function runThePopup() {
|
||||
sponsorTimes[index][1] = getSponsorTimeEditTimes("endTime", index);
|
||||
|
||||
//save this
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes}, function() {
|
||||
SB.config.sponsorTimes.set(currentVideoID, sponsorTimes);
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
@@ -678,7 +669,6 @@ function runThePopup() {
|
||||
{message: "sponsorDataChanged"}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
if (closeEditMode) {
|
||||
displaySponsorTimes();
|
||||
@@ -708,8 +698,7 @@ function runThePopup() {
|
||||
sponsorTimes.splice(index, 1);
|
||||
|
||||
//save this
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes}, function() {
|
||||
SB.config.sponsorTimes.set(currentVideoID, sponsorTimes);
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
@@ -719,7 +708,6 @@ function runThePopup() {
|
||||
{message: "sponsorDataChanged"}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
//update display
|
||||
displaySponsorTimes();
|
||||
@@ -760,9 +748,8 @@ function runThePopup() {
|
||||
|
||||
//reset sponsorTimes
|
||||
sponsorTimes = [];
|
||||
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes}, function() {
|
||||
|
||||
SB.config.sponsorTimes.set(currentVideoID, sponsorTimes);
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
@@ -772,7 +759,6 @@ function runThePopup() {
|
||||
{message: "sponsorDataChanged"}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
displaySponsorTimes();
|
||||
|
||||
@@ -799,15 +785,7 @@ function runThePopup() {
|
||||
|
||||
clearTimes();
|
||||
} else {
|
||||
let errorMessage = "";
|
||||
|
||||
if([400,429,409,502].includes(response.statusCode)) {
|
||||
errorMessage = chrome.i18n.getMessage(response.statusCode);
|
||||
} else {
|
||||
errorMessage = chrome.i18n.getMessage("connectionError") + response.statusCode;
|
||||
}
|
||||
|
||||
document.getElementById("submitTimesInfoMessage").innerText = errorMessage;
|
||||
document.getElementById("submitTimesInfoMessage").innerText = getErrorMessage(response.statusCode);
|
||||
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
|
||||
|
||||
SB.submitTimesInfoMessageContainer.style.display = "unset";
|
||||
@@ -818,156 +796,11 @@ function runThePopup() {
|
||||
}
|
||||
|
||||
function showNoticeAgain() {
|
||||
chrome.storage.sync.set({"dontShowNoticeAgain": false});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "showNoticeAgain"
|
||||
});
|
||||
});
|
||||
SB.config.dontShowNotice = false;
|
||||
|
||||
SB.showNoticeAgain.style.display = "none";
|
||||
}
|
||||
|
||||
function hideVideoPlayerControls() {
|
||||
chrome.storage.sync.set({"hideVideoPlayerControls": true});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "changeVideoPlayerControlsVisibility",
|
||||
value: true
|
||||
});
|
||||
});
|
||||
|
||||
SB.hideVideoPlayerControls.style.display = "none";
|
||||
SB.showVideoPlayerControls.style.display = "unset";
|
||||
}
|
||||
|
||||
function showVideoPlayerControls() {
|
||||
chrome.storage.sync.set({"hideVideoPlayerControls": false});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "changeVideoPlayerControlsVisibility",
|
||||
value: false
|
||||
});
|
||||
});
|
||||
|
||||
SB.hideVideoPlayerControls.style.display = "unset";
|
||||
SB.showVideoPlayerControls.style.display = "none";
|
||||
}
|
||||
|
||||
function hideInfoButtonPlayerControls() {
|
||||
chrome.storage.sync.set({"hideInfoButtonPlayerControls": true});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "changeInfoButtonPlayerControlsVisibility",
|
||||
value: true
|
||||
});
|
||||
});
|
||||
|
||||
SB.hideInfoButtonPlayerControls.style.display = "none";
|
||||
SB.showInfoButtonPlayerControls.style.display = "unset";
|
||||
}
|
||||
|
||||
function showInfoButtonPlayerControls() {
|
||||
chrome.storage.sync.set({"hideInfoButtonPlayerControls": false});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "changeVideoPlayerCochangeInfoButtonPlayerControlsVisibilityntrolsVisibility",
|
||||
value: false
|
||||
});
|
||||
});
|
||||
|
||||
SB.hideInfoButtonPlayerControls.style.display = "unset";
|
||||
SB.showInfoButtonPlayerControls.style.display = "none";
|
||||
}
|
||||
|
||||
function hideDeleteButtonPlayerControls() {
|
||||
chrome.storage.sync.set({"hideDeleteButtonPlayerControls": true});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "changeDeleteButtonPlayerControlsVisibility",
|
||||
value: true
|
||||
});
|
||||
});
|
||||
|
||||
SB.hideDeleteButtonPlayerControls.style.display = "none";
|
||||
SB.showDeleteButtonPlayerControls.style.display = "unset";
|
||||
}
|
||||
|
||||
function showDeleteButtonPlayerControls() {
|
||||
chrome.storage.sync.set({"hideDeleteButtonPlayerControls": false});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "changeVideoPlayerCochangeDeleteButtonPlayerControlsVisibilityntrolsVisibility",
|
||||
value: false
|
||||
});
|
||||
});
|
||||
|
||||
SB.hideDeleteButtonPlayerControls.style.display = "unset";
|
||||
SB.showDeleteButtonPlayerControls.style.display = "none";
|
||||
}
|
||||
|
||||
function disableSponsorViewTracking() {
|
||||
chrome.storage.sync.set({"trackViewCount": false});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "trackViewCount",
|
||||
value: false
|
||||
});
|
||||
});
|
||||
|
||||
SB.disableSponsorViewTracking.style.display = "none";
|
||||
SB.enableSponsorViewTracking.style.display = "unset";
|
||||
}
|
||||
|
||||
function enableSponsorViewTracking() {
|
||||
chrome.storage.sync.set({"trackViewCount": true});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "trackViewCount",
|
||||
value: true
|
||||
});
|
||||
});
|
||||
|
||||
SB.enableSponsorViewTracking.style.display = "none";
|
||||
SB.disableSponsorViewTracking.style.display = "unset";
|
||||
}
|
||||
|
||||
|
||||
function updateStartTimeChosen() {
|
||||
//update startTimeChosen letiable
|
||||
if (!startTimeChosen) {
|
||||
@@ -981,7 +814,7 @@ function runThePopup() {
|
||||
//set it to false
|
||||
function resetStartTimeChosen() {
|
||||
startTimeChosen = false;
|
||||
SB.sponsorStart.innerHTML = "SP_START";
|
||||
SB.sponsorStart.innerHTML = chrome.i18n.getMessage("sponsorStart");
|
||||
}
|
||||
|
||||
//hides and shows the submit times button when needed
|
||||
@@ -998,16 +831,13 @@ function runThePopup() {
|
||||
|
||||
//make the options div visible
|
||||
function openOptions() {
|
||||
document.getElementById("optionsButtonContainer").style.display = "none";
|
||||
document.getElementById("options").style.display = "unset";
|
||||
chrome.runtime.sendMessage({"message": "openConfig"});
|
||||
}
|
||||
|
||||
//make the options username setting option visible
|
||||
function setUsernameButton() {
|
||||
//get the userID
|
||||
chrome.storage.sync.get(["userID"], function(result) {
|
||||
//get username from the server
|
||||
sendRequestToServer("GET", "/api/getUsername?userID=" + result.userID, function (xmlhttp, error) {
|
||||
sendRequestToServer("GET", "/api/getUsername?userID=" + SB.config.userID, function (xmlhttp, error) {
|
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||
SB.usernameInput.value = JSON.parse(xmlhttp.responseText).userName;
|
||||
|
||||
@@ -1024,10 +854,9 @@ function runThePopup() {
|
||||
SB.usernameInput.style.display = "none";
|
||||
|
||||
SB.setUsernameStatusContainer.style.display = "unset";
|
||||
SB.setUsernameStatus.innerText = "Couldn't connect to server. Error code: " + xmlhttp.status;
|
||||
SB.setUsernameStatus.innerText = getErrorMessage(xmlhttp.status);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//submit the new username
|
||||
@@ -1037,8 +866,7 @@ function runThePopup() {
|
||||
SB.setUsernameStatus.innerText = "Loading...";
|
||||
|
||||
//get the userID
|
||||
chrome.storage.sync.get(["userID"], function(result) {
|
||||
sendRequestToServer("POST", "/api/setUsername?userID=" + result.userID + "&username=" + SB.usernameInput.value, function (xmlhttp, error) {
|
||||
sendRequestToServer("POST", "/api/setUsername?userID=" + SB.config.userID + "&username=" + SB.usernameInput.value, function (xmlhttp, error) {
|
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||
//submitted
|
||||
SB.submitUsername.style.display = "none";
|
||||
@@ -1046,24 +874,15 @@ function runThePopup() {
|
||||
|
||||
SB.setUsernameStatus.innerText = chrome.i18n.getMessage("success");
|
||||
} else if (xmlhttp.readyState == 4) {
|
||||
let errorMessage = "";
|
||||
|
||||
if([400, 429, 409, 502].includes(xmlhttp.status)) {
|
||||
errorMessage = chrome.i18n.getMessage(xmlhttp.status);
|
||||
} else {
|
||||
errorMessage = chrome.i18n.getMessage("connectionError") + xmlhttp.status;
|
||||
}
|
||||
|
||||
SB.setUsernameStatus.innerText = errorMessage;
|
||||
SB.setUsernameStatus.innerText = getErrorMessageI(xmlhttp.status);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
SB.setUsernameContainer.style.display = "none";
|
||||
SB.setUsername.style.display = "unset";
|
||||
}
|
||||
|
||||
|
||||
//this is not a YouTube video page
|
||||
function displayNoVideo() {
|
||||
document.getElementById("loadingIndicator").innerText = chrome.i18n.getMessage("noVideoID");
|
||||
@@ -1101,27 +920,21 @@ function runThePopup() {
|
||||
}, function(response) {
|
||||
if (response != undefined) {
|
||||
//see if it was a success or failure
|
||||
if (response.successType == 1) {
|
||||
//success
|
||||
if (response.successType == 1 || (response.successType == -1 && response.statusCode == 429)) {
|
||||
//success (treat rate limits as a success)
|
||||
addVoteMessage(chrome.i18n.getMessage("voted"), UUID)
|
||||
} else if (response.successType == 0) {
|
||||
//failure: duplicate vote
|
||||
addVoteMessage(chrome.i18n.getMessage("voteFail"), UUID)
|
||||
} else if (response.successType == -1) {
|
||||
if (response.statusCode == 502) {
|
||||
addVoteMessage(chrome.i18n.getMessage("serverDown"), UUID)
|
||||
} else {
|
||||
//failure: unknown error
|
||||
addVoteMessage(chrome.i18n.getMessage("connectionError") + response.statusCode, UUID)
|
||||
}
|
||||
addVoteMessage(getErrorMessage(response.statusCode), UUID)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function hideDiscordButton() {
|
||||
chrome.storage.sync.set({"hideDiscordLink": false});
|
||||
|
||||
SB.config.hideDiscordLink = true;
|
||||
SB.discordButtonContainer.style.display = "none";
|
||||
}
|
||||
|
||||
@@ -1150,8 +963,7 @@ function runThePopup() {
|
||||
{message: 'getChannelURL'},
|
||||
function(response) {
|
||||
//get whitelisted channels
|
||||
chrome.storage.sync.get(["whitelistedChannels"], function(result) {
|
||||
let whitelistedChannels = result.whitelistedChannels;
|
||||
let whitelistedChannels = SB.config.whitelistedChannels;
|
||||
if (whitelistedChannels == undefined) {
|
||||
whitelistedChannels = [];
|
||||
}
|
||||
@@ -1163,11 +975,11 @@ function runThePopup() {
|
||||
SB.whitelistChannel.style.display = "none";
|
||||
SB.unwhitelistChannel.style.display = "unset";
|
||||
|
||||
SB.downloadedSponsorMessageTimes.innerText = "Channel Whitelisted!";
|
||||
SB.downloadedSponsorMessageTimes.innerText = chrome.i18n.getMessage("channelWhitelisted");
|
||||
SB.downloadedSponsorMessageTimes.style.fontWeight = "bold";
|
||||
|
||||
//save this
|
||||
chrome.storage.sync.set({whitelistedChannels: whitelistedChannels});
|
||||
SB.config.whitelistedChannels = whitelistedChannels;
|
||||
|
||||
//send a message to the client
|
||||
chrome.tabs.query({
|
||||
@@ -1181,7 +993,6 @@ function runThePopup() {
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -1198,8 +1009,7 @@ function runThePopup() {
|
||||
{message: 'getChannelURL'},
|
||||
function(response) {
|
||||
//get whitelisted channels
|
||||
chrome.storage.sync.get(["whitelistedChannels"], function(result) {
|
||||
let whitelistedChannels = result.whitelistedChannels;
|
||||
let whitelistedChannels = SB.config.whitelistedChannels;
|
||||
if (whitelistedChannels == undefined) {
|
||||
whitelistedChannels = [];
|
||||
}
|
||||
@@ -1216,7 +1026,7 @@ function runThePopup() {
|
||||
SB.downloadedSponsorMessageTimes.style.fontWeight = "unset";
|
||||
|
||||
//save this
|
||||
chrome.storage.sync.set({whitelistedChannels: whitelistedChannels});
|
||||
SB.config.whitelistedChannels = whitelistedChannels;
|
||||
|
||||
//send a message to the client
|
||||
chrome.tabs.query({
|
||||
@@ -1230,12 +1040,29 @@ function runThePopup() {
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Should skipping be disabled (visuals stay)
|
||||
*/
|
||||
function toggleSkipping(disabled) {
|
||||
SB.config.disableSkipping = disabled;
|
||||
|
||||
let hiddenButton = SB.disableSkipping;
|
||||
let shownButton = SB.enableSkipping;
|
||||
|
||||
if (!disabled) {
|
||||
hiddenButton = SB.enableSkipping;
|
||||
shownButton = SB.disableSkipping;
|
||||
}
|
||||
|
||||
shownButton.style.display = "unset";
|
||||
hiddenButton.style.display = "none";
|
||||
}
|
||||
|
||||
//converts time in seconds to minutes
|
||||
function getTimeInMinutes(seconds) {
|
||||
let minutes = Math.floor(seconds / 60);
|
||||
@@ -1272,14 +1099,25 @@ function runThePopup() {
|
||||
//submit this request
|
||||
xmlhttp.send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts time in hours to 5h 25.1
|
||||
* If less than 1 hour, just returns minutes
|
||||
*
|
||||
* @param {float} seconds
|
||||
* @returns {string}
|
||||
*/
|
||||
function getFormattedHours(minues) {
|
||||
let hours = Math.floor(minues / 60);
|
||||
return (hours > 0 ? hours + "h " : "") + (minues % 60).toFixed(1);
|
||||
}
|
||||
|
||||
//end of function
|
||||
}
|
||||
|
||||
if (chrome.tabs != undefined) {
|
||||
//add the width restriction (because Firefox)
|
||||
document.getElementById("sponorBlockStyleSheet").sheet.insertRule('.popupBody { width: 300 }', 0);
|
||||
|
||||
document.getElementById("sponorBlockStyleSheet").sheet.insertRule('.popupBody { width: 325 }', 0);
|
||||
//this means it is actually opened in the popup
|
||||
runThePopup();
|
||||
}
|
||||
|
||||
276
utils.js
276
utils.js
@@ -1,37 +1,271 @@
|
||||
var isBackgroundScript = false;
|
||||
var onInvidious = false;
|
||||
|
||||
// Function that can be used to wait for a condition before returning
|
||||
async function wait(condition, timeout = 5000, check = 100) {
|
||||
return await new Promise((resolve, reject) => {
|
||||
setTimeout(() => reject("TIMEOUT"), timeout);
|
||||
|
||||
let intervalCheck = () => {
|
||||
let result = condition();
|
||||
if (result !== false) {
|
||||
resolve(result);
|
||||
clearInterval(interval);
|
||||
};
|
||||
};
|
||||
|
||||
let interval = setInterval(intervalCheck, check);
|
||||
|
||||
//run the check once first, this speeds it up a lot
|
||||
intervalCheck();
|
||||
});
|
||||
}
|
||||
|
||||
function getYouTubeVideoID(url) {
|
||||
// For YouTube TV support
|
||||
if(url.startsWith("https://www.youtube.com/tv#/")) url = url.replace("#", "");
|
||||
|
||||
//Attempt to parse url
|
||||
let urlObject = null;
|
||||
try {
|
||||
urlObject = new URL(url);
|
||||
} catch (e) {
|
||||
console.error("[SB] Unable to parse URL: " + url);
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check if valid hostname
|
||||
if (SB.config && SB.config.invidiousInstances.includes(urlObject.host)) {
|
||||
onInvidious = true;
|
||||
} else if (!["www.youtube.com", "www.youtube-nocookie.com"].includes(urlObject.host)) {
|
||||
if (!SB.config) {
|
||||
// Call this later, in case this is an Invidious tab
|
||||
wait(() => SB.config !== undefined).then(() => videoIDChange(getYouTubeVideoID(url)));
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
//Check if valid hostname
|
||||
if(!["www.youtube.com","www.youtube-nocookie.com"].includes(urlObject.host)) return false;
|
||||
|
||||
|
||||
//Get ID from searchParam
|
||||
if ((urlObject.pathname == "/watch" || urlObject.pathname == "/watch/") && urlObject.searchParams.has("v")) {
|
||||
id = urlObject.searchParams.get("v");
|
||||
return id.length == 11 ? id : false;
|
||||
if (urlObject.searchParams.has("v") && ["/watch", "/watch/"].includes(urlObject.pathname) || urlObject.pathname.startsWith("/tv/watch")) {
|
||||
id = urlObject.searchParams.get("v");
|
||||
return id.length == 11 ? id : false;
|
||||
} else if (urlObject.pathname.startsWith("/embed/")) {
|
||||
try {
|
||||
return urlObject.pathname.substr(7, 11);
|
||||
} catch (e) {
|
||||
console.error("[SB] Video ID not valid for " + url);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return urlObject.pathname.substr(7, 11);
|
||||
} catch (e) {
|
||||
console.error("[SB] Video ID not valid for " + url);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks for the optional permissions required for all extra sites.
|
||||
* It also starts the content script registrations.
|
||||
*
|
||||
* For now, it is just SB.config.invidiousInstances.
|
||||
*
|
||||
* @param {CallableFunction} callback
|
||||
*/
|
||||
function setupExtraSitePermissions(callback) {
|
||||
// Request permission
|
||||
let permissions = ["declarativeContent"];
|
||||
if (isFirefox()) permissions = [];
|
||||
|
||||
chrome.permissions.request({
|
||||
origins: getInvidiousInstancesRegex(),
|
||||
permissions: permissions
|
||||
}, async function (granted) {
|
||||
if (granted) {
|
||||
setupExtraSiteContentScripts();
|
||||
} else {
|
||||
removeExtraSiteRegistration();
|
||||
}
|
||||
|
||||
callback(granted);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the content scripts for the extra sites.
|
||||
* Will use a different method depending on the browser.
|
||||
* This is called by setupExtraSitePermissions().
|
||||
*
|
||||
* For now, it is just SB.config.invidiousInstances.
|
||||
*/
|
||||
function setupExtraSiteContentScripts() {
|
||||
let js = [
|
||||
"config.js",
|
||||
"SB.js",
|
||||
"utils/previewBar.js",
|
||||
"utils/skipNotice.js",
|
||||
"utils.js",
|
||||
"content.js",
|
||||
"popup.js"
|
||||
];
|
||||
let css = [
|
||||
"content.css",
|
||||
"./libs/Source+Sans+Pro.css",
|
||||
"popup.css"
|
||||
];
|
||||
|
||||
if (isFirefox()) {
|
||||
let firefoxJS = [];
|
||||
for (const file of js) {
|
||||
firefoxJS.push({file});
|
||||
}
|
||||
let firefoxCSS = [];
|
||||
for (const file of css) {
|
||||
firefoxCSS.push({file});
|
||||
}
|
||||
|
||||
let registration = {
|
||||
message: "registerContentScript",
|
||||
id: "invidious",
|
||||
allFrames: true,
|
||||
js: firefoxJS,
|
||||
css: firefoxCSS,
|
||||
matches: getInvidiousInstancesRegex()
|
||||
};
|
||||
|
||||
if (isBackgroundScript) {
|
||||
registerFirefoxContentScript(registration);
|
||||
} else {
|
||||
chrome.runtime.sendMessage(registration);
|
||||
}
|
||||
} else {
|
||||
chrome.declarativeContent.onPageChanged.removeRules(["invidious"], function() {
|
||||
let conditions = [];
|
||||
for (const regex of getInvidiousInstancesRegex()) {
|
||||
conditions.push(new chrome.declarativeContent.PageStateMatcher({
|
||||
pageUrl: { urlMatches: regex }
|
||||
}));
|
||||
}
|
||||
|
||||
// Add page rule
|
||||
let rule = {
|
||||
id: "invidious",
|
||||
conditions,
|
||||
actions: [new chrome.declarativeContent.RequestContentScript({
|
||||
allFrames: true,
|
||||
js,
|
||||
css
|
||||
})]
|
||||
};
|
||||
|
||||
chrome.declarativeContent.onPageChanged.addRules([rule]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//returns the start time of the video if there was one specified (ex. ?t=5s)
|
||||
function getYouTubeVideoStartTime(url) {
|
||||
let searchParams = new URL(url).searchParams;
|
||||
let startTime = searchParams.get("t");
|
||||
if (startTime == null) {
|
||||
startTime = searchParams.get("time_continue");
|
||||
}
|
||||
/**
|
||||
* Removes the permission and content script registration.
|
||||
*/
|
||||
function removeExtraSiteRegistration() {
|
||||
if (isFirefox()) {
|
||||
let id = "invidious";
|
||||
|
||||
return startTime;
|
||||
if (isBackgroundScript) {
|
||||
if (contentScriptRegistrations[id]) {
|
||||
contentScriptRegistrations[id].unregister();
|
||||
delete contentScriptRegistrations[id];
|
||||
}
|
||||
} else {
|
||||
chrome.runtime.sendMessage({
|
||||
message: "unregisterContentScript",
|
||||
id: id
|
||||
});
|
||||
}
|
||||
} else {
|
||||
chrome.declarativeContent.onPageChanged.removeRules(["invidious"]);
|
||||
}
|
||||
|
||||
chrome.permissions.remove({
|
||||
origins: getInvidiousInstancesRegex()
|
||||
});
|
||||
}
|
||||
|
||||
function localizeHtmlPage() {
|
||||
//Localize by replacing __MSG_***__ meta tags
|
||||
var objects = document.getElementsByClassName("sponsorBlockPageBody")[0].children;
|
||||
for (var j = 0; j < objects.length; j++) {
|
||||
var obj = objects[j];
|
||||
|
||||
let localizedMessage = getLocalizedMessage(obj.innerHTML.toString());
|
||||
if (localizedMessage) obj.innerHTML = localizedMessage;
|
||||
}
|
||||
}
|
||||
|
||||
function getLocalizedMessage(text) {
|
||||
var valNewH = text.replace(/__MSG_(\w+)__/g, function(match, v1) {
|
||||
return v1 ? chrome.i18n.getMessage(v1) : "";
|
||||
});
|
||||
|
||||
if(valNewH != text) {
|
||||
return valNewH;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {String[]} Invidious Instances in regex form
|
||||
*/
|
||||
function getInvidiousInstancesRegex() {
|
||||
var invidiousInstancesRegex = [];
|
||||
for (const url of SB.config.invidiousInstances) {
|
||||
invidiousInstancesRegex.push("https://*." + url + "/*");
|
||||
invidiousInstancesRegex.push("http://*." + url + "/*");
|
||||
}
|
||||
|
||||
return invidiousInstancesRegex;
|
||||
}
|
||||
|
||||
function generateUserID(length = 36) {
|
||||
let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
let result = "";
|
||||
if (window.crypto && window.crypto.getRandomValues) {
|
||||
values = new Uint32Array(length);
|
||||
window.crypto.getRandomValues(values);
|
||||
for (i = 0; i < length; i++) {
|
||||
result += charset[values[i] % charset.length];
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
for (let i = 0; i < length; i++) {
|
||||
result += charset[Math.floor(Math.random() * charset.length)];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the error message in a nice string
|
||||
*
|
||||
* @param {int} statusCode
|
||||
* @returns {string} errorMessage
|
||||
*/
|
||||
function getErrorMessage(statusCode) {
|
||||
let errorMessage = "";
|
||||
|
||||
if([400, 429, 409, 502, 0].includes(statusCode)) {
|
||||
//treat them the same
|
||||
if (statusCode == 503) statusCode = 502;
|
||||
|
||||
errorMessage = chrome.i18n.getMessage(statusCode + "") + " " + chrome.i18n.getMessage("errorCode") + statusCode
|
||||
+ "\n\n" + chrome.i18n.getMessage("statusReminder");
|
||||
} else {
|
||||
errorMessage = chrome.i18n.getMessage("connectionError") + statusCode;
|
||||
}
|
||||
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this Firefox (web-extensions)
|
||||
*/
|
||||
function isFirefox() {
|
||||
return typeof(browser) !== "undefined";
|
||||
}
|
||||
|
||||
@@ -13,6 +13,10 @@ let barTypes = {
|
||||
"sponsor": {
|
||||
color: "#00d400",
|
||||
opacity: "0.5"
|
||||
},
|
||||
"previewSponsor": {
|
||||
color: "#0000d4",
|
||||
opacity: "0.5"
|
||||
}
|
||||
};
|
||||
|
||||
@@ -55,6 +59,8 @@ class PreviewBar {
|
||||
duration = Math.floor(duration * 100) / 100;
|
||||
let width;
|
||||
for (let i = 0; i < timestamps.length; i++) {
|
||||
if (types[i] == null) continue;
|
||||
|
||||
width = (timestamps[i][1] - timestamps[i][0]) / duration * 100;
|
||||
width = Math.floor(width * 100) / 100;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
//The notice that tells the user that a sponsor was just skipped
|
||||
/**
|
||||
* The notice that tells the user that a sponsor was just skipped
|
||||
*/
|
||||
class SkipNotice {
|
||||
constructor(parent, UUID) {
|
||||
/**
|
||||
* @param {HTMLElement} parent
|
||||
* @param {String} UUID
|
||||
* @param {String} noticeTitle
|
||||
* @param {boolean} manualSkip
|
||||
*/
|
||||
constructor(parent, UUID, manualSkip = false) {
|
||||
this.parent = parent;
|
||||
this.UUID = UUID;
|
||||
this.manualSkip = manualSkip;
|
||||
|
||||
let noticeTitle = chrome.i18n.getMessage("noticeTitle");
|
||||
|
||||
if (manualSkip) {
|
||||
noticeTitle = chrome.i18n.getMessage("noticeTitleNotSkipped");
|
||||
}
|
||||
|
||||
this.maxCountdownTime = () => 4;
|
||||
//the countdown until this notice closes
|
||||
@@ -54,7 +69,7 @@ class SkipNotice {
|
||||
noticeMessage.id = "sponsorSkipMessage" + this.idSuffix;
|
||||
noticeMessage.classList.add("sponsorSkipMessage");
|
||||
noticeMessage.classList.add("sponsorSkipObject");
|
||||
noticeMessage.innerText = chrome.i18n.getMessage("noticeTitle");
|
||||
noticeMessage.innerText = noticeTitle;
|
||||
|
||||
//create the first column
|
||||
logoColumn.appendChild(logoElement);
|
||||
@@ -136,7 +151,10 @@ class SkipNotice {
|
||||
dontShowAgainButton.className = "sponsorSkipObject sponsorSkipNoticeButton sponsorSkipNoticeRightButton";
|
||||
dontShowAgainButton.addEventListener("click", dontShowNoticeAgain);
|
||||
|
||||
dontshowContainer.appendChild(dontShowAgainButton);
|
||||
// Don't let them hide it if manually skipping
|
||||
if (!this.manualSkip) {
|
||||
dontshowContainer.appendChild(dontShowAgainButton);
|
||||
}
|
||||
|
||||
//add to row
|
||||
secondRow.appendChild(voteButtonsContainer);
|
||||
@@ -148,7 +166,7 @@ class SkipNotice {
|
||||
noticeElement.appendChild(secondRow);
|
||||
|
||||
//get reference node
|
||||
let referenceNode = document.getElementById("movie_player");
|
||||
let referenceNode = document.getElementById("movie_player") || document.querySelector("#player-container .video-js");
|
||||
if (referenceNode == null) {
|
||||
//for embeds
|
||||
let player = document.getElementById("player");
|
||||
@@ -165,6 +183,10 @@ class SkipNotice {
|
||||
|
||||
referenceNode.prepend(noticeElement);
|
||||
|
||||
if (manualSkip) {
|
||||
this.unskippedMode(chrome.i18n.getMessage("skip"));
|
||||
}
|
||||
|
||||
this.startCountdown();
|
||||
}
|
||||
|
||||
@@ -228,10 +250,13 @@ class SkipNotice {
|
||||
unskip() {
|
||||
unskipSponsorTime(this.UUID);
|
||||
|
||||
this.unskippedMode(chrome.i18n.getMessage("reskip"));
|
||||
}
|
||||
|
||||
/** Sets up notice to be not skipped yet */
|
||||
unskippedMode(buttonText) {
|
||||
//change unskip button to a reskip button
|
||||
let unskipButton = document.getElementById("sponsorSkipUnskipButton" + this.idSuffix);
|
||||
unskipButton.innerText = chrome.i18n.getMessage("reskip");
|
||||
unskipButton.removeEventListener("click", this.unskipCallback);
|
||||
let unskipButton = this.changeUnskipButton(buttonText);
|
||||
|
||||
//setup new callback
|
||||
this.unskipCallback = this.reskip.bind(this);
|
||||
@@ -252,10 +277,8 @@ class SkipNotice {
|
||||
reskip() {
|
||||
reskipSponsorTime(this.UUID);
|
||||
|
||||
//change unskip button to a reskip button
|
||||
let unskipButton = document.getElementById("sponsorSkipUnskipButton" + this.idSuffix);
|
||||
unskipButton.innerText = chrome.i18n.getMessage("unskip");
|
||||
unskipButton.removeEventListener("click", this.unskipCallback);
|
||||
//change reskip button to a unskip button
|
||||
let unskipButton = this.changeUnskipButton(chrome.i18n.getMessage("unskip"));
|
||||
|
||||
//setup new callback
|
||||
this.unskipCallback = this.unskip.bind(this);
|
||||
@@ -265,6 +288,27 @@ class SkipNotice {
|
||||
this.maxCountdownTime = () => 4;
|
||||
this.countdownTime = this.maxCountdownTime();
|
||||
this.updateTimerDisplay();
|
||||
|
||||
// See if the title should be changed
|
||||
if (this.manualSkip) {
|
||||
this.changeNoticeTitle(chrome.i18n.getMessage("noticeTitle"));
|
||||
|
||||
vote(1, this.UUID, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the text on the reskip button
|
||||
*
|
||||
* @param {string} text
|
||||
* @returns {HTMLElement} unskipButton
|
||||
*/
|
||||
changeUnskipButton(text) {
|
||||
let unskipButton = document.getElementById("sponsorSkipUnskipButton" + this.idSuffix);
|
||||
unskipButton.innerText = text;
|
||||
unskipButton.removeEventListener("click", this.unskipCallback);
|
||||
|
||||
return unskipButton;
|
||||
}
|
||||
|
||||
afterDownvote() {
|
||||
@@ -280,35 +324,49 @@ class SkipNotice {
|
||||
//add this as a hidden sponsorTime
|
||||
hiddenSponsorTimes.push(i);
|
||||
|
||||
let sponsorTimesLeft = sponsorTimes.slice();
|
||||
for (let j = 0; j < hiddenSponsorTimes.length; j++) {
|
||||
//remove this sponsor time
|
||||
sponsorTimesLeft.splice(hiddenSponsorTimes[j], 1);
|
||||
}
|
||||
|
||||
//update the preview
|
||||
previewBar.set(sponsorTimesLeft, [], v.duration);
|
||||
|
||||
updatePreviewBar();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
changeNoticeTitle(title) {
|
||||
let noticeElement = document.getElementById("sponsorSkipMessage" + this.idSuffix);
|
||||
|
||||
noticeElement.innerText = title;
|
||||
}
|
||||
|
||||
addNoticeInfoMessage(message) {
|
||||
addNoticeInfoMessage(message, message2) {
|
||||
let previousInfoMessage = document.getElementById("sponsorTimesInfoMessage" + this.idSuffix);
|
||||
if (previousInfoMessage != null) {
|
||||
//remove it
|
||||
document.getElementById("sponsorSkipNotice" + this.idSuffix).removeChild(previousInfoMessage);
|
||||
}
|
||||
|
||||
let previousInfoMessage2 = document.getElementById("sponsorTimesInfoMessage" + this.idSuffix + "2");
|
||||
if (previousInfoMessage2 != null) {
|
||||
//remove it
|
||||
document.getElementById("sponsorSkipNotice" + this.idSuffix).removeChild(previousInfoMessage2);
|
||||
}
|
||||
|
||||
//add info
|
||||
let thanksForVotingText = document.createElement("p");
|
||||
thanksForVotingText.id = "sponsorTimesInfoMessage" + this.idSuffix;
|
||||
thanksForVotingText.className = "sponsorTimesInfoMessage";
|
||||
thanksForVotingText.innerText = message;
|
||||
|
||||
|
||||
//add element to div
|
||||
document.getElementById("sponsorSkipNotice" + this.idSuffix).insertBefore(thanksForVotingText, document.getElementById("sponsorSkipNoticeSpacer" + this.idSuffix));
|
||||
|
||||
if (message2 !== undefined) {
|
||||
let thanksForVotingText2 = document.createElement("p");
|
||||
thanksForVotingText2.id = "sponsorTimesInfoMessage" + this.idSuffix + "2";
|
||||
thanksForVotingText2.className = "sponsorTimesInfoMessage";
|
||||
thanksForVotingText2.innerText = message2;
|
||||
|
||||
//add element to div
|
||||
document.getElementById("sponsorSkipNotice" + this.idSuffix).insertBefore(thanksForVotingText2, document.getElementById("sponsorSkipNoticeSpacer" + this.idSuffix));
|
||||
}
|
||||
}
|
||||
|
||||
resetNoticeInfoMessage() {
|
||||
@@ -337,7 +395,7 @@ class SkipNotice {
|
||||
thanksForVotingText.id = "sponsorTimesVoteButtonInfoMessage" + this.idSuffix;
|
||||
thanksForVotingText.className = "sponsorTimesInfoMessage sponsorTimesVoteButtonMessage";
|
||||
thanksForVotingText.innerText = message;
|
||||
|
||||
|
||||
//add element to div
|
||||
document.getElementById("sponsorSkipNoticeSecondRow" + this.idSuffix).prepend(thanksForVotingText);
|
||||
}
|
||||
@@ -348,17 +406,23 @@ class SkipNotice {
|
||||
//remove it
|
||||
document.getElementById("sponsorSkipNoticeSecondRow" + this.idSuffix).removeChild(previousInfoMessage);
|
||||
}
|
||||
|
||||
|
||||
//show button again
|
||||
document.getElementById("sponsorTimesDownvoteButtonsContainer" + this.idSuffix).style.removeProperty("display");
|
||||
}
|
||||
|
||||
//close this notice
|
||||
close() {
|
||||
//reset message
|
||||
this.resetNoticeInfoMessage();
|
||||
|
||||
let notice = document.getElementById("sponsorSkipNotice" + this.idSuffix);
|
||||
if (notice != null) {
|
||||
notice.remove();
|
||||
}
|
||||
|
||||
//remove setInterval
|
||||
if (this.countdownInterval != -1) clearInterval(this.countdownInterval);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user