Compare commits

...

857 Commits

Author SHA1 Message Date
Ajay Ramachandran
ba575f6b8d Merge pull request #296 from ajayyy/experimental
Prevent manual skips from triggering a view and improved skip schedule for manual skip
2020-03-09 18:20:11 -04:00
Ajay Ramachandran
ff9b2338e0 Fixed scheduling being wrong when manual skip is enabled 2020-03-09 18:12:05 -04:00
Ajay Ramachandran
d2bb4b38e3 Increased version number 2020-03-09 18:07:29 -04:00
Ajay Ramachandran
760c08dd0c Prevent manual skips from triggering a view 2020-03-09 18:07:06 -04:00
Ajay Ramachandran
50517eb462 Switched upload to release action 2020-03-09 11:15:29 -04:00
Ajay Ramachandran
e77425c21e Merge pull request #294 from ajayyy/experimental
Another potential fix for zero second sponsor freezing
2020-03-09 11:04:26 -04:00
Ajay Ramachandran
f63abb053d Revert to only using workflows 2020-03-09 11:02:14 -04:00
Ajay Ramachandran
7b5703aa04 Fixed action format 2020-03-09 10:56:06 -04:00
Ajay Ramachandran
d641066312 Checkout in CI 2020-03-09 10:52:43 -04:00
Ajay Ramachandran
44ca8d47d8 Moved CI into the right place 2020-03-09 10:51:26 -04:00
Ajay Ramachandran
d5f41bf4ad Fixed CI 2020-03-09 10:49:50 -04:00
Ajay Ramachandran
73e8926444 Start skip schedule from skip time to prevent slow video updates from breaking it. 2020-03-09 10:43:13 -04:00
Ajay Ramachandran
5ad694af65 Increase version number 2020-03-08 23:26:46 -04:00
Ajay Ramachandran
d7f7acb219 Fixed release action 2020-03-08 23:20:41 -04:00
Ajay Ramachandran
b4be51333a Merge pull request #293 from ajayyy/experimental
Fixed double sponsor skip for zero second sponsors
2020-03-08 23:17:48 -04:00
Ajay Ramachandran
ae94811a00 Increase version number 2020-03-08 23:16:50 -04:00
Ajay Ramachandran
a484f2f2cc Fixed double sponsor skip for zero second sponsors 2020-03-08 23:16:09 -04:00
Ajay Ramachandran
9cce4e734d Merge pull request #292 from grishka/russian
Fix Russian translation and add missing strings
2020-03-07 12:34:48 -05:00
Grishka
3c63644213 fix 2020-03-07 13:45:56 +03:00
Grishka
ad25bc34de Add missing Russian strings 2020-03-07 13:37:58 +03:00
Ajay Ramachandran
0241e15691 Only seek if the video is not paused 2020-02-28 15:06:08 -05:00
Ajay Ramachandran
af9a6b8a84 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into experimental 2020-02-28 14:09:21 -05:00
Ajay Ramachandran
329b188435 Checkout before using other CI 2020-02-27 22:23:33 -05:00
Ajay Ramachandran
2e49bb73c5 Merge pull request #290 from ajayyy/experimental
Potentially fixed zero second skip spam
2020-02-27 22:21:33 -05:00
Ajay Ramachandran
5158020293 Potentially fixed zero second skip spam 2020-02-27 22:20:30 -05:00
Ajay Ramachandran
feaf80ad1e Merge pull request #289 from Joe-Dowd/messages-typo
Typo in en messages locale "skipeed -> skipped"
2020-02-25 15:14:01 -05:00
Joe Dowd
7fbd89159e Typo in en messages locale skipped 2020-02-25 18:25:28 +00:00
Ajay Ramachandran
716861da18 Fixed beta builds 2020-02-23 20:49:17 -05:00
Ajay Ramachandran
d0a34d423c Fix release CI 2020-02-23 20:42:12 -05:00
Ajay Ramachandran
adfba72f19 Merge pull request #286 from ajayyy/experimental
Mobile fix + mobile update notice
2020-02-23 20:40:48 -05:00
Ajay Ramachandran
f00337c376 Increase version number. 2020-02-23 20:39:29 -05:00
Ajay Ramachandran
737a023b65 Added mobile support message. 2020-02-23 20:39:13 -05:00
Ajay Ramachandran
5551344355 Fixed mobile notice zoom on Firefox 2020-02-23 16:14:18 -05:00
Ajay Ramachandran
07f64382fb Merge pull request #285 from cherryblossom000/patch-1
Fix "0 sponsor" in popup
2020-02-23 11:21:21 -05:00
Ajay Ramachandran
1c7cde2a19 Changed to !== 2020-02-23 11:20:21 -05:00
cherryblossom
8510a7f3d8 Fix popup saying "0 sponsor" 2020-02-23 17:03:18 +11:00
Ajay Ramachandran
db60b11a17 Merge pull request #284 from ajayyy/experimental
CI Improvements
2020-02-20 15:38:35 -05:00
Ajay Ramachandran
6a212b762a Fixed invalid release workflow 2020-02-20 12:21:30 -05:00
Ajay Ramachandran
c8ec2922cf Added makedir to CI 2020-02-20 12:17:51 -05:00
Ajay Ramachandran
b629b7d333 Added basic release workflow 2020-02-20 12:14:01 -05:00
Ajay Ramachandran
514a8b62d6 Added beta build to CI 2020-02-20 11:39:06 -05:00
Ajay Ramachandran
cd11618a5d Merge pull request #283 from ajayyy/experimental
New skipping mechanism fixes
2020-02-20 11:25:32 -05:00
Ajay Ramachandran
8be3cb157a Increased version number 2020-02-20 11:23:44 -05:00
Ajay Ramachandran
4ca57cc025 Fixed preview sponsors not skipping when only they are there. 2020-02-19 13:45:00 -05:00
Ajay Ramachandran
397bcc94c5 Remove redundant code 2020-02-19 13:35:05 -05:00
Ajay Ramachandran
8b28bccfd7 Run dev now uses dev build. 2020-02-19 12:57:22 -05:00
Ajay Ramachandran
c6107057d9 Firefox dev environment now loads Firefox uBlock Origin 2020-02-19 12:54:58 -05:00
Ajay Ramachandran
ab2a9530e9 Sped up zero second sponsors a tiny bit 2020-02-19 12:41:22 -05:00
Ajay Ramachandran
bfc771bd99 Removed unused variables 2020-02-19 12:37:39 -05:00
Ajay Ramachandran
e75e588755 Sped up direct links a tiny bit. 2020-02-19 12:37:17 -05:00
Ajay Ramachandran
0266bb49ca Fixed typo 2020-02-19 12:35:10 -05:00
Ajay Ramachandran
9e693fd555 Update README.md 2020-02-19 12:33:48 -05:00
Ajay Ramachandran
1f30b9ec84 Merge pull request #280 from ajayyy/mobile-youtube
Mobile YouTube support + Precise skipping
2020-02-19 11:40:07 -05:00
Ajay Ramachandran
50862e3c03 Increased version number 2020-02-19 11:25:14 -05:00
Ajay Ramachandran
20e90bbc34 Fixed schedule not updating when new sponsors arrive 2020-02-19 00:54:30 -05:00
Ajay Ramachandran
2e212e6d10 Improved mobile preview bar 2020-02-19 00:14:08 -05:00
Ajay Ramachandran
2039bfa081 Made buttons on mobile not close the menu. 2020-02-19 00:10:05 -05:00
Ajay Ramachandran
7dc8a99247 Added button support to mobile. 2020-02-19 00:00:22 -05:00
Ajay Ramachandran
1b25ea7f95 Shrunk notice on mobile 2020-02-18 19:29:20 -05:00
Ajay Ramachandran
1869382166 Fixed popup issues. 2020-02-18 19:03:34 -05:00
Ajay Ramachandran
d58cd639c7 Added zero second preview sponsors. 2020-02-18 18:45:33 -05:00
Ajay Ramachandran
6cd2d4cf83 Added back whitelist support 2020-02-18 18:44:06 -05:00
Ajay Ramachandran
b681f5abd9 Added support for preview sponsors in new skipping method. 2020-02-18 18:43:45 -05:00
Ajay Ramachandran
5b2a0feccf Switched to new skipping mechanic 2020-02-18 18:29:02 -05:00
Ajay Ramachandran
cd58f6bc73 Skip notice improvement. 2020-02-18 15:57:40 -05:00
Ajay Ramachandran
aeabf806ac Added duration change listener check to prevent mid-video zero second skips.
Sometimes the video gets reset to zero seconds for a few milliseconds, this should not trigger a skip.

Resolves https://github.com/ajayyy/SponsorBlock/issues/183
2020-02-18 15:03:55 -05:00
Ajay Ramachandran
af7ba31c2f Remove logging. 2020-02-18 14:40:40 -05:00
Ajay Ramachandran
5b962b1b9d Merge pull request #281 from ajayyy/experimental
Rename CI artifacts
2020-02-17 15:24:49 -05:00
Ajay Ramachandran
219a7ba8c3 Added preview bar to mobile 2020-02-17 15:10:50 -05:00
Ajay Ramachandran
933babb4e6 Added mobile YouTube site to the whitelist. 2020-02-17 11:32:00 -05:00
Ajay Ramachandran
023ba2e051 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into experimental 2020-02-17 11:24:36 -05:00
Ajay Ramachandran
1c833a8b1d Rename CI artifacts. 2020-02-11 21:04:41 -05:00
Ajay Ramachandran
7143d7532d Increase version number 2020-02-11 21:01:35 -05:00
Ajay Ramachandran
1f10bdf593 Merge pull request #279 from CommanderRoot/patch-1
Retain decimals in seconds value when editing sponsor times
2020-02-11 20:33:04 -05:00
CommanderRoot
3b543916ff Retain decimals in seconds value 2020-02-12 02:24:03 +01:00
Ajay Ramachandran
c4da85340a Merge pull request #277 from ajayyy/experimental
Fixed regex to support Firefox
2020-02-11 14:10:47 -05:00
Ajay Ramachandran
ec59c7e0f9 Increase version number. 2020-02-11 14:10:11 -05:00
Ajay Ramachandran
2454cd9a39 Fixed regex to support Firefox. 2020-02-11 12:29:19 -05:00
Ajay Ramachandran
c19e2bea29 Merge pull request #274 from ajayyy/experimental
Various fixes
2020-02-10 22:35:54 -05:00
Ajay Ramachandran
2f2c1ad49b Increased version number. 2020-02-10 22:32:15 -05:00
Ajay Ramachandran
657aff2167 Removed use of Invidious API.
Resolves https://github.com/ajayyy/SponsorBlock/issues/189.
2020-02-10 22:27:54 -05:00
Ajay Ramachandran
2450457fe5 Fixed close button on dark theme.
Resolves https://github.com/ajayyy/SponsorBlock/issues/196
2020-02-10 21:54:11 -05:00
Ajay Ramachandran
ba9e42e6f0 Forced auto skip if previewing sponsor.
Resolves https://github.com/ajayyy/SponsorBlock/issues/222
2020-02-10 21:49:17 -05:00
Ajay Ramachandran
f05d80523b Made it unpause when previewing a sponsor.
Resolves https://github.com/ajayyy/SponsorBlock/issues/222
2020-02-10 21:39:39 -05:00
Ajay Ramachandran
d2779aba86 Fix editing not adding numbers.
Resolves https://github.com/ajayyy/SponsorBlock/issues/273.
2020-02-10 18:03:09 -05:00
Ajay Ramachandran
852912a42b Fixed inlines sponsor popup.
Fixes https://github.com/ajayyy/SponsorBlock/issues/272
2020-02-10 17:12:52 -05:00
Ajay Ramachandran
45e0f87f9f Reformatted manifest. 2020-02-09 11:14:40 -05:00
Ajay Ramachandran
79b02c7ae7 Merge pull request #269 from ajayyy/experimental
Fixed Firefox recursion issue
2020-02-09 10:36:20 -05:00
Ajay Ramachandran
cfb902180d Increased version number. 2020-02-09 10:35:32 -05:00
Ajay Ramachandran
1753c05686 Fix Firefox infinite recursion issue. 2020-02-09 10:34:18 -05:00
Ajay Ramachandran
c76d2c9a95 Merge pull request #266 from ajayyy/experimental
Options page improvements + Preview sponsors
2020-02-08 23:30:12 -05:00
Ajay Ramachandran
00117bdfac Increase version number. 2020-02-08 23:29:09 -05:00
Ajay Ramachandran
40cddbf8ee Disabling auto skip now enables the notice. 2020-02-08 23:28:41 -05:00
Ajay Ramachandran
9026044528 Fixed preview sponsor times not turning into actual ones upon submission. 2020-02-08 23:16:44 -05:00
Ajay Ramachandran
50f293d783 Added better server address trimming. 2020-02-08 23:01:28 -05:00
Ajay Ramachandran
2b558c43bd Removed subdomain requirement. 2020-02-08 22:55:59 -05:00
Ajay Ramachandran
22cc51734f Merge pull request #264 from ajayyy/privacy-confirm
Added privacy confirmation for unlisted videos
2020-02-08 22:45:22 -05:00
Ajay Ramachandran
cd5adc1b82 Merge pull request #265 from ajayyy/typescript
Issue fixing
2020-02-08 22:44:47 -05:00
Ajay Ramachandran
b7e83a0efe Added unlisted check option.
https://github.com/ajayyy/SponsorBlock/pull/224

Co-authored-by: OfficialNoob <OfficialNoob@users.noreply.github.com>
2020-02-08 22:43:27 -05:00
Ajay Ramachandran
6159605afd Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into typescript
# Conflicts:
#	public/_locales/en/messages.json
#	src/config.ts
2020-02-08 22:19:07 -05:00
Ajay Ramachandran
ceae02426d Merge pull request #262 from Joe-Dowd/customServerAddress
Add custom server address
2020-02-08 22:18:07 -05:00
Ajay Ramachandran
51d2886f70 Seperated show upload button option from info button. 2020-02-08 22:18:03 -05:00
Ajay Ramachandran
c2eb973a28 Fixed centering and added some more notes to the help page. 2020-02-08 22:13:36 -05:00
Ajay Ramachandran
f8532d39eb Improved invidious warning on the help page. 2020-02-08 22:07:51 -05:00
Ajay Ramachandran
c2be1ee6d4 Added reset button to text change. 2020-02-08 22:03:45 -05:00
Ajay Ramachandran
1735cdb45d Added server address input validation. 2020-02-08 21:58:50 -05:00
Ajay Ramachandran
be6cd62fbe Rename string change option to more fitting name. 2020-02-08 21:42:15 -05:00
Ajay Ramachandran
cfe91f6280 Changed order of options. 2020-02-08 21:34:26 -05:00
Ajay Ramachandran
4e7bfa5ed3 Changed server address config name 2020-02-08 21:32:46 -05:00
Ajay Ramachandran
6f03c68fdc Change the way server address defaults are handled. 2020-02-08 21:30:57 -05:00
Ajay Ramachandran
62653705ff Improved custom instance message 2020-02-08 21:27:55 -05:00
Ajay Ramachandran
3791c5c78b Fixed JSON conversion iterator 2020-02-08 20:05:31 -05:00
Joe Dowd
6bd22896b9 Merged Lartza/min-duration 2020-02-09 01:02:40 +00:00
Ajay Ramachandran
ea4331e4b1 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into typescript
# Conflicts:
#	src/config.ts
2020-02-08 19:31:18 -05:00
Ajay Ramachandran
84fbc93c8a Merge pull request #250 from Lartza/min-duration
Add minimum duration option
2020-02-08 19:30:36 -05:00
Ajay Ramachandran
553581f67b Removed extra file 2020-02-08 19:28:23 -05:00
Ajay Ramachandran
afe16e6623 Improved confirm message. 2020-02-08 19:27:38 -05:00
Ajay Ramachandran
0942da0cd1 Moved minimum duration open down 2020-02-08 19:23:48 -05:00
Ajay Ramachandran
c2b3835618 Added colon to minimum duration message 2020-02-08 19:23:34 -05:00
Ajay Ramachandran
4a96a52398 Fixed multiple sponsors being hidden. 2020-02-08 19:19:27 -05:00
Ajay Ramachandran
4e1eb82538 Fixed typescript issues. 2020-02-08 19:10:04 -05:00
Ajay Ramachandran
885fae175d Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into min-duration
# Conflicts:
#	SB.js
#	src/options.ts
2020-02-08 19:09:17 -05:00
Ajay Ramachandran
1cd84d8a2c Fixed Chrome Invidious CSS issues.
Apparently the chrome API doesn't work well with CSS.

Resolves https://github.com/ajayyy/SponsorBlock/issues/241
2020-02-08 18:23:08 -05:00
Ajay Ramachandran
0c891e0a09 Changed time saved date to updated time. 2020-02-08 17:51:16 -05:00
Ajay Ramachandran
08c7754f29 Fixed skip count resetting.
Resolves https://github.com/ajayyy/SponsorBlock/issues/256
2020-02-08 17:50:06 -05:00
Ajay Ramachandran
5f21d3f96f Default UUIDs to an empty list instead of null.
Resolves https://github.com/ajayyy/SponsorBlock/issues/252.
2020-02-08 17:45:22 -05:00
Ajay Ramachandran
158b76c17e Fixed incorrect type. 2020-02-06 20:10:35 -05:00
Joe Dowd
3455a79298 Removed console.log calls 2020-02-07 00:57:24 +00:00
Joe Dowd
dd08ff1507 add custom server address 2020-02-07 00:40:01 +00:00
Lartza
b5996a9783 Discard short segments instead of ignoring them later 2020-02-05 01:12:03 +02:00
Lartza
edb108bbcf Confirm shorter than minDuration submissions 2020-02-04 22:36:22 +00:00
Ajay Ramachandran
feda7fd1a0 Merge pull request #260 from ajayyy/typescript
Rename SB.js
2020-02-04 02:16:47 -05:00
Ajay Ramachandran
46ffb330fc Fix invidious enabling error 2020-02-04 02:15:06 -05:00
Ajay Ramachandran
2f7a4bdb36 Fix chrome build scripts 2020-02-04 02:14:30 -05:00
Ajay Ramachandran
96dab6b6b2 Renamed SB.js and setup types for the config. 2020-02-04 02:10:59 -05:00
Ajay Ramachandran
3e9afe1dc8 Merge pull request #259 from ajayyy/typescript
Manifest building
2020-02-04 01:57:48 -05:00
Ajay Ramachandran
2df2b4c53d Mkdir with directory 2020-02-04 01:48:32 -05:00
Ajay Ramachandran
968dd34c3d Update README.md 2020-02-04 01:45:41 -05:00
Ajay Ramachandran
0cbe73c527 Add recursive to mkdir 2020-02-04 01:43:49 -05:00
Ajay Ramachandran
6d312e7ba7 Create dir when building if needed. 2020-02-04 01:41:47 -05:00
Ajay Ramachandran
09a33c4252 Added manifest building. 2020-02-04 01:32:58 -05:00
Ajay Ramachandran
76d966c1f9 Merge pull request #254 from ajayyy/typescript
Moving to TypeScript
2020-02-04 00:22:08 -05:00
Ajay Ramachandran
da364b49f0 Removed old config example 2020-02-04 00:16:46 -05:00
Ajay Ramachandran
f6f416b899 Fixed direct link channel whitelisting 2020-02-04 00:13:38 -05:00
Ajay Ramachandran
3582f45fd8 Fixed skip notice references fixing manual skip notices. 2020-02-04 00:05:03 -05:00
Ajay Ramachandran
13cef5ff14 Remove invidious message 2020-02-03 23:40:44 -05:00
Ajay Ramachandran
4049d2d1ab Fixed keybind not working 2020-02-03 23:39:41 -05:00
Ajay Ramachandran
db7ac02c7d Fix CI filepath 2020-02-03 23:25:50 -05:00
Ajay Ramachandran
26f3560e97 CI uses new manifest location 2020-02-03 23:23:26 -05:00
Ajay Ramachandran
1eaf4f44c2 Fixed incorrect syntax in example config 2020-02-03 23:20:57 -05:00
Ajay Ramachandran
0a0d4d3e0f Fixed config.json.example naming 2020-02-03 23:16:05 -05:00
Ajay Ramachandran
7f22687c24 Updated CI to use config.json 2020-02-03 23:13:40 -05:00
Ajay Ramachandran
7404e0831b Updated CI 2020-02-03 23:11:01 -05:00
Ajay Ramachandran
e3be54cbe7 Updated build commands 2020-02-03 23:10:04 -05:00
Ajay Ramachandran
b0a23a5c4e Converted options page to TypeScript 2020-02-03 22:34:43 -05:00
Ajay Ramachandran
5bb5dae20e Added config types and added back handler to proxy 2020-02-03 14:11:52 -05:00
Ajay Ramachandran
bb9de35722 Fixed naming issue 2020-02-02 18:26:43 -05:00
Ajay Ramachandran
4907be7738 Fixed maps not being handled properly 2020-02-01 19:25:40 -05:00
Ajay Ramachandran
23141aa624 Made the extension successfully build 2020-02-01 19:18:53 -05:00
Ajay Ramachandran
17381e7deb Moved Utils away from a static class.
Moved Firefox content script registration to the background script.

Moved onInvidious to the content script.
2020-02-01 18:47:36 -05:00
Ajay Ramachandran
4bd410f04e Made the skip notice work with TypeScript. 2020-02-01 18:17:48 -05:00
Ajay Ramachandran
20a09d3d27 Fixed type errors. 2020-02-01 17:51:42 -05:00
Ajay Ramachandran
98b36380b5 Update readme to new config name 2020-02-01 17:46:55 -05:00
Ajay Ramachandran
7716827a98 Fixed incorrect import. 2020-02-01 17:40:12 -05:00
Ajay Ramachandran
070a51954a Fixed channel ID promise 2020-02-01 17:38:58 -05:00
Ajay Ramachandran
de66e21d14 Added support for the on page popup. 2020-02-01 17:36:02 -05:00
Ajay Ramachandran
932cf8ecf1 Fixed SBMap not importing entries. 2020-02-01 16:53:33 -05:00
Ajay Ramachandran
4a491f1ebf Moved server code to utils 2020-02-01 16:41:08 -05:00
Ajay Ramachandran
5ebdfd8466 Added config to gitignore. 2020-02-01 16:27:58 -05:00
Ajay Ramachandran
16c720e500 Setup new config.json and fixed typescript errors in the popup 2020-02-01 16:26:57 -05:00
Ajay Ramachandran
d77f8abf42 Converted more code to TypeScript. 2020-01-28 23:52:15 -05:00
Ajay Ramachandran
03836b69f2 Started conversion to TypeScript. 2020-01-28 22:16:48 -05:00
Ajay Ramachandran
5837205a9a Updated API URL 2020-01-28 15:45:18 -05:00
Ajay Ramachandran
0f346c2096 Updated API url 2020-01-28 15:38:32 -05:00
Ajay Ramachandran
30acfdd788 Uses old query 2020-01-25 12:20:40 -05:00
Ajay Ramachandran
478edfee7c Changed to new user count query 2020-01-25 12:20:18 -05:00
Ajay Ramachandran
a685950a66 Use defaults if it the config is broken 2020-01-24 21:44:24 -05:00
Ajay Ramachandran
69d1d709f6 Merge pull request #251 from ajayyy/experimental
Removed December date.
2020-01-24 21:43:03 -05:00
Ajay Ramachandran
1fcfdcd13c Removed December date. 2020-01-24 21:39:06 -05:00
Lartza
34a21c6d8c Handle invalid current minDuration in options.js 2020-01-24 02:29:11 +02:00
Lartza
e6ef27936e Add minimum duration option 2020-01-24 01:02:23 +02:00
Ajay Ramachandran
2b7f940669 Merge pull request #248 from ajayyy/hotfix-invidious
Fixed firefox content script registration
2020-01-21 23:05:33 -05:00
Ajay Ramachandran
bdcd613f02 Update version number 2020-01-21 23:05:23 -05:00
Ajay Ramachandran
7255300903 Merge pull request #244 from OfficialNoob/patch-5
Support options button when not in popup
2020-01-19 21:44:03 -05:00
Ajay Ramachandran
21b2ad71b9 Merge pull request #245 from jplsek/opt-html5
Set options and help page to use html5
2020-01-19 10:11:23 -05:00
Ajay Ramachandran
1ff7e69556 Merge pull request #247 from OfficialNoob/patch-6
Save Map content
2020-01-19 10:09:28 -05:00
Official Noob
f7a3f98ad3 Comments 2020-01-16 18:43:49 +00:00
Official Noob
4cdb874b4f Removed deleteProperty from MapIO 2020-01-16 18:27:29 +00:00
Official Noob
5df0801c64 deleteProperty() if no key provided delete by id 2020-01-16 18:13:07 +00:00
Official Noob
e286797ac5 Update SB.js 2020-01-16 18:03:40 +00:00
Official Noob
e784dc017d Added clear 2020-01-16 18:02:48 +00:00
Official Noob
251339f26b Comments and added delete 2020-01-16 17:57:54 +00:00
Official Noob
3e3b8eab6f Save Map content 2020-01-16 14:29:03 +00:00
Ajay Ramachandran
a7d769dd6d Merge pull request #246 from jplsek/keybind-esc
Allow keybind cancel with ESC
2020-01-15 21:39:14 -05:00
Jeremy Plsek
ad37e9abe7 Allow keybind cancel with ESC 2020-01-15 20:50:51 -05:00
Jeremy Plsek
f99a3f5088 Set options and help page to use html5
- Fix css when using html5
- Add encoding scheme to html
- Remove font-size change on title on hover. It's jarring
seeing the whole page move when trying to move your mouse
to the options.
- Remove center tags
- Remove unnecessary styles
- Fix some minor grammar
2020-01-15 20:30:07 -05:00
Ajay Ramachandran
6f2a09695b Update README.md 2020-01-14 10:32:26 -05:00
Official Noob
9ae8769869 inPopup did not always work 2020-01-13 20:08:06 +00:00
Official Noob
f58a16179a Added "openConfig" message 2020-01-13 19:54:24 +00:00
Official Noob
297c95ac6b Added inPopup check for options button 2020-01-13 19:52:54 +00:00
Ajay Ramachandran
ced3100b4e Merge pull request #243 from Deykun/master
Polish translation created
2020-01-12 19:04:57 -05:00
Szymon T
7358be6faa Shorter version of fullName 2020-01-13 00:27:55 +01:00
Szymon T
03e29dbb81 Polish translation created 2020-01-12 23:46:38 +01:00
Ajay Ramachandran
7cb2915fd7 Fixed firefox content script registration. 2020-01-11 17:48:11 -05:00
Ajay Ramachandran
5348496768 Merge pull request #235 from OfficialNoob/patch-2
Formatting changes & proxy delete support
2020-01-11 15:17:34 -05:00
Ajay Ramachandran
7526abc3e1 Merge pull request #236 from ajayyy/hotfix-invidious
Fixed new line issue
2020-01-11 14:55:34 -05:00
Ajay Ramachandran
1163b6f0ce Fixed wrong variabled being used. 2020-01-11 14:50:11 -05:00
Ajay Ramachandran
7c809419f8 Formatting changes 2020-01-11 14:48:17 -05:00
Ajay Ramachandran
0a42f130ac Fixed new line issue 2020-01-11 14:45:16 -05:00
Official Noob
4de0ae51e8 Formatting changes & proxy delete support 2020-01-11 19:42:35 +00:00
Ajay Ramachandran
f5a4ffabde Merge pull request #234 from ajayyy/hotfix-invidious
Hotfix
2020-01-11 13:42:10 -05:00
Ajay Ramachandran
115b1edf11 Increased version number 2020-01-11 13:41:44 -05:00
Ajay Ramachandran
04942a3a5d Fixed delete button potentially appearing. 2020-01-11 13:35:20 -05:00
Ajay Ramachandran
aee0712ef1 Fixed old sponsortime config being broken. 2020-01-11 13:27:20 -05:00
Ajay Ramachandran
63568aae9c Merge pull request #229 from ajayyy/experimental-ajay
Increase version number
2020-01-10 22:26:22 -05:00
Ajay Ramachandran
bf90d2a8e6 Increase version number 2020-01-10 22:22:55 -05:00
Ajay Ramachandran
d87cb77895 Merge pull request #228 from ajayyy/experimental-ajay
Invidious support fixes
2020-01-10 22:22:24 -05:00
Ajay Ramachandran
36c4ebda65 Added comments to the settimeout on install 2020-01-10 22:16:53 -05:00
Ajay Ramachandran
968df5a2e4 Increased notice width 2020-01-10 22:15:42 -05:00
Ajay Ramachandran
259f7a9439 Added notice info about the Invidious update. TODO: remove this in the future. 2020-01-10 22:15:28 -05:00
Ajay Ramachandran
4f8e1bc827 Fixed formatting. 2020-01-10 20:49:21 -05:00
Ajay Ramachandran
9e8a520d1e Fixed broken voting. 2020-01-10 20:48:16 -05:00
Ajay Ramachandran
7335429541 Added option for auto-vote. 2020-01-10 20:06:16 -05:00
Ajay Ramachandran
5c227f445a Added ublock origin to npm run dev 2020-01-10 19:58:59 -05:00
Ajay Ramachandran
dce90e86bf Added invidious support info to the help page. 2020-01-10 15:46:50 -05:00
Ajay Ramachandran
36d7dcce9b Revert "Removed snopyta.org from the default."
This reverts commit fb974de53b.
2020-01-10 15:17:31 -05:00
Ajay Ramachandran
502bec55c4 Merge pull request #181 from afrmtbl/add-invidious
Initial Invidious support
2020-01-09 22:41:08 -05:00
Ajay Ramachandran
21a61bb238 Fixed options page and manifest. 2020-01-09 22:40:44 -05:00
Ajay Ramachandran
fb974de53b Removed snopyta.org from the default. 2020-01-09 22:34:26 -05:00
Ajay Ramachandran
a5adf73b88 Moved registration removal to a util function. 2020-01-09 22:32:20 -05:00
Ajay Ramachandran
1f4c4c0901 Make content script reregister on firefox every browser restart 2020-01-09 22:13:00 -05:00
Ajay Ramachandran
338fbcea9c Fixed buttons appearing on invidious. 2020-01-09 21:32:56 -05:00
Ajay Ramachandran
a20fa9871e Added support for any invidious instance. 2020-01-09 21:23:25 -05:00
Ajay Ramachandran
25436d9620 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into add-invidious
# Conflicts:
#	background.js
2020-01-09 20:42:31 -05:00
Ajay Ramachandran
8d3a633d85 Merge pull request #226 from ajayyy/ajay-config-listener
Config callback updating
2020-01-09 20:41:18 -05:00
Ajay Ramachandran
f67568e3b6 Fixed indentation. 2020-01-09 20:29:47 -05:00
Ajay Ramachandran
d902cc5efe Made buttons update with the config. 2020-01-09 20:29:20 -05:00
Ajay Ramachandran
9e89eb521a Added config callback support. 2020-01-09 20:09:32 -05:00
Ajay Ramachandran
f4c5f50f8c Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into add-invidious 2020-01-09 19:53:49 -05:00
Ajay Ramachandran
4301a6bfe3 Merge pull request #225 from ajayyy/experimental-ajay
Option page fixes
2020-01-09 19:53:40 -05:00
Ajay Ramachandran
2c5a78947a Added instance display 2020-01-09 19:52:20 -05:00
Ajay Ramachandran
8f7eb82b6e Remove unnecessary code 2020-01-09 19:42:18 -05:00
Ajay Ramachandran
d2e1373e2a Fixed more merging issues. 2020-01-09 19:23:05 -05:00
Ajay Ramachandran
d705610855 Fix merge issues 2020-01-09 19:19:30 -05:00
Ajay Ramachandran
c40b6576d6 Updated gitignore. 2020-01-09 15:02:06 -05:00
Ajay Ramachandran
1c3e2fcdad Fixed help page style issue. 2020-01-09 15:01:42 -05:00
Ajay Ramachandran
7acc6c3329 Added warning message when changing the userID. 2020-01-09 15:00:03 -05:00
Ajay Ramachandran
1715ee327f Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into experimental-ajay 2020-01-09 14:28:40 -05:00
Ajay Ramachandran
0481943737 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into add-invidious
# Conflicts:
#	background.js
#	content.js
#	options/options.js
2020-01-09 14:28:06 -05:00
Ajay Ramachandran
c53bc20294 Merge pull request #219 from OfficialNoob/patch-26
Config proxy [WIP]
2020-01-09 13:24:33 -05:00
Ajay Ramachandran
a8fc22eae8 Reformatted variable name. 2020-01-09 13:17:26 -05:00
Ajay Ramachandran
4ba82f6e00 Set local config right away 2020-01-09 13:16:27 -05:00
Ajay Ramachandran
8fd671d4d3 Added docs and improved consistency. 2020-01-09 12:46:04 -05:00
Ajay Ramachandran
309b1b007e Removed unneeded function 2020-01-09 12:39:48 -05:00
Ajay Ramachandran
d0e7213cc4 Added docs and removed reflection. Also removed inheritance. 2020-01-09 12:38:15 -05:00
Ajay Ramachandran
a2e9688418 Formatting + duplicate code removal. 2020-01-09 12:30:09 -05:00
Ajay Ramachandran
f42c23cd9a Formatting fixes 2020-01-09 12:12:49 -05:00
Official Noob
52f60d70e2 Map support :D 2020-01-09 16:39:23 +00:00
Official Noob
339d05e157 :/ 2020-01-08 23:27:34 +00:00
Official Noob
c0c3640638 Reverted back <Not working> 2020-01-08 23:16:02 +00:00
Official Noob
a314139302 Map storage encoding 2020-01-08 22:22:18 +00:00
Official Noob
bfa0472f84 Reflect 2020-01-08 19:52:41 +00:00
Ajay Ramachandran
fa19e435cc Switched to a listener map. 2020-01-07 22:59:50 -05:00
Ajay Ramachandran
eb4bf89194 Fixed default 2020-01-07 22:12:53 -05:00
Ajay Ramachandran
da8a1376a7 Converted options page to new config system. 2020-01-07 22:02:16 -05:00
Ajay Ramachandran
267132cdde Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into patch-26 2020-01-07 21:24:54 -05:00
Ajay Ramachandran
b8ebe5076b Fixed indentation. 2020-01-07 21:23:59 -05:00
Ajay Ramachandran
cb9877b3b4 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into experimental-ajay 2020-01-06 22:31:17 -05:00
Ajay Ramachandran
c73b9ed5a6 Remove redundant code. 2020-01-06 22:30:35 -05:00
Ajay Ramachandran
1bd0b4349f Fixed build not ignoring ignored folder 2020-01-06 19:51:49 -05:00
Official Noob
d15785146f Update options.js 2020-01-06 23:42:02 +00:00
Official Noob
47d9d93818 Added SB.js to options html 2020-01-06 23:34:33 +00:00
Official Noob
601ff44145 Forgot comma 2020-01-06 23:29:04 +00:00
Official Noob
cbd451949b Added hideDiscordLink, hideDiscordLink 2020-01-06 23:27:07 +00:00
Official Noob
a7dc207c5f Fix format conflict 2020-01-06 23:12:48 +00:00
Official Noob
c20b67d11f Fixed syntax 2020-01-06 21:20:22 +00:00
Official Noob
0b9def800b Update SB.js 2020-01-06 21:17:28 +00:00
Official Noob
d8ae73e96a Update SB.js 2020-01-06 21:14:31 +00:00
Ajay Ramachandran
c99f7925eb Fixed migrate 2020-01-06 16:13:50 -05:00
Official Noob
3627661e1f Backwards compatibility 2020-01-06 21:11:37 +00:00
Official Noob
f1c68a98cf removed SB.config.dontShowNoticeOld 2020-01-06 18:59:38 +00:00
Official Noob
92f10d51aa Removed SB.config.dontShowNoticeOld 2020-01-06 18:58:47 +00:00
Official Noob
bdae68be35 () => 2020-01-06 18:56:37 +00:00
Official Noob
2a4abf958d Map test 2020-01-01 19:20:14 +00:00
Official Noob
1362331a93 Map test 2020-01-01 19:12:15 +00:00
Official Noob
a70aa7723e Map test 2020-01-01 19:11:17 +00:00
Official Noob
a3f5200c9a Map test 2020-01-01 19:10:34 +00:00
Official Noob
1005783034 Update SB.js 2020-01-01 18:02:16 +00:00
Official Noob
278e40207c Create empty array for sponsorTimeKey 2020-01-01 18:00:47 +00:00
Ajay Ramachandran
509b627e88 Made it reenable the permission when an invidious instance is added.
Right now it throws an error
2020-01-01 12:55:35 -05:00
Official Noob
ecd9f6eaff Update content.js 2020-01-01 15:09:13 +00:00
Official Noob
1d2b6b2010 userID 2020-01-01 14:50:05 +00:00
Official Noob
6c4d5c0705 submitTimes async 2020-01-01 14:47:41 +00:00
Official Noob
0533919bde Update SB.js 2020-01-01 14:45:34 +00:00
Official Noob
e02ca1c822 Update SB.js 2020-01-01 14:45:22 +00:00
Official Noob
039c1a178f Update background.js 2020-01-01 14:44:39 +00:00
Official Noob
6f682baa45 Update content.js 2020-01-01 14:30:23 +00:00
Official Noob
0241c0a036 Update SB.js 2020-01-01 14:04:49 +00:00
Official Noob
4ebdcf1cc5 Update content.js 2020-01-01 14:04:18 +00:00
Official Noob
46c3187c89 Update content.js 2020-01-01 13:46:09 +00:00
Official Noob
c65e3c21e3 fix 2020-01-01 13:01:42 +00:00
Official Noob
e35774138f Added run_at document_start 2020-01-01 13:01:18 +00:00
Official Noob
a9b678f0ff dontShowNoticeAgain 2020-01-01 12:36:29 +00:00
Official Noob
32356d711d Update SB.js 2020-01-01 12:35:54 +00:00
Official Noob
477ae3eb2c Update SB.js 2020-01-01 12:27:59 +00:00
Ajay Ramachandran
0b41118232 Added option for custom invidious instances. 2019-12-31 19:09:37 -05:00
Ajay Ramachandran
ea3f9f246e Fixed firefox support. 2019-12-31 18:13:51 -05:00
Official Noob
9dd954e7d8 Added default for trackViewCount 2019-12-31 22:54:02 +00:00
Official Noob
41352a5116 Update content.js 2019-12-31 22:52:41 +00:00
Official Noob
1ac9989288 Use defaults 2019-12-31 22:50:52 +00:00
Ajay Ramachandran
b441cc2123 Added firefox support and support for multiple invidious instances. 2019-12-31 17:48:43 -05:00
Official Noob
5e2bc43722 Update SB.js 2019-12-31 22:48:29 +00:00
Official Noob
da17dd8bae Added addDefaults and resetConfig 2019-12-31 22:46:16 +00:00
Official Noob
87098d1c3e Update content.js 2019-12-31 22:04:40 +00:00
Official Noob
2a1b60596b debug 2019-12-31 21:30:54 +00:00
Official Noob
7bbbe0dcf3 Use SB.config 2019-12-31 20:56:30 +00:00
Official Noob
25672a6496 SB.js content script 2019-12-31 20:17:27 +00:00
Official Noob
796bf6ef45 Added SB.js 2019-12-31 20:10:16 +00:00
Official Noob
6ceeaebd9d Added SB 2019-12-31 20:08:11 +00:00
Official Noob
61b8427270 File used to control the SB object 2019-12-31 20:07:43 +00:00
Official Noob
4450aaa3b3 Moving to separate due to load order 2019-12-31 20:07:03 +00:00
Ajay Ramachandran
b0e0c380dd Added Firefox fixes 2019-12-31 14:50:01 -05:00
Official Noob
8baf11a053 Forgot SB. 2019-12-31 19:20:20 +00:00
Official Noob
67f9697f3f test 2019-12-31 19:17:10 +00:00
Official Noob
a94d941125 Added sync config 2019-12-31 19:16:46 +00:00
Official Noob
2917de6776 Moved localconfig to SB object 2019-12-31 19:06:33 +00:00
Official Noob
272698f97b Update utils.js 2019-12-31 19:03:43 +00:00
Official Noob
3fbb689e0a Moving utils 2019-12-31 19:01:17 +00:00
Ajay Ramachandran
4817af5e4f Removed minimum version 2019-12-31 13:29:59 -05:00
Ajay Ramachandran
aba08a515e Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into add-invidious 2019-12-31 13:18:46 -05:00
Ajay Ramachandran
83801db82e Merge pull request #215 from jplsek/ci4
Add web-ext and ci artifact generation
2019-12-31 13:17:46 -05:00
Official Noob
84e4adbc12 Config proxy [POC]
Having a global SB.config that can be used to store get and set variables easily  
Example: SB.config.userID = "blah"
2019-12-31 14:55:03 +00:00
Ajay Ramachandran
6a37753753 Added defaults to option page. 2019-12-31 02:32:44 -05:00
Ajay Ramachandran
0898c7e28c Added options description. 2019-12-31 02:23:39 -05:00
Ajay Ramachandran
412be37ae5 Fixed channel parsing error. 2019-12-31 02:23:23 -05:00
Ajay Ramachandran
beec376e10 Updated invidious explainer. 2019-12-31 02:17:02 -05:00
Ajay Ramachandran
df30f00347 Moved invidious code to functions and made it check permissions on init. 2019-12-31 02:15:10 -05:00
Ajay Ramachandran
dcfdade927 Added invidio.sh 2019-12-31 02:08:32 -05:00
Ajay Ramachandran
741ddcd8aa Fixed permissions. 2019-12-31 02:06:58 -05:00
Ajay Ramachandran
433db26078 Added option to enable invidious support. 2019-12-30 23:15:29 -05:00
Ajay Ramachandran
fc033cb69d Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into add-invidious 2019-12-30 17:40:32 -05:00
Ajay Ramachandran
bd8c67bc24 Merge branch 'experimental-ajay' of https://github.com/ajayyy/SponsorBlock into add-invidious 2019-12-30 17:39:07 -05:00
Ajay Ramachandran
a80fbc1a04 Merge pull request #216 from ajayyy/options-page
Options Page
2019-12-30 17:37:59 -05:00
Ajay Ramachandran
e347504616 Removed options from popup. 2019-12-30 17:37:02 -05:00
Ajay Ramachandran
94cbf089db Added submission keybind option 2019-12-30 17:23:05 -05:00
Ajay Ramachandran
cb2fb6925b Added keybind option. 2019-12-30 16:41:33 -05:00
Ajay Ramachandran
b3361a473c Removed use of center tag. 2019-12-30 14:44:03 -05:00
Ajay Ramachandran
fcb6ed7676 Added text set option (userID) 2019-12-30 01:20:20 -05:00
Ajay Ramachandran
91f4d7f669 Removed logs 2019-12-30 00:49:23 -05:00
Ajay Ramachandran
2e2ff60c23 Made the options save. 2019-12-30 00:48:59 -05:00
Ajay Ramachandran
13727270d4 Added all toggle buttons and made them set to their values. 2019-12-30 00:39:02 -05:00
Ajay Ramachandran
b27f56bc00 Added basic options panel.
Co-authored-by: Official Noob <31563761+OfficialNoob@users.noreply.github.com>
2019-12-29 23:18:18 -05:00
Ajay Ramachandran
7ad7d793d0 Added info about web-ext run 2019-12-29 20:52:40 -05:00
Ajay Ramachandran
491bef680e Removed unnecessary ignored files. 2019-12-29 20:49:31 -05:00
Ajay Ramachandran
e581dc818f Updated ignore files for build. 2019-12-29 20:26:47 -05:00
Jeremy Plsek
8d0b032eb6 Add web-ext and ci artifact generation 2019-12-29 19:35:02 -05:00
Ajay Ramachandran
9cb4fd6f79 Merge pull request #214 from OfficialNoob/patch-26
getYouTubeVideoID ~ TV support
2019-12-29 16:56:36 -05:00
Official Noob
87abcae249 fix embeds 2019-12-29 21:51:11 +00:00
Ajay Ramachandran
fe608b579e Formatting 2019-12-29 16:48:10 -05:00
Official Noob
f74e25a482 Update utils.js 2019-12-29 21:42:43 +00:00
Official Noob
1db9d25f3b getYouTubeVideoID ~ TV support 2019-12-29 21:39:19 +00:00
Ajay Ramachandran
f25aeefe83 Merge branch 'master' into add-invidious 2019-12-29 00:34:49 -05:00
Ajay Ramachandran
1abc1b9b28 Merge pull request #212 from ajayyy/experimental-ajay
UserID import, ID fixes, view count fix, embed error fix
2019-12-29 00:29:51 -05:00
Ajay Ramachandran
d10c8041bf Update build number 2019-12-29 00:28:56 -05:00
Ajay Ramachandran
c14c795474 Improved channel name query selector.
Resolves https://github.com/ajayyy/SponsorBlock/issues/199
2019-12-29 00:21:38 -05:00
Ajay Ramachandran
e5937431c3 Prevented error on embed.
Resolves https://github.com/ajayyy/SponsorBlock/issues/202
2019-12-29 00:14:51 -05:00
Ajay Ramachandran
b24a688e63 Improved view count 2019-12-29 00:10:08 -05:00
Ajay Ramachandran
10fd22f49c Fixed view counting being broken. 2019-12-29 00:08:57 -05:00
Ajay Ramachandran
f1dda95847 Merge branch 'experimental' of https://github.com/ajayyy/SponsorBlock into experimental-ajay
# Conflicts:
#	content.js
2019-12-29 00:08:41 -05:00
Ajay Ramachandran
f3f6dd171b Switched vote and view to POST. 2019-12-28 23:56:38 -05:00
Ajay Ramachandran
c802212a62 Added ability to import/export your userID. 2019-12-28 22:13:03 -05:00
Ajay Ramachandran
afb666797d Fixed IDs being localized in some parts. 2019-12-28 11:04:36 -05:00
Ajay Ramachandran
85a591c984 Merge pull request #207 from ImMaax/master
Fixed German translation
2019-12-23 21:01:04 -05:00
Max
3edaea8102 Removed word 2019-12-22 22:57:04 +01:00
Max
93c39c3ecc Fixed German translation 2019-12-22 22:54:43 +01:00
Ajay Ramachandran
ab2f0ef395 Crowdin fixes 2019-12-21 00:00:23 -05:00
Ajay Ramachandran
005ca73cce Update Crowdin configuration file 2019-12-20 23:56:49 -05:00
Ajay Ramachandran
8dd8897f1f Fixed yaml formatting 2019-12-20 23:08:34 -05:00
Ajay Ramachandran
95555ed3fd Fixed yaml 2019-12-20 23:06:07 -05:00
Ajay Ramachandran
11b71f7366 Added custom language mapping to crowdin file 2019-12-20 23:03:41 -05:00
Ajay Ramachandran
4537c70105 Update Crowdin configuration file 2019-12-20 22:42:22 -05:00
Ajay Ramachandran
42a0cff162 Update crowdin.yml 2019-12-20 17:55:35 -05:00
Ajay Ramachandran
527e6d4c24 Update Crowdin configuration file 2019-12-20 17:43:23 -05:00
Ajay Ramachandran
2c19da2117 Merge pull request #201 from ajayyy/experimental-ajay
Fixed channel whitelisting on old YouTube
2019-12-19 01:06:48 -05:00
Ajay Ramachandran
7ee1cc911f Increase version number. 2019-12-19 01:05:11 -05:00
Ajay Ramachandran
9fc846bd7a Made sure the video player button options are ignored on Invidious. 2019-12-19 01:03:09 -05:00
Ajay Ramachandran
5b628ccbf9 Fixed submit button being shown at the wrong time. 2019-12-19 00:56:52 -05:00
Ajay Ramachandran
5471273673 Fixed getting channel ID for invidious. 2019-12-19 00:48:26 -05:00
Ajay Ramachandran
58c0c6e152 Merge branch 'experimental-ajay' of https://github.com/ajayyy/SponsorBlock into add-invidious 2019-12-19 00:46:52 -05:00
Ajay Ramachandran
36078acaee Fixed channel whitelisting on old YouTube. 2019-12-19 00:46:37 -05:00
Ajay Ramachandran
7d62c9f575 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into add-invidious 2019-12-19 00:40:32 -05:00
Ajay Ramachandran
45a64fcb03 Prevented upload button from appearing on invidious.
It still appears if the video player controls are disabled.
2019-12-19 00:38:55 -05:00
Ajay Ramachandran
630b099fd6 Fixed formatting and removed whitelisting fix code.
Whitelisting was now fixed in a different way.
2019-12-19 00:36:35 -05:00
Ajay Ramachandran
c17e47ddd3 Merge pull request #198 from ajayyy/experimental-ajay
German translation + fixes
2019-12-19 00:09:46 -05:00
Ajay Ramachandran
81bf54c42d Upped version number 2019-12-19 00:08:31 -05:00
Ajay Ramachandran
5b693e81fd Added german translation thanks to Floatinger. 2019-12-19 00:08:07 -05:00
Ajay Ramachandran
00115cd707 Fixed string not using language file. 2019-12-17 18:32:20 -05:00
Ajay Ramachandran
e992844fa2 Fixed channel parsing error.
Fixes whitelisting issues.
2019-12-17 18:32:01 -05:00
Ajay Ramachandran
b30acaac78 Merge pull request #195 from ajayyy/experimental-ajay
Small Fixes
2019-12-13 23:37:11 -05:00
Ajay Ramachandran
46ac654224 Update version number 2019-12-13 23:35:17 -05:00
Ajay Ramachandran
8578e96c3a Fixed channel whitelisting and channel finding on new YouTube layout. 2019-12-13 23:21:21 -05:00
Ajay Ramachandran
b42bdc6e6f Fixed popup stats padding. 2019-12-13 22:45:40 -05:00
Ajay Ramachandran
369364f574 Fixed downvoted sponsors reappearing. 2019-12-13 22:38:00 -05:00
Ajay Ramachandran
a5baebab3f Fixed new submissions getting added to the downloaded submissions. 2019-12-13 21:55:43 -05:00
Ajay Ramachandran
b34e6076e4 Moved error message handling to a util file and added a link to the status site. 2019-12-13 21:32:57 -05:00
Ajay Ramachandran
226c5d601c Added space to notification. 2019-12-10 18:17:07 -05:00
Ajay Ramachandran
cc1a12e1a2 Clarified that auto-upvote can be disabled. 2019-12-09 17:06:30 -05:00
Ajay Ramachandran
1d342b21fd Added small guideline reminder to submission confirmation dialog. 2019-12-08 12:08:36 -05:00
afrmtbl
5dc67a386c Fix manifest 2019-12-05 16:13:22 -05:00
afrmtbl
6d442b9e80 Explain additional whitelist check 2019-12-05 15:48:26 -05:00
afrmtbl
2f6ddeb5f1 Initial Invidious support 2019-12-05 15:35:25 -05:00
Ajay Ramachandran
3d01ffee1b Merge pull request #179 from ajayyy/experimental-ajay
Added better local stats.
2019-12-04 23:53:26 -05:00
Ajay Ramachandran
9c51df9159 Increased version number. 2019-12-04 23:51:47 -05:00
Ajay Ramachandran
3a29fcc3d8 Added time the user saved others from plus better time formatting. 2019-12-04 23:51:20 -05:00
Ajay Ramachandran
b18f2ae60d Made it show how much time you have saved yourself. 2019-12-04 23:38:07 -05:00
Ajay Ramachandran
ab07478e25 Updated build number 2019-12-03 17:01:34 -05:00
Ajay Ramachandran
d6aeec933a Merge pull request #176 from ajayyy/experimental-ajay
Better error messages and manual skipping
2019-12-03 00:02:07 -05:00
Ajay Ramachandran
cd5207f816 Added ability to disable auto skip.
Resolves https://github.com/ajayyy/SponsorBlock/issues/131 and https://github.com/ajayyy/SponsorBlock/issues/162
2019-12-02 23:58:29 -05:00
Ajay Ramachandran
381c11ed99 Updated error messages. 2019-11-28 18:03:33 -05:00
Ajay Ramachandran
62d4b365c2 Merge pull request #173 from ajayyy/experimental-ajay
Made the popup work on non YouTube tabs
2019-11-24 01:16:56 -05:00
Ajay Ramachandran
524df6389a Update version number. 2019-11-24 01:14:55 -05:00
Ajay Ramachandran
24292e771b Made the popup work on non YouTube tabs. 2019-11-24 01:13:52 -05:00
Ajay Ramachandran
f35d34a807 Merge pull request #172 from ajayyy/experimental-ajay
Small features and bug fixes
2019-11-24 00:55:04 -05:00
Ajay Ramachandran
468e33eff7 Update version number. 2019-11-24 00:53:51 -05:00
Ajay Ramachandran
600f9e4b85 Changed order of popup. Also fixed discord link.
Resolves https://github.com/ajayyy/SponsorBlock/issues/156.
2019-11-24 00:48:35 -05:00
Ajay Ramachandran
9cb3da4a7f Added a button to disable skipping. Also changed up popup look.
Resolves https://github.com/ajayyy/SponsorBlock/issues/167
2019-11-24 00:05:35 -05:00
Ajay Ramachandran
a66c7c8063 Properly added submissions to sponsor times when done. 2019-11-23 18:05:42 -05:00
Ajay Ramachandran
0a84dbd3a5 Improved speed of whitelist check. 2019-11-23 17:53:04 -05:00
Ajay Ramachandran
2fa412e574 Removed deprecated code to fix whitelist array. 2019-11-23 17:44:22 -05:00
Ajay Ramachandran
f240416886 Fixed reversed strings.
Resolves https://github.com/ajayyy/SponsorBlock/issues/170.
2019-11-23 14:35:33 -05:00
Ajay Ramachandran
2a025b7977 Fixed formatting in readme 2019-11-23 13:33:55 -05:00
Ajay Ramachandran
f44d2b67e5 Added link to MPV port 2019-11-23 13:33:22 -05:00
Ajay Ramachandran
6b15ebac99 Added link in readme 2019-11-23 12:54:34 -05:00
Ajay Ramachandran
ff41251f17 Merge pull request #171 from ajayyy/experimental-ajay
Fixed error message, prevented double counting contributions and delayed userID generation
2019-11-23 12:49:19 -05:00
Ajay Ramachandran
c7c1cb79a8 Increased version number. 2019-11-23 12:48:10 -05:00
Ajay Ramachandran
fc155ccdfa Prevented contributions from counting twice. 2019-11-23 12:47:00 -05:00
Ajay Ramachandran
dfad1a5636 Added delayed startup after install. 2019-11-23 12:44:38 -05:00
Ajay Ramachandran
6790952f86 Fixed error messages not working. Added message for error 503 and 0. 2019-11-23 12:26:24 -05:00
Ajay Ramachandran
1a28f714a1 Update README.md 2019-11-17 21:32:31 -05:00
Ajay Ramachandran
55a55fefba Update README.md 2019-11-17 21:32:01 -05:00
Ajay Ramachandran
fe74f7caa3 Merge pull request #169 from ajayyy/experimental-ajay
Decreased requests to help with server load issues
2019-11-14 15:05:57 -05:00
Ajay Ramachandran
108aac0e79 Improved non YouTube tab message. 2019-11-14 15:04:46 -05:00
Ajay Ramachandran
008c07acc3 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into experimental-ajay 2019-11-14 14:59:55 -05:00
Ajay Ramachandran
831a3c1b5a Increased retry timeout when the server is down. 2019-11-14 14:59:44 -05:00
Ajay Ramachandran
dc7b63d735 Merge pull request #164 from Otiel/french-translation
Improve French translation
2019-11-14 14:58:50 -05:00
Ajay Ramachandran
9267f36165 Raised retry time from 10 seconds to 180 seconds (3 mins). 2019-11-14 14:53:40 -05:00
Ajay Ramachandran
ae6d63c3ab Merge pull request #168 from ajayyy/experimental-ajay
Fixed notice never hiding
2019-11-07 13:05:22 -05:00
Ajay Ramachandran
a3214f0fa7 Fixed notice never hiding. 2019-11-07 13:04:31 -05:00
Otiel
d4bd5313fc french: add missing translation 2019-10-31 21:07:37 +01:00
Otiel
c69fe53ea6 french: improve existing translation 2019-10-31 21:07:12 +01:00
Otiel
d7c496847f french: fix spelling 2019-10-31 20:20:48 +01:00
Ajay Ramachandran
44516648a1 Merge pull request #163 from ajayyy/experimental-ajay
Keybind edit, show notice again, ignore rate limits
2019-10-30 23:39:18 -04:00
Ajay Ramachandran
fbeabc830b Merge branch 'firefox-optimizations' of https://github.com/ajayyy/SponsorBlock into experimental-ajay 2019-10-30 23:38:56 -04:00
Ajay Ramachandran
f370746382 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into experimental-ajay 2019-10-30 23:38:18 -04:00
Ajay Ramachandran
e82beb861a Merge pull request #153 from owendaprile/firefox-optimizations
Some Firefox Optimizations
2019-10-30 23:38:13 -04:00
Ajay Ramachandran
1791d31681 Revert "Moved browser specific settings into manifest"
This reverts commit 047432af03.
2019-10-30 23:37:36 -04:00
Ajay Ramachandran
784ddea34a Updated version number. 2019-10-30 23:33:10 -04:00
Ajay Ramachandran
69c93a0563 Removed deprecated show install page code 2019-10-30 23:32:32 -04:00
Ajay Ramachandran
4e4d50de82 Fixed feature to show the notice to users again. 2019-10-30 23:30:30 -04:00
Ajay Ramachandran
25b9edabf8 Changed hint to say that you can change the keybind. 2019-10-28 16:16:13 -04:00
Ajay Ramachandran
6851470547 Added the ability to change the keybind. 2019-10-28 16:13:37 -04:00
Ajay Ramachandran
73c1fc17b3 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into experimental-ajay 2019-10-28 11:59:10 -04:00
Ajay Ramachandran
cba5b05c0c Merge pull request #160 from ptalmeida/master
Add european portuguese translation
2019-10-27 20:17:22 -04:00
Pedro Almeida
3f1573f1b3 Improve portuguese locales 2019-10-27 22:11:47 +01:00
Pedro Almeida
93ffc93943 Improve Brazilian Portuguese locale 2019-10-27 19:28:16 +01:00
Pedro Almeida
4214af4d56 Add support for European Portuguese 2019-10-27 19:27:22 +01:00
Owen D'Aprile
01405dd32e Ignore WebStorm project configuration folder 2019-10-15 17:49:01 -04:00
Owen D'Aprile
047432af03 Moved browser specific settings into manifest 2019-10-15 17:48:40 -04:00
Owen D'Aprile
a8bd5d0068 Suppress Firefox error when changing tabs 2019-10-15 17:46:42 -04:00
Ajay Ramachandran
eeb6d20e96 Fixed grammar 2019-10-13 12:09:14 -04:00
Ajay Ramachandran
8bb8511bf4 Fixed indenting. 2019-09-24 18:21:47 -04:00
Ajay Ramachandran
563610cbcd Made it show the new notice again. 2019-09-24 18:16:57 -04:00
Ajay Ramachandran
04190b27d8 Made it ignore rate limits for voting. 2019-09-24 17:55:07 -04:00
Ajay Ramachandran
1782376e3d Merge pull request #145 from ajayyy/experimental-ajay
Fixed info button + videoChannelID errors
2019-09-02 21:33:36 -04:00
Ajay Ramachandran
ef1b96bbf1 Update version number 2019-09-02 21:33:14 -04:00
Ajay Ramachandran
7deea5d648 Made getChannelID only get called if there is a valid YouTube page. 2019-09-02 10:54:49 -04:00
Ajay Ramachandran
c6460b006f Update README.md 2019-09-01 22:41:52 -04:00
Ajay Ramachandran
4352667b1c Added days saved 2019-09-01 22:40:18 -04:00
Ajay Ramachandran
a84502dc92 Update README.md 2019-09-01 21:54:52 -04:00
Ajay Ramachandran
d7c67fb481 Update README.md 2019-09-01 21:52:14 -04:00
Ajay Ramachandran
adc9748d4d Update README.md 2019-09-01 21:51:31 -04:00
Ajay Ramachandran
f310c53f88 Made sure info menu is not placed in the incorrect container. 2019-09-01 21:08:29 -04:00
Ajay Ramachandran
f2c2fd0d29 Merge pull request #144 from Strappazzon/i18n-it
Add Italian translation
2019-09-01 14:47:40 -04:00
Strappazzon
1b0cd0f485 Shorter title 2019-09-01 19:17:33 +02:00
Strappazzon
48f6f2f66c Add Italian translation 2019-09-01 18:52:24 +02:00
Ajay Ramachandran
85b70f8ad7 Merge pull request #143 from ajayyy/experimental-ajay
More Localisation + Fixed Whitelisting
2019-08-31 22:07:41 -04:00
Ajay Ramachandran
3e32f28d2e Update version number. 2019-08-31 22:07:22 -04:00
Ajay Ramachandran
9bd1b03504 Made the info button not appear on embeds.
Also fixed issues with the buttons changing visibility before being added.
2019-08-31 21:32:48 -04:00
Ajay Ramachandran
cdccc43b31 Revert "Fancy tooltip for player controls"
This reverts commit 0c2ceb134b.
2019-08-31 21:21:01 -04:00
Ajay Ramachandran
21ce614bd9 Made the function clear whitelisted channels that were null. 2019-08-31 21:17:07 -04:00
Ajay Ramachandran
7f56ec238f Merge branch 'experimental' of https://github.com/ajayyy/SponsorBlock into experimental-ajay 2019-08-31 21:04:19 -04:00
Ajay Ramachandran
e1625437d4 Fixed getting the channel URL for whitelisting. 2019-08-31 21:04:08 -04:00
Ajay Ramachandran
5b9afebd4e Merge pull request #142 from omarroth/fields-api
Only request published field from Invidious API
2019-08-31 17:14:31 -04:00
Ajay Ramachandran
93afc06717 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into experimental 2019-08-31 17:13:59 -04:00
Omar Roth
cfbf1f8995 Only request published field from Invidious API 2019-08-31 16:44:46 -04:00
Ajay Ramachandran
516e5077a9 Merge pull request #141 from FisheyLP/experimental
Fancy tooltip for player controls
2019-08-31 14:06:40 -04:00
FisheyLP
0c2ceb134b Fancy tooltip for player controls 2019-08-31 18:37:29 +02:00
Ajay Ramachandran
02bcb0b213 Merge branch 'experimental' of https://github.com/ajayyy/SponsorBlock into experimental-ajay 2019-08-28 18:12:59 -04:00
Ajay Ramachandran
35c6ed81b5 Updated hotkey handling. 2019-08-28 18:11:29 -04:00
Ajay Ramachandran
a229aee2cc Merge pull request #134 from OfficialNoob/patch-23
Content.js messageListener switch
2019-08-27 21:17:46 -04:00
Ajay Ramachandran
f91c6d5f9d Change return to break. 2019-08-27 21:17:21 -04:00
Ajay Ramachandran
0e93fb6f57 Merge pull request #135 from OfficialNoob/patch-24
Popup i18n support
2019-08-27 21:14:13 -04:00
Ajay Ramachandran
1f491d2031 Updated naming 2019-08-27 21:13:37 -04:00
Ajay Ramachandran
32dd7d43d7 Updated it to make it work in the info menu (on page popup). 2019-08-27 21:10:35 -04:00
Ajay Ramachandran
284efe9902 Merge branch 'experimental' into patch-24 2019-08-27 21:04:05 -04:00
Ajay Ramachandran
4e795c8fb1 Merge pull request #139 from ajayyy/experimental-ajay
Fixed preview bar causing issues
2019-08-27 21:01:48 -04:00
Ajay Ramachandran
c83eb589ea Updated version number. 2019-08-27 21:00:00 -04:00
Ajay Ramachandran
7cd6b324b9 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into experimental-ajay 2019-08-27 20:59:36 -04:00
Ajay Ramachandran
5891fccacb Updated shield links 2019-08-26 16:10:25 -04:00
Ajay Ramachandran
59233f3307 Update README.md 2019-08-26 16:09:26 -04:00
Ajay Ramachandran
796466a72a Added some shields 2019-08-26 16:08:33 -04:00
Ajay Ramachandran
3f35642010 Made the preview bar wait for it to not be null. 2019-08-26 14:35:49 -04:00
Ajay Ramachandran
5bbfcf742d Fixed preview bar bar loading too early 2019-08-26 14:30:55 -04:00
Ajay Ramachandran
aaf79fda0d Added more language strings 2019-08-25 23:22:35 -04:00
Ajay Ramachandran
8604788d27 Merge branch 'experimental' into patch-24 2019-08-24 14:03:04 -04:00
Ajay Ramachandran
519a822751 Merge pull request #138 from ajayyy/experimental-ajay
Improved away function
2019-08-24 14:01:35 -04:00
Ajay Ramachandran
fef31c399b Update version number. 2019-08-24 14:00:15 -04:00
Ajay Ramachandran
5802e05228 Update utils.js 2019-08-24 13:59:53 -04:00
Ajay Ramachandran
da21081a12 Merge branch 'patch-21' into experimental-ajay 2019-08-24 13:54:24 -04:00
Official Noob
6d739de57c Fixed html 2019-08-24 18:22:04 +01:00
Official Noob
edcd328743 Added localizeHtmlPage(); to popup.js 2019-08-24 18:18:16 +01:00
Official Noob
5c9e6cac0e Removed localizeHtmlPage(); 2019-08-24 18:17:36 +01:00
Official Noob
7ab5e2cf52 Added localizeHtmlPage() 2019-08-24 18:08:22 +01:00
Official Noob
42dcdb40cf Added localizeHtmlPage 2019-08-24 18:06:25 +01:00
Ajay Ramachandran
896357a943 Merge pull request #136 from ajayyy/experimental-ajay
Fixed submissions being broken on the video player
2019-08-24 12:32:56 -04:00
Ajay Ramachandran
2d96c24b13 Update version number 2019-08-24 12:30:03 -04:00
Ajay Ramachandran
1753f58120 Fixed submissions being broken. 2019-08-24 12:29:51 -04:00
Official Noob
7244ca8f5e Update messages.json 2019-08-24 15:16:29 +01:00
Official Noob
ec0c989066 Added stuff for popup 2019-08-24 15:07:05 +01:00
Official Noob
c801b1fecd Update popup.html 2019-08-24 15:03:19 +01:00
Official Noob
57b50106d1 Popup i18n support 2019-08-24 14:50:02 +01:00
Official Noob
871ba63f67 Content.js messageListener switch 2019-08-24 12:55:42 +01:00
Ajay Ramachandran
f0888faf78 Merge pull request #133 from ajayyy/experimental
Update master
2019-08-23 23:30:11 -04:00
Ajay Ramachandran
23fbbebc9e Merge branch 'experimental' of https://github.com/ajayyy/SponsorBlock into experimental-ajay 2019-08-23 23:28:56 -04:00
Ajay Ramachandran
9951a19478 Updated version number. 2019-08-23 23:27:42 -04:00
Ajay Ramachandran
dd4ab2f38a Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into experimental 2019-08-23 21:13:37 -04:00
Ajay Ramachandran
6bcdb3e272 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into experimental-ajay 2019-08-23 21:13:23 -04:00
Ajay Ramachandran
227bec4d8e Merge pull request #83 from OfficialNoob/patch-16
Added youtube-nocookie.com
2019-08-23 21:13:03 -04:00
Ajay Ramachandran
556b4f88d2 Merge pull request #122 from OfficialNoob/patch-21
Added addButtons
2019-08-23 21:11:04 -04:00
Ajay Ramachandran
2d12f957bc Improved await function. 2019-08-23 21:10:28 -04:00
Ajay Ramachandran
c1efe02614 Improved promise calling in button updating function. 2019-08-23 21:06:00 -04:00
Ajay Ramachandran
f0e1979aab Renamed addButtons and defined controls. 2019-08-23 21:03:43 -04:00
Ajay Ramachandran
989db6d6b6 Added more spacing. 2019-08-23 21:02:17 -04:00
Ajay Ramachandran
781096c290 Fixed cut off text. 2019-08-23 21:01:31 -04:00
Ajay Ramachandran
536c6e3e41 Removed new line from messages. 2019-08-23 21:00:07 -04:00
Ajay Ramachandran
de376176db Fixed preview bar being added too soon. 2019-08-23 20:59:13 -04:00
Ajay Ramachandran
e63389cfa3 Fixed buttons appearing too early not hidden (submit and clear button). 2019-08-23 20:52:12 -04:00
Ajay Ramachandran
1c4ca8da26 Fixed formatting issues + previewBar not displaying.
Also changed the isSubmitButtonLoaded function to be checking for the right button and fixed the startSponsorButton not hiding.

Useless function was removed.
2019-08-23 20:50:10 -04:00
Ajay Ramachandran
dcbd7ba4cd Merge pull request #132 from ajayyy/experimental-ajay
More checks + popup fix
2019-08-23 20:31:29 -04:00
Ajay Ramachandran
9fc8d385ab Fixed popup getting cut off. 2019-08-23 14:23:34 -04:00
Ajay Ramachandran
07e878e065 Fixed missing language call. 2019-08-23 14:22:16 -04:00
Official Noob
a2af4dba52 Added back getYouTubeVideoStartTime 2019-08-23 17:19:44 +01:00
Ajay Ramachandran
2fbafb6b10 Added duration check to popup as well. 2019-08-22 23:12:30 -04:00
Ajay Ramachandran
98eb72ef1f Made sure rechecks didn't happen twice. 2019-08-22 22:43:55 -04:00
Ajay Ramachandran
89d127c5c5 Added a check to make sure the time doesn't exceed the duration of the video. 2019-08-22 22:43:19 -04:00
Ajay Ramachandran
a784c8a850 Merge pull request #130 from doubouil/patch-1
Better french translation
2019-08-22 21:29:45 -04:00
Ajay Ramachandran
a533aaf5cf Updated French translation 2019-08-22 21:28:52 -04:00
doubouil
434b5bdbad Better french translation
Native speaker here, the machine based translation was not great so here's a first draft.
I choose to use "message commercial" (commercial message) and not "publicité" (advertisement) since ads feels to me to be more a legal status than a definite thing. "Endossement" is not a valid french word in this context, and endorsements would be translated to "sponsors" or "mécénat" in fr_FR, but again this are more legal category than pure identifying terms and fr_CA strongly dislikes frenglish.
But I left it in the extension name since this is a good keyword for people looking for adblocking-related extensions.
2019-08-22 21:10:41 +00:00
Ajay Ramachandran
d1f1f9213e Merge pull request #129 from ajayyy/experimental-ajay
UserID undefined checks
2019-08-22 16:10:50 -04:00
Ajay Ramachandran
d498c107a8 Update version number. 2019-08-22 16:08:38 -04:00
Ajay Ramachandran
f12b44762e Added new check to setup a proper userID if undefined while voting. 2019-08-22 16:08:16 -04:00
Official Noob
fc4da038e9 Merge branch 'experimental' into patch-21 2019-08-22 19:48:59 +01:00
Official Noob
d5999ad330 Added isDraggable 2019-08-22 19:39:17 +01:00
Official Noob
146ece3bff Fixed JSON error 2019-08-22 19:36:30 +01:00
Ajay Ramachandran
92095acf36 Merge pull request #128 from Revadike/fix-draggable
Disallow dragging of button
2019-08-22 12:34:18 -04:00
Revadike
279c10d555 Disallow dragging of button 2019-08-22 15:52:45 +02:00
Ajay Ramachandran
0ae3820681 Merge pull request #127 from ajayyy/experimental
Update master
2019-08-21 20:01:43 -04:00
Ajay Ramachandran
283e4d053e Merge pull request #126 from ajayyy/experimental-ajay
Translations + Unsubmitted sponsor preview
2019-08-21 20:01:18 -04:00
Ajay Ramachandran
6dbb2f9d10 Update version number. 2019-08-21 19:58:44 -04:00
Ajay Ramachandran
c657bb763b Merge branch 'experimental' of https://github.com/ajayyy/SponsorBlock into experimental-ajay 2019-08-21 19:57:40 -04:00
Ajay Ramachandran
259cdb1abe Merge pull request #123 from bershanskiy/russian
Russian translation
2019-08-21 19:57:30 -04:00
Ajay Ramachandran
86e96e59af Update README.md 2019-08-21 19:21:06 -04:00
Official Noob
9ba30dbafa Moved to bottom 2019-08-21 20:21:39 +01:00
Anton Bershanskiy
2907db705c Update messages.json 2019-08-21 14:03:46 -05:00
Ajay Ramachandran
a6a0f917e0 Fixed preview not working when no sponsors are found. 2019-08-21 14:35:46 -04:00
Official Noob
bcdba798d9 Added locals for buttons 2019-08-21 19:29:24 +01:00
Ajay Ramachandran
32884372fa Unsubmitted sponsors are now in the preview. 2019-08-21 14:27:25 -04:00
Official Noob
9b2364cfb7 fixed isSubmitLoaded 2019-08-21 19:22:59 +01:00
Ajay Ramachandran
c1aebf45c8 Removed the need for getYouTubeVideoStartTime and made it check the current video time instead. 2019-08-21 14:16:52 -04:00
Official Noob
6e0c6332cc Fixed title in createButton 2019-08-21 19:15:35 +01:00
Official Noob
47d0d340d4 Requested changes 2019-08-21 19:10:49 +01:00
Ajay Ramachandran
118804e139 Added confirm language to translations. Increased size of notice. Updated translations. 2019-08-21 14:04:05 -04:00
Ajay Ramachandran
0bef50e259 Merge pull request #121 from OfficialNoob/patch-18
Added wait function
2019-08-21 13:47:57 -04:00
Official Noob
bfb876af8b Changed button exists check 2019-08-21 18:29:41 +01:00
Official Noob
84d5d3124c Update content.js 2019-08-21 18:17:30 +01:00
Official Noob
825d997d6d Update content.js 2019-08-20 23:37:40 +01:00
Official Noob
8e9e5bfddb Update content.js 2019-08-20 23:26:35 +01:00
Official Noob
05765682a5 Update content.js 2019-08-20 23:11:18 +01:00
Official Noob
2b5d56942a Update content.js 2019-08-20 22:59:34 +01:00
Ajay Ramachandran
f097ff60aa Fixed indentation 2019-08-20 17:47:31 -04:00
Anton Bershanskiy
655691a28f Russian translation 2019-08-20 15:10:21 -05:00
Ajay Ramachandran
7ddef8d519 Update README.md 2019-08-20 16:09:47 -04:00
Ajay Ramachandran
2fb79f0066 Update README.md 2019-08-20 16:09:22 -04:00
Ajay Ramachandran
655d87ce0f Update README.md 2019-08-20 16:08:27 -04:00
Ajay Ramachandran
ed7c98afa8 Update README.md 2019-08-20 16:06:29 -04:00
Ajay Ramachandran
41bf0c9697 Update README.md 2019-08-20 16:05:47 -04:00
Ajay Ramachandran
5eb0132660 Update README.md 2019-08-20 16:05:25 -04:00
Ajay Ramachandran
c43695e596 Update README.md 2019-08-20 16:04:47 -04:00
Ajay Ramachandran
9aeda25136 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into experimental 2019-08-20 15:54:51 -04:00
Ajay Ramachandran
90e671ebf8 Updated french translation 2019-08-20 15:54:40 -04:00
Ajay Ramachandran
3ecc180d06 Added french translation + fixed i18n not being used for the notification. 2019-08-20 15:46:00 -04:00
Official Noob
7ac9ec37ef Adding addButtons and using sponsorVideoID more 2019-08-20 20:27:30 +01:00
Ajay Ramachandran
e176a9f241 Fixed it linking to non existent file 2019-08-20 15:07:36 -04:00
Ajay Ramachandran
91bd910c40 Added Brazilian Portuguese translation by @Geroyuni
Co-authored-by: Geroyuni <Geroyuni@users.noreply.github.com>
2019-08-20 15:04:13 -04:00
Official Noob
a6c77185de Added wait function 2019-08-20 17:46:05 +01:00
Ajay Ramachandran
b871d721db Update version number. 2019-08-19 22:27:42 -04:00
Ajay Ramachandran
85f9bb1d34 Removed setInterval when removing the notice. 2019-08-19 22:26:49 -04:00
Ajay Ramachandran
adb60c6357 Update README.md 2019-08-19 20:57:31 -04:00
Ajay Ramachandran
90046aed53 Merge pull request #120 from ajayyy/experimental-ajay
Update version number
2019-08-19 20:25:52 -04:00
Ajay Ramachandran
7adef119d3 Update version number 2019-08-19 20:23:42 -04:00
Ajay Ramachandran
4db6593681 Merge branch 'experimental' of https://github.com/ajayyy/SponsorBlock into experimental 2019-08-19 20:20:08 -04:00
Ajay Ramachandran
f4c7e11ae1 Merge pull request #119 from ajayyy/experimental-ajay
Notice countdown counter, reskip, formatting fixes + sponsor check fixes
2019-08-19 20:19:48 -04:00
Ajay Ramachandran
b1393a563f Added language support to setUsername. Fixed error messages not appearing. Reset error messages properly.
Resolves https://github.com/ajayyy/SponsorBlock/issues/111
2019-08-19 20:17:32 -04:00
Ajay Ramachandran
279e49a143 Fixed more indentation 2019-08-19 20:05:33 -04:00
Ajay Ramachandran
db4182d074 Fixed indentation 2019-08-19 19:21:19 -04:00
Ajay Ramachandran
cc2d1405b6 Made the notice id suffix not just the sponsor UUID. 2019-08-19 19:19:33 -04:00
Ajay Ramachandran
19802a7a31 Made the notice stay open after an unskip and allow to reskip.
The time remaining of the popup becomes the time remaining of the sponsor.
2019-08-19 19:07:14 -04:00
Ajay Ramachandran
50f929c11a Adjusted fade out animation to feel much better 2019-08-19 17:57:10 -04:00
Ajay Ramachandran
e5e250ff36 Added fade out animation 2019-08-19 17:39:22 -04:00
Ajay Ramachandran
6fe94a70a7 Countdown timer now pauses after hovering.
Also lowered countdown time.
2019-08-19 17:24:17 -04:00
Ajay Ramachandran
db2af83a34 Added countdown to skip notice 2019-08-19 17:08:31 -04:00
Ajay Ramachandran
cbab026f27 Added new button backgrounds. Centered report button 2019-08-19 16:49:22 -04:00
Ajay Ramachandran
0c2c868e5c Made report text disappear after voting. 2019-08-19 16:13:18 -04:00
Ajay Ramachandran
175cf62201 Refractored skipNotice to use a class now 2019-08-19 16:09:54 -04:00
Ajay Ramachandran
761ae63845 Fixed css issues on old YouTube on the notice. 2019-08-19 12:11:19 -04:00
Ajay Ramachandran
70948d9b36 Update version number 2019-08-15 23:56:35 -04:00
Ajay Ramachandran
3e0638d811 Updated sponsor check to support slower PCs 2019-08-15 15:16:24 -04:00
Ajay Ramachandran
096bf0d750 Merge pull request #118 from ajayyy/experimental-ajay
Report button additions
2019-08-15 11:26:01 -04:00
Ajay Ramachandran
c81d4cc2a1 Update version number 2019-08-15 11:23:38 -04:00
Ajay Ramachandran
628f1043fa Added text to the report button. 2019-08-15 11:23:19 -04:00
Ajay Ramachandran
73b8d82b0f Made view count tracking work when the notice is disabled 2019-08-15 11:12:46 -04:00
Ajay Ramachandran
d6ba6c83e8 Update README.md 2019-08-15 00:54:45 -04:00
Ajay Ramachandran
3c56bc49fd Merge pull request #117 from ajayyy/experimental-ajay
Updated help page
2019-08-14 22:22:40 -04:00
Ajay Ramachandran
1697bf5e6a Updated help page 2019-08-14 22:22:19 -04:00
Ajay Ramachandran
960bca13d4 Merge pull request #116 from ajayyy/experimental
New notice + language support + preview fixes
2019-08-14 22:18:49 -04:00
Ajay Ramachandran
ccf6d8dd8f Merge pull request #115 from ajayyy/experimental-ajay
Added new notice and new only downvote behavior
2019-08-14 22:17:59 -04:00
Ajay Ramachandran
6822fa9a67 Merge branch 'experimental' of https://github.com/ajayyy/SponsorBlock into experimental-ajay 2019-08-14 22:09:59 -04:00
Ajay Ramachandran
2266df88d5 Update version number 2019-08-14 22:09:50 -04:00
Ajay Ramachandran
5d075a6be4 Made autovote only happen if view counting is enabled 2019-08-14 22:08:23 -04:00
Ajay Ramachandran
215098f647 Added new text values to translation file. 2019-08-14 21:53:38 -04:00
Ajay Ramachandran
a7f3701272 Made it auto vote when a sponsor is skipped 2019-08-14 21:50:32 -04:00
Ajay Ramachandran
08b8b63678 Removed need for important tag 2019-08-14 21:46:30 -04:00
Ajay Ramachandran
d550bb6b7f Revert upvote and downvote buttons 2019-08-14 21:33:32 -04:00
Ajay Ramachandran
edb577cf5b Changed popup to only use report button instead of upvote and downvote + improved popup. 2019-08-14 21:30:02 -04:00
Ajay Ramachandran
739548d169 Changed alignment and switched icons 2019-08-14 14:07:00 -04:00
Ajay Ramachandran
2e2e5d136a Added explanation about the username 2019-08-14 13:56:19 -04:00
Ajay Ramachandran
b1ce20cd5a Added basic features for the new voting UI 2019-08-13 23:43:02 -04:00
Ajay Ramachandran
2431f44a29 Merge pull request #114 from ajayyy/experimental-ajay
Made preview bar update more and made the sponsor times reset more.
2019-08-13 21:10:48 -04:00
Ajay Ramachandran
0e4d95dca7 Made preview bar update more and made the sponsor times reset more. 2019-08-13 19:18:53 -04:00
Ajay Ramachandran
5ee80d6e50 Merge pull request #113 from ajayyy/experimental-ajay
Fixes for #86 and better preview bar
2019-08-13 18:58:15 -04:00
Ajay Ramachandran
bfd841486e Fixed incorrect message and changed formatting 2019-08-13 18:55:50 -04:00
Ajay Ramachandran
29da12ec71 Updated popup title 2019-08-13 18:49:55 -04:00
Ajay Ramachandran
d89238f76b Changed to not change popup HTML file based on language 2019-08-13 18:44:47 -04:00
Ajay Ramachandran
57f076c5d3 Removed debug log 2019-08-13 18:40:46 -04:00
Ajay Ramachandran
ea41980fc6 Merge branch 'experimental' of https://github.com/ajayyy/SponsorBlock into experimental-ajay
# Conflicts:
#	manifest.json
2019-08-13 18:23:56 -04:00
Ajay Ramachandran
33954aafaf Merge pull request #86 from OfficialNoob/patch-18
Multilingual support [TESTING]
2019-08-13 18:12:37 -04:00
OfficialNoob
a10b4ab06e Fix merge error 2019-08-13 22:14:45 +01:00
OfficialNoob
f350f18190 Fixed code problems 2019-08-13 22:05:39 +01:00
Ajay Ramachandran
60fc61560d Added leaderboard link 2019-08-13 14:39:20 -04:00
Ajay Ramachandran
fadb294c98 Made the preview bar only get created if a video is found. 2019-08-13 14:05:32 -04:00
Ajay Ramachandran
137ba895bb Merge pull request #110 from ajayyy/experimental
Update master
2019-08-13 13:06:10 -04:00
Ajay Ramachandran
ecc48de396 Merge pull request #109 from ajayyy/experimental-ajay
Fixed preview bar
2019-08-13 13:05:52 -04:00
Ajay Ramachandran
aa95687b56 Update version number 2019-08-13 13:03:08 -04:00
Ajay Ramachandran
a8147738ef Raised retry limit for when the server is down. 2019-08-13 13:02:54 -04:00
Ajay Ramachandran
4a3d36b952 Fixed preview bar.
Made it reset when no sponsors are found.

Made it wait until the video metadata is loaded if necessary.
2019-08-13 13:02:35 -04:00
Ajay Ramachandran
f9bd82db35 Merge pull request #103 from OfficialNoob/patch-20
Added switch for chrome.runtime.onMessage
2019-08-13 00:32:43 -04:00
Ajay Ramachandran
c8438b9d59 Updated formatting 2019-08-13 00:32:33 -04:00
Ajay Ramachandran
5347340c1c Merge pull request #107 from ajayyy/experimental-ajay
Preview bar, downvote to hide sponsor, usernames
2019-08-12 23:44:53 -04:00
Ajay Ramachandran
524e443f4d Updated build number 2019-08-12 23:44:14 -04:00
Ajay Ramachandran
b9091c3a97 Made it get the current username when letting you edit it. 2019-08-12 23:32:10 -04:00
Ajay Ramachandran
5445146b56 Added ability to set your username 2019-08-12 23:20:35 -04:00
Ajay Ramachandran
13d0e4a33a Made it still possible to vote on downvoted sponsors.
Added "(hidden)" to the button.

Resolves https://github.com/ajayyy/SponsorBlock/issues/28
2019-08-12 20:22:00 -04:00
Ajay Ramachandran
8f0a9d97f6 Downvoting now temporarily hides the sponsor time. 2019-08-12 20:00:42 -04:00
Ajay Ramachandran
5feed6bfcc Added preview bar with the sponsors 2019-08-12 19:34:44 -04:00
Official Noob
e8246a9a8a Added new stuff 2019-08-12 22:29:15 +01:00
Official Noob
e141b1f4e8 Update manifest.json 2019-08-12 22:28:41 +01:00
Official Noob
f9fcd80552 CC 2019-08-12 22:28:07 +01:00
Official Noob
8c7d749f11 CC 2019-08-12 22:15:25 +01:00
Official Noob
bcc927f21a CC 2019-08-12 22:10:33 +01:00
Official Noob
b13837ce44 CC 2019-08-12 22:07:24 +01:00
Official Noob
806456d287 added helpPage 2019-08-12 21:45:14 +01:00
Official Noob
2deb2ff4b5 added helpPage 2019-08-12 21:43:34 +01:00
Official Noob
fb1836cd07 Rename popup.html to popup_en.html 2019-08-12 21:41:40 +01:00
Official Noob
f2036885aa Update manifest.json 2019-08-12 21:41:16 +01:00
Official Noob
948293db04 added popup 2019-08-12 21:40:23 +01:00
Official Noob
5031a85a5c Update background.js 2019-08-12 21:38:44 +01:00
Official Noob
a5e3dcaf4d Update background.js 2019-08-12 21:34:03 +01:00
Official Noob
37816ba762 Rename index.html to index_en.html 2019-08-12 21:30:02 +01:00
Official Noob
ed9a445b4c browser.i18n -> chrome.i18n 2019-08-12 21:25:03 +01:00
Official Noob
0b801ae986 browser.i18n -> chrome.i18n 2019-08-12 21:23:11 +01:00
Ajay Ramachandran
5916baf5ea Merge pull request #105 from ajayyy/experimental
Lowered permissions + Edit panel additions
2019-08-12 16:05:28 -04:00
Official Noob
afa260b733 Merge branch 'experimental' into patch-18 2019-08-12 21:02:55 +01:00
Ajay Ramachandran
1c3a857fcf Merge pull request #104 from ajayyy/experimental-ajay
Edit panel additions
2019-08-12 16:01:56 -04:00
Ajay Ramachandran
640ad58c65 Updated version number 2019-08-12 15:59:06 -04:00
Ajay Ramachandran
41aa58e004 Fixed userIDs not being properly submitted. 2019-08-12 15:58:25 -04:00
Ajay Ramachandran
6b3eb09198 Added button to set edit to the current time. 2019-08-12 15:27:35 -04:00
Official Noob
59c2e5cae7 i18n 2019-08-12 20:10:13 +01:00
Official Noob
a30c7cf383 Update messages.json 2019-08-12 20:08:26 +01:00
Official Noob
334e32fb6b i18n 2019-08-12 19:47:11 +01:00
Official Noob
7a36277695 added connectionError 2019-08-12 19:46:25 +01:00
Official Noob
9a2bce4ba6 Added Segment 2019-08-12 19:35:08 +01:00
Official Noob
71d2231fb5 Update messages.json 2019-08-12 18:41:45 +01:00
Official Noob
cc3f970aef Internationalization 2019-08-12 18:40:16 +01:00
Official Noob
189a28f027 added fullName 2019-08-12 18:36:02 +01:00
Official Noob
a2750ad709 Fixed JSON 2019-08-12 18:34:17 +01:00
Official Noob
c8341a448d Switched to native 2019-08-12 18:33:36 +01:00
Official Noob
44c4671977 Added switch for chrome.runtime.onMessage 2019-08-12 17:41:26 +01:00
Ajay Ramachandran
ac118173a5 Made preview also save the edit. 2019-08-12 12:26:52 -04:00
Ajay Ramachandran
3f815a18c4 Added a sponsor time preview.
It skips 2 seconds before the start time so you can preview how it feels.

Also increased the space between the times and the clear times button.

Resolves https://github.com/ajayyy/SponsorBlock/issues/66
2019-08-12 12:21:20 -04:00
Ajay Ramachandran
e281b90699 Fixed sponsor times not properly saving 2019-08-12 12:05:16 -04:00
Ajay Ramachandran
012a36b931 Increased button padding 2019-08-12 12:04:57 -04:00
Ajay Ramachandran
43e3d03e9a Added better error checking 2019-08-12 12:02:01 -04:00
Ajay Ramachandran
5adeeed634 Made editing not possible on unfinished sponsors.
Resolved https://github.com/ajayyy/SponsorBlock/issues/77
2019-08-12 11:42:39 -04:00
Ajay Ramachandran
29a8608f9d Merge pull request #90 from OfficialNoob/patch-19
Removed tabs permission
2019-08-12 11:36:57 -04:00
Official Noob
5347b9c935 Merge branch 'experimental' into patch-18 2019-08-12 15:59:25 +01:00
Official Noob
67c4acbc5e Removed videoID as now message active tab 2019-08-12 13:38:35 +01:00
Official Noob
a5d605f539 Removed videoID as now message active tab 2019-08-12 13:38:27 +01:00
Ajay Ramachandran
66b6985c5e Merge pull request #101 from ajayyy/experimental
Better lookups + userID generator improvements
2019-08-11 23:24:17 -04:00
Ajay Ramachandran
0025785a78 Updated version number 2019-08-11 23:22:20 -04:00
Ajay Ramachandran
ba284aec2f Merge pull request #100 from ajayyy/experimental-ajay
More lookups
2019-08-11 23:19:40 -04:00
Ajay Ramachandran
5ffe207a86 Made it retry a sponsor lookup each second if there is a connection error.
It will stop after 15 tries.
2019-08-11 23:18:50 -04:00
Ajay Ramachandran
3a4d867ae3 Made it check again for sponsors after submitting. 2019-08-11 23:13:07 -04:00
Ajay Ramachandran
7a2c57aae9 Merge pull request #73 from OfficialNoob/patch-13
Made UUID less predictable
2019-08-11 23:08:54 -04:00
Ajay Ramachandran
05faa7e138 Merge branch 'master' into patch-13 2019-08-11 23:07:27 -04:00
Ajay Ramachandran
455189d916 Merge pull request #99 from ajayyy/experimental-ajay
Update version number
2019-08-11 17:10:56 -04:00
Ajay Ramachandran
1c05de3098 Update version number 2019-08-11 17:10:40 -04:00
Ajay Ramachandran
577baa508b Merge pull request #98 from ajayyy/experimental
New background script and utils script
2019-08-11 17:10:08 -04:00
Ajay Ramachandran
aebb4313bc Merge pull request #97 from ajayyy/experimental-ajay
Fixed background not using serverAddress from config
2019-08-11 17:09:42 -04:00
Ajay Ramachandran
d42377a5cd Fixed background not using serverAddress from config. 2019-08-11 17:09:04 -04:00
Official Noob
f254a99d6f notifications 2019-08-11 21:21:04 +01:00
Official Noob
19a1a5efda Added alertPrevious message 2019-08-11 21:20:10 +01:00
Official Noob
28322f19b5 videoID 2019-08-11 19:36:52 +01:00
Official Noob
c7d03aa423 videoID 2019-08-11 19:32:44 +01:00
Official Noob
60242df3c9 Removed stuff thats in utils.js 2019-08-11 19:29:38 +01:00
Official Noob
1aab52edbe Remove userID 2019-08-11 19:27:38 +01:00
Ajay Ramachandran
2580577ce0 Added comments 2019-08-11 12:49:25 -04:00
Official Noob
1ab33375ec Update background.js 2019-08-11 13:51:59 +01:00
Official Noob
e1f5046ace Merge branch 'experimental' into patch-19 2019-08-11 13:38:00 +01:00
Ajay Ramachandran
699ca91a94 Made channel whitelisting properly work on first loaded video. 2019-08-10 22:04:32 -04:00
Ajay Ramachandran
30c12e3983 Reduced errors by getting if the channel is whitelisted after checking it is is a YouTube tab. 2019-08-10 20:57:11 -04:00
Ajay Ramachandran
15d6a48359 Fixed url object not being properly defined. 2019-08-10 20:53:43 -04:00
Ajay Ramachandran
b700d4eec0 Merge pull request #72 from OfficialNoob/patch-10
Added Utils file + Updated Parser
2019-08-10 19:57:11 -04:00
Ajay Ramachandran
5be8ecb32b Fixed up formatting and style. Added more detailed error messages. Changed from var to let.
Co-author worked on creating this url parser.

Co-Authored-By: Giacomo Rossetto <jackyman_cs4@live.it>
2019-08-10 19:55:39 -04:00
Ajay Ramachandran
ccafbf663c Fixed typos.
Co-author worked on creating this url parser.

Co-Authored-By: Giacomo Rossetto <jackyman_cs4@live.it>
2019-08-10 19:51:08 -04:00
Ajay Ramachandran
3f7e9e22ec Merge pull request #89 from bershanskiy/nonpersistent
Refactor: make background non-persistent
2019-08-10 19:38:29 -04:00
Ajay Ramachandran
e5d9c75392 Merge pull request #92 from bershanskiy/web_accessible_resources
Remove help/* from web_accessible_resources
2019-08-10 19:37:46 -04:00
Official Noob
b28087f723 Kind of better :/ 2019-08-09 11:34:08 +01:00
Official Noob
866cc33f0e Update content.js 2019-08-08 20:33:05 +01:00
Official Noob
02448307ab Update background.js 2019-08-08 20:32:18 +01:00
Anton Bershanskiy
b34b3f5651 Remove help/* from web_accessible_resources
Remove files in help/ directory from web_accessible_resources in manifest.json because the help page opens in context of the extension (no need to expose it to other contexts).
2019-08-08 14:21:42 -05:00
Anton Bershanskiy
7c787b77e8 Remove unnecessary changes 2019-08-08 14:17:33 -05:00
Official Noob
1b5d5f8a3a Added tab update back 2019-08-08 20:15:23 +01:00
Official Noob
6707d6df8d Added onUpdated back as did not work 2019-08-08 19:59:15 +01:00
Anton Bershanskiy
0c669d6b83 Fix: add migration path away from shownInstallPage 2019-08-08 13:29:09 -05:00
Official Noob
883871123a Update content.js 2019-08-08 19:26:26 +01:00
Official Noob
301e16b8f1 Removed tabUpdate as detecting in contentscript 2019-08-08 19:25:29 +01:00
Ajay Ramachandran
df1bc9d7a6 Merge pull request #91 from ajayyy/master
Update experimental
2019-08-08 13:40:22 -04:00
Official Noob
e1f1814748 Moved code from background.js 2019-08-08 17:03:58 +01:00
Official Noob
074f7c5456 Switched callback to onTabs 2019-08-08 16:50:33 +01:00
Official Noob
2a64afe9dc camelCase 2019-08-08 16:48:00 +01:00
Official Noob
4c12bb9c2f camelCase 2019-08-08 16:45:23 +01:00
Official Noob
22e7c6a40d Sync Video ID with Storage API 2019-08-08 14:44:48 +01:00
Official Noob
a9ea22f505 Get ID from storage API 2019-08-08 14:43:15 +01:00
Official Noob
2067b1c787 Removed unused lines 2019-08-08 14:04:21 +01:00
Official Noob
410f5fc138 Update background.js 2019-08-08 14:03:13 +01:00
Official Noob
077efd2de3 Moving to content script 2019-08-08 14:02:06 +01:00
Official Noob
62632792cc Removed tabs permission 2019-08-08 13:28:50 +01:00
Anton Bershanskiy
7e2925a1e3 Refactor: make background non-persistent 2019-08-08 00:24:30 -05:00
Official Noob
4c37bd24ac Update LANG.js 2019-08-07 18:12:04 +01:00
Official Noob
8e3a46d393 Update LANG.js 2019-08-07 17:45:56 +01:00
Official Noob
c7f8a39282 Update LANG.js 2019-08-07 17:45:10 +01:00
Official Noob
c09cff86b5 Update popup.js 2019-08-07 17:33:16 +01:00
Official Noob
24c61bab71 Auto detect lang 2019-08-07 17:15:57 +01:00
Official Noob
37df697b3d Added Utils for lang 2019-08-07 17:08:29 +01:00
Official Noob
86fee63a8b Moving into LANG 2019-08-07 17:04:50 +01:00
Official Noob
21b5fc9723 Added LANG.js 2019-08-07 16:59:57 +01:00
Official Noob
e5add6c392 Create LANG.js 2019-08-07 16:55:47 +01:00
Official Noob
b964d93ea9 Update utils.js 2019-08-07 16:35:29 +01:00
Official Noob
baba619fe7 Fixed scope 2019-08-07 16:20:07 +01:00
Official Noob
dce036b0e6 Update utils.js 2019-08-07 15:46:07 +01:00
Official Noob
c6c8d7de49 Update utils.js 2019-08-07 15:34:21 +01:00
Official Noob
02e11503cb Removed Regex as "looks bad" 2019-08-06 22:06:23 +01:00
Official Noob
d75a7ca897 Added youtube-nocookie.com 2019-08-06 21:40:23 +01:00
Official Noob
2b5402fa57 Added sanity check 2019-08-06 14:08:46 +01:00
Official Noob
7ad5e426fb Improved Parser 2019-08-06 10:27:13 +01:00
Official Noob
bbbb4f4877 Made UUID less predictable 2019-08-04 20:01:39 +01:00
Official Noob
9a32710ef8 Removed getYouTubeVideoStartTime 2019-08-04 19:09:46 +01:00
Official Noob
d25792f39a Removed getYouTubeVideoID 2019-08-04 19:07:00 +01:00
Official Noob
5ee279dec7 Added getYouTubeVideoStartTime 2019-08-04 19:06:07 +01:00
Official Noob
e6fa832cb8 Removed getYouTubeVideoID as in utils 2019-08-04 19:04:43 +01:00
Official Noob
64befaebfc Removed getYouTubeVideoID as in utils 2019-08-04 19:00:54 +01:00
Official Noob
5425c54fca Added utils.js 2019-08-04 18:59:51 +01:00
Official Noob
aae0998426 Added utils.js 2019-08-04 18:59:08 +01:00
Official Noob
f6c9e8e235 Added getYouTubeVideoID 2019-08-04 18:47:07 +01:00
Ajay Ramachandran
18909ffef6 Merge pull request #71 from marioortizmanero/master
Grammar and phrasing fixes
2019-08-04 09:17:10 -04:00
Mario Ortiz Manero
3a037818a8 Grammar and phrasing fixes 2019-08-04 13:29:43 +02:00
Ajay Ramachandran
101d94f46e Merge pull request #70 from ajayyy/experimental
Made popup close on video change
2019-08-03 23:32:07 -04:00
Ajay Ramachandran
38bb50a472 Made popup close on video change 2019-08-03 23:30:45 -04:00
Ajay Ramachandran
3b3653af67 Update README.md 2019-08-03 22:38:21 -04:00
Ajay Ramachandran
6be7408d80 Merge pull request #68 from ajayyy/experimental
Channel whitelisting, more support and bug fixes
2019-08-03 22:17:29 -04:00
Ajay Ramachandran
6d67559627 Update version number. 2019-08-03 22:14:08 -04:00
Ajay Ramachandran
db46d0438f Added whitelist support to the old YouTube theme. 2019-08-03 22:12:20 -04:00
Ajay Ramachandran
a5580daebd Added channel whitelisting.
Known issue: Does not work with 0 second sponsors.

Resolves https://github.com/ajayyy/SponsorBlock/issues/38
2019-08-03 21:35:41 -04:00
Ajay Ramachandran
809be3b2fb Fixed submit button disappearing after already submitting once. 2019-08-03 20:52:09 -04:00
Ajay Ramachandran
0319c507d3 Made videos load from the subscription page. 2019-08-03 14:11:47 -04:00
Ajay Ramachandran
8ffab867e1 Made zero second skips not skip when the video starts at a non zero time. 2019-08-02 22:37:12 -04:00
Ajay Ramachandran
fcf7141733 Update version number 2019-08-02 22:14:35 -04:00
Ajay Ramachandran
1c1fb6006c Added support for loading a channel page first.
Still has some issues on slow PCs, see https://github.com/ajayyy/SponsorBlock/issues/60
2019-08-02 12:18:56 -04:00
Ajay Ramachandran
6cb07b5be3 Fixed the preview sometimes not updating 2019-08-02 00:54:50 -04:00
Ajay Ramachandran
9342112bac Merge pull request #59 from ajayyy/experimental
Moved notice, embed support and bug fixes
2019-08-01 21:42:52 -04:00
Ajay Ramachandran
3d1be7158d Added support for embedded videos.
Resolved https://github.com/ajayyy/SponsorBlock/issues/12
2019-08-01 20:55:47 -04:00
Ajay Ramachandran
efe512b561 Removed unnecessary check for if the info tab is loaded 2019-08-01 20:38:36 -04:00
Ajay Ramachandran
d738eac42d Moved notice to a better location and shrunk it. 2019-08-01 20:32:04 -04:00
Ajay Ramachandran
a83969e3eb Fixed notice never displaying 2019-08-01 20:21:45 -04:00
Ajay Ramachandran
92cb8fb65c Updated version number 2019-08-01 20:02:42 -04:00
Ajay Ramachandran
932702cca1 Added preview before uploading submissions. 2019-08-01 20:01:33 -04:00
Ajay Ramachandran
ca8404147d Made clicking upload hide the clear button 2019-08-01 15:19:58 -04:00
Ajay Ramachandran
35c3b5b97f Made it only count a contribution if it was uploaded successfully. 2019-07-31 23:47:04 -04:00
Ajay Ramachandran
015b283731 Merge pull request #50 from OfficialNoob/patch-7
Added ErrorParser
2019-07-31 23:24:28 -04:00
Ajay Ramachandran
2667838937 Merge branch 'experimental' of https://github.com/ajayyy/SponsorBlock into patch-7
# Conflicts:
#	popup.js
2019-07-31 23:22:43 -04:00
Ajay Ramachandran
a5ec7b2466 Fixed missing comma 2019-07-31 23:21:30 -04:00
Ajay Ramachandran
3a0a267e12 Reimplements error system 2019-07-31 23:17:40 -04:00
Ajay Ramachandran
cbdb715fac Merge pull request #51 from OfficialNoob/patch-8
"Improvements" to the Ref system
2019-07-31 23:11:26 -04:00
Ajay Ramachandran
64fb12289c Merge branch 'experimental' into patch-8 2019-07-31 23:11:18 -04:00
Ajay Ramachandran
25801b6fcd Merged into master 2019-07-31 23:09:33 -04:00
Ajay Ramachandran
1341d5e11d Fixed grammer 2019-07-31 22:57:50 -04:00
Official Noob
e1dc5fbdf5 t => T 2019-07-31 12:53:25 +01:00
Ajay Ramachandran
83b4bbc95a Merge pull request #56 from ajayyy/experimental
Added help page on install
2019-07-31 00:14:04 -04:00
Ajay Ramachandran
585be8adf4 Added help page on install. 2019-07-31 00:12:02 -04:00
Ajay Ramachandran
9462886539 Merge pull request #55 from ajayyy/experimental
Fixed save button being in the wrong place and made submit button hidden on editing
2019-07-30 21:08:58 -04:00
Ajay Ramachandran
85518d8130 Fixed save button being in the wrong place and made submit button hide on editing. 2019-07-30 21:07:27 -04:00
Ajay Ramachandran
e3aeb0caa1 Update LICENSE 2019-07-30 18:38:07 -04:00
Ajay Ramachandran
7ed72fad40 Merge pull request #52 from ajayyy/experimental
Firefox fixes
2019-07-30 18:22:45 -04:00
Ajay Ramachandran
a2b4f8d141 Update version number 2019-07-30 18:21:23 -04:00
Ajay Ramachandran
6ad1070c44 Merge branch 'master' into experimental 2019-07-30 18:20:27 -04:00
Ajay Ramachandran
b1784fa311 Update version number. 2019-07-30 18:18:03 -04:00
Ajay Ramachandran
74affbd9c0 Fixed Firefox notification issue 2019-07-30 18:15:49 -04:00
Ajay Ramachandran
10d1978566 Added better support for the old YouTube layout. 2019-07-30 15:57:28 -04:00
Official Noob
d51e8044f4 Update popup.js 2019-07-30 20:46:02 +01:00
Official Noob
69dee25ea8 "Improvements" to the Ref system 2019-07-30 20:43:45 +01:00
Official Noob
0d8c18a38a Update popup.js 2019-07-30 19:44:45 +01:00
Ajay Ramachandran
a1c8ecabca Merge pull request #49 from OfficialNoob/patch-6
Old function in-use
2019-07-30 14:41:21 -04:00
Official Noob
a4eb37db18 Added ErrorParser 2019-07-30 19:41:06 +01:00
Official Noob
53f611a43a Old function in-use 2019-07-30 18:59:06 +01:00
Ajay Ramachandran
b0929e2431 Remade the popup menu to support Firefox and not use IFrames. 2019-07-30 13:27:20 -04:00
Ajay Ramachandran
da20709512 Merge pull request #48 from ajayyy/experimental
More options
2019-07-30 00:11:45 -04:00
Ajay Ramachandran
6ff461fa86 Updated version number 2019-07-30 00:09:11 -04:00
Ajay Ramachandran
e205447968 Added ability to hide info and delete button. 2019-07-29 21:40:13 -04:00
Ajay Ramachandran
ff6234bffe Increased font size of sponsor time, edit and delete buttons.
Also made clicking times trigger an edit.
2019-07-29 21:19:29 -04:00
Ajay Ramachandran
d93d475c1f Added error messages to video player submission. 2019-07-29 21:09:10 -04:00
Ajay Ramachandran
0d0b919106 Added better error messages to voting. 2019-07-29 21:06:15 -04:00
Ajay Ramachandran
366fd43752 Added more specific error message for error 502 2019-07-29 20:58:48 -04:00
Ajay Ramachandran
1119adffb7 Added clear button. 2019-07-29 20:54:10 -04:00
Ajay Ramachandran
9d14f02bec Update README.md 2019-07-29 17:54:21 -04:00
Ajay Ramachandran
9fada00028 Update LICENSE 2019-07-29 17:53:15 -04:00
Ajay Ramachandran
e0d2436372 Added support for old youtube theme 2019-07-29 16:35:30 -04:00
Ajay Ramachandran
e4c94aa5c5 Added more info the confirmation button. 2019-07-29 16:29:20 -04:00
72 changed files with 21754 additions and 2369 deletions

62
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,62 @@
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.json.example config.json
# Create Chrome artifacts
- name: Create Chrome artifacts
run: npm run build:chrome
- uses: actions/upload-artifact@v1
with:
name: ChromeExtension
path: dist
- run: mkdir ./builds
- uses: montudor/action-zip@v0.1.0
with:
args: zip -qq -r ./builds/ChromeExtension.zip ./dist
# Create Firefox artifacts
- name: Create Firefox artifacts
run: npm run build:firefox
- uses: actions/upload-artifact@v1
with:
name: FirefoxExtension
path: dist
- uses: montudor/action-zip@v0.1.0
with:
args: zip -qq -r ./builds/FirefoxExtension.zip ./dist
# Create Beta artifacts (Builds with the name changed to beta)
- name: Create Chrome Beta artifacts
run: npm run build:chrome -- --env.stream=beta
- uses: actions/upload-artifact@v1
with:
name: ChromeExtensionBeta
path: dist
- uses: montudor/action-zip@v0.1.0
with:
args: zip -qq -r ./builds/ChromeExtensionBeta.zip ./dist
- name: Create Firefox Beta artifacts
run: npm run build:firefox -- --env.stream=beta
- uses: actions/upload-artifact@v1
with:
name: FirefoxExtensionBeta
path: dist
- uses: montudor/action-zip@v0.1.0
with:
args: zip -qq -r ./builds/FirefoxExtensionBeta.zip ./dist

76
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,76 @@
name: Upload Release Build
on: release
jobs:
build:
name: Upload Release
runs-on: ubuntu-latest
steps:
# Initialization
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- run: npm install
- name: Copy configuration
run: cp config.json.example config.json
# Create Chrome artifacts
- name: Create Chrome artifacts
run: npm run build:chrome
- uses: actions/upload-artifact@v1
with:
name: ChromeExtension
path: dist
- run: mkdir ./builds
- uses: montudor/action-zip@v0.1.0
with:
args: zip -qq -r ./builds/ChromeExtension.zip ./dist
# Create Firefox artifacts
- name: Create Firefox artifacts
run: npm run build:firefox
- uses: actions/upload-artifact@v1
with:
name: FirefoxExtension
path: dist
- uses: montudor/action-zip@v0.1.0
with:
args: zip -qq -r ./builds/FirefoxExtension.zip ./dist
# Create Beta artifacts (Builds with the name changed to beta)
- name: Create Chrome Beta artifacts
run: npm run build:chrome -- --env.stream=beta
- uses: actions/upload-artifact@v1
with:
name: ChromeExtensionBeta
path: dist
- uses: montudor/action-zip@v0.1.0
with:
args: zip -qq -r ./builds/ChromeExtensionBeta.zip ./dist
- name: Create Firefox Beta artifacts
run: npm run build:firefox -- --env.stream=beta
- uses: actions/upload-artifact@v1
with:
name: FirefoxExtensionBeta
path: dist
- uses: montudor/action-zip@v0.1.0
with:
args: zip -qq -r ./builds/FirefoxExtensionBeta.zip ./dist
# Upload each release asset
- name: Upload to release
uses: Shopify/upload-to-release@master
with:
args: builds/ChromeExtension.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload to release
uses: Shopify/upload-to-release@master
with:
args: builds/FirefoxExtension.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

10
.gitignore vendored
View File

@@ -1,2 +1,8 @@
config.js
ignored
config.json
ignored
.idea/
node_modules
web-ext-artifacts
.vscode/
dist/
tmp/

View File

@@ -1,4 +1,8 @@
GNU GENERAL PUBLIC LICENSE
SponsorBlock Copyright (C) 2019 Ajay Ramachandran and other SponsorBlock contributors.
Please refer to the license below.
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
@@ -651,8 +655,9 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.

View File

@@ -1,15 +1,38 @@
![Logo](icons/LogoSponsorBlocker256px.png)
<br/><sub>Logo by [@munadikieh](https://github.com/munadikieh)</sub>
<p align="center">
<a href="https://sponsor.ajay.app"><img src="public/icons/LogoSponsorBlocker256px.png" alt="Logo"></img></a>
<br/>
<sub>Logo by <a href="https://github.com/munadikieh">@munadikieh</a></sub>
</p>
# SponsorBlock
<h1 align="center">SponsorBlock</h1>
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.
<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>
# Available for Chrome and Firefox
<p align="center">
<b>Unofficial Ports:</b>
<a href="https://github.com/ajayyy/SponsorBlock/wiki/Unofficial-Ports#mpv-media-player">MPV</a>
</p>
Chrome: https://chrome.google.com/webstore/detail/ajjollijmimolcncegpgkbilohbhjnhi
<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>
Firefox: https://addons.mozilla.org/addon/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.
Also support Invidio.us.
# Server
@@ -17,20 +40,38 @@ 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://api.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.
# Previous extension
# API
This project is partially based off of [this experimental extension](https://github.com/OfficialNoob/YTSponsorSkip). That extension has the basic video skipping functionality.
You can read the API docs [here](https://github.com/ajayyy/SponsorBlockServer#api-docs).
# 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.
You can load this project as an unpacked extension. Make sure to rename the `config.json.example` file to `config.json` 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. Use `npm run dev:firefox` for Firefox. This uses [`web-ext run`](https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#commands).
## Packing
Run `npm run build` to generate a packed Chrome extension.
Use `npm run build:firefox` to generate a Firefox extension.
The result is in `dist`.
# Credit
The awesome [Invidious API](https://github.com/omarroth/invidious/wiki/API) is used to grab the time the video was published.
The awesome [Invidious API](https://github.com/omarroth/invidious/wiki/API) previously was used.
Originally forked from [YTSponsorSkip](https://github.com/OfficialNoob/YTSponsorSkip), but zero code remains.
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>

View File

@@ -1,244 +0,0 @@
var previousVideoID = null
//the id of this user, randomly generated once per install
var userID = null;
//when a new tab is highlighted
chrome.tabs.onActivated.addListener(
function(activeInfo) {
chrome.tabs.get(activeInfo.tabId, function(tab) {
let id = getYouTubeVideoID(tab.url);
//if this even is a YouTube tab
if (id) {
videoIDChange(id, activeInfo.tabId);
}
})
}
);
//when a tab changes URLs
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (changeInfo != undefined && changeInfo.url != undefined) {
let id = getYouTubeVideoID(changeInfo.url);
//if URL changed and is youtube video message contentScript the video id
if (changeInfo.url && id) {
videoIDChange(id, tabId);
}
}
});
chrome.runtime.onMessage.addListener(function (request, sender, callback) {
if (request.message == "submitTimes") {
submitTimes(request.videoID, callback);
//this allows the callback to be called later by the submitTimes function
return true;
} else if (request.message == "addSponsorTime") {
addSponsorTime(request.time, request.videoID);
} else if (request.message == "getSponsorTimes") {
getSponsorTimes(request.videoID, function(sponsorTimes) {
callback({
sponsorTimes: sponsorTimes
})
});
//this allows the callback to be called later
return true;
} else if (request.message == "submitVote") {
submitVote(request.type, request.UUID, callback);
//this allows the callback to be called later
return true;
}
});
//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)
});
}
function addSponsorTime(time, videoID) {
getSponsorTimes(videoID, function(sponsorTimes) {
//add to sponsorTimes
if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) {
//it is an end time
sponsorTimes[sponsorTimes.length - 1][1] = time;
} else {
//it is a start time
let sponsorTimesIndex = sponsorTimes.length;
sponsorTimes[sponsorTimesIndex] = [];
sponsorTimes[sponsorTimesIndex][0] = time;
}
//save this info
let sponsorTimeKey = "sponsorTimes" + videoID;
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
});
}
function submitVote(type, UUID, callback) {
getUserID(function(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
});
} else if (error) {
//error while connect
callback({
successType: -1
});
}
})
})
}
function submitTimes(videoID, callback) {
//get the video times from storage
let sponsorTimeKey = 'sponsorTimes' + videoID;
chrome.storage.sync.get([sponsorTimeKey], function(result) {
let sponsorTimes = result[sponsorTimeKey];
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
//submit these times
for (let i = 0; i < sponsorTimes.length; i++) {
getUserID(function(userIDStorage) {
//submit the sponsorTime
sendRequestToServer('GET', "/api/postVideoSponsorTimes?videoID=" + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1]
+ "&userID=" + userIDStorage, function(xmlhttp, error) {
if (xmlhttp.readyState == 4 && !error) {
callback({
statusCode: xmlhttp.status
});
} else if (error) {
callback({
statusCode: -1
});
}
});
});
}
//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});
});
}
});
}
function videoIDChange(currentVideoID, tabId) {
//send a message to the content script
chrome.tabs.sendMessage(tabId, {
message: 'ytvideoid',
id: currentVideoID
});
//warn them if they had unsubmitted times
if (previousVideoID != null) {
//get the sponsor times from storage
let sponsorTimeKey = 'sponsorTimes' + previousVideoID;
chrome.storage.sync.get([sponsorTimeKey], function(result) {
let sponsorTimes = result[sponsorTimeKey];
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
//warn them that they have unsubmitted sponsor times
chrome.notifications.create("stillThere" + Math.random(), {
type: "basic",
title: "Do you want to submit the sponsor times for watch?v=" + 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"
});
}
//set the previous video id to the currentID
previousVideoID = currentVideoID;
});
} else {
previousVideoID = currentVideoID;
}
}
function getUserID(callback) {
if (userID != null) {
callback(userID);
return;
}
//if it is not cached yet, grab it from storage
chrome.storage.sync.get(["userID"], function(result) {
let userIDStorage = result.userID;
if (userIDStorage != undefined) {
userID = userIDStorage;
callback(userID);
} else {
//double check if a UUID hasn't been created since this was first called
if (userID != null) {
callback(userID);
return;
}
//generate a userID
userID = generateUUID();
//save this UUID
chrome.storage.sync.set({"userID": userID});
callback(userID);
}
});
}
function sendRequestToServer(type, address, callback) {
let xmlhttp = new XMLHttpRequest();
xmlhttp.open(type, serverAddress + address, true);
if (callback != undefined) {
xmlhttp.onreadystatechange = function () {
callback(xmlhttp, false);
};
xmlhttp.onerror = function(ev) {
callback(xmlhttp, true);
};
}
//submit this request
xmlhttp.send();
}
function getYouTubeVideoID(url) { // Return video id or false
var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
var match = url.match(regExp);
return (match && match[7].length == 11) ? match[7] : false;
}
//uuid generator function from https://gist.github.com/jed/982883
function generateUUID(a){return a?(a^Math.random()*16>>a/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,generateUUID)}

View File

@@ -1,3 +0,0 @@
//this file is loaded along iwth content.js
//this file sets the server to connect to, and is gitignored
var serverAddress = "https://sponsor.ajay.app";

4
config.json.example Normal file
View File

@@ -0,0 +1,4 @@
{
"serverAddress": "https://sponsor.ajay.app",
"serverAddressComment": "This specifies the default SponsorBlock server to conect to"
}

View File

@@ -1,835 +0,0 @@
//was sponsor data found when doing SponsorsLookup
var sponsorDataFound = false;
//the actual sponsorTimes if loaded and UUIDs associated with them
var sponsorTimes = null;
var UUIDs = null;
//what video id are these sponsors for
var sponsorVideoID = null;
if(id = getYouTubeVideoID(document.URL)){ // Direct Links
videoIDChange(id);
}
//the video
var v;
//the last time looked at (used to see if this time is in the interval)
var lastTime = -1;
//the actual time (not video time) that the last skip happened
var lastUnixTimeSkipped = -1;
//the last time in the video a sponsor was skipped
//used for the go back button
var lastSponsorTimeSkipped = null;
//used for ratings
var lastSponsorTimeSkippedUUID = null;
//if showing the start sponsor button or the end sponsor button on the player
var showingStartSponsor = true;
//should the video controls buttons be added
var hideVideoPlayerControls = false;
//becomes true when isInfoFound is called
//this is used to close the popup on YouTube when the other popup opens
var popupInitialised = false;
//should view counts be tracked
var trackViewCount = false;
chrome.storage.sync.get(["trackViewCount"], function(result) {
let trackViewCountStorage = result.trackViewCount;
if (trackViewCountStorage != undefined) {
trackViewCount = trackViewCountStorage;
} else {
trackViewCount = true;
}
});
//if the notice should not be shown
//happens when the user click's the "Don't show notice again" button
var dontShowNotice = false;
chrome.storage.sync.get(["dontShowNoticeAgain"], function(result) {
let dontShowNoticeAgain = result.dontShowNoticeAgain;
if (dontShowNoticeAgain != undefined) {
dontShowNotice = dontShowNoticeAgain;
}
});
chrome.runtime.onMessage.addListener( // Detect URL Changes
function(request, sender, sendResponse) {
//message from background script
if (request.message == "ytvideoid") {
videoIDChange(request.id);
}
//messages from popup script
if (request.message == "sponsorStart") {
sponsorMessageStarted(sendResponse);
}
if (request.message == "isInfoFound") {
//send the sponsor times along with if it's found
sendResponse({
found: sponsorDataFound,
sponsorTimes: sponsorTimes,
UUIDs: UUIDs
});
if (popupInitialised && document.getElementById("sponsorBlockPopupContainer") != null) {
//the popup should be closed now that another is opening
closeInfoMenu();
}
popupInitialised = true;
}
if (request.message == "getVideoID") {
sendResponse({
videoID: getYouTubeVideoID(document.URL)
})
}
if (request.message == "showNoticeAgain") {
dontShowNotice = false;
}
if (request.message == "changeStartSponsorButton") {
changeStartSponsorButton(request.showStartSponsor, request.uploadButtonVisible);
}
if (request.message == "changeVideoPlayerControlsVisibility") {
hideVideoPlayerControls = request.value;
updateVisibilityOfPlayerControlsButton();
}
if (request.message == "trackViewCount") {
trackViewCount = request.value;
}
});
//check for hotkey pressed
document.onkeydown = function(e){
e = e || window.event;
var key = e.which || e.keyCode;
let video = document.getElementById("movie_player");
//is the video in focus, otherwise they could be typing a comment
if (document.activeElement === video) {
if(key == 186){
//semicolon
startSponsorClicked();
} else if (key == 222) {
//single quote
submitSponsorTimes();
}
}
}
function videoIDChange(id) {
//not a url change
if (sponsorVideoID == id){
return;
}
//reset last sponsor times
lastTime = -1;
lastUnixTimeSkipped = -1;
//reset sponsor times
sponsorTimes = null;
UUIDs = null;
sponsorVideoID = id;
//reset sponsor data found check
sponsorDataFound = false;
sponsorsLookup(id);
//see if the onvideo control image needs to be changed
chrome.runtime.sendMessage({
message: "getSponsorTimes",
videoID: id
}, function(response) {
if (response != undefined) {
let sponsorTimes = response.sponsorTimes;
if (sponsorTimes != null && sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length >= 2) {
changeStartSponsorButton(true, true);
} else if (sponsorTimes != null && sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) {
changeStartSponsorButton(false, true);
} else {
changeStartSponsorButton(true, true);
document.getElementById("submitButton").style.display = "none";
}
}
});
//see if video control buttons should be added
chrome.storage.sync.get(["hideVideoPlayerControls"], function(result) {
if (result.hideVideoPlayerControls != undefined) {
hideVideoPlayerControls = result.hideVideoPlayerControls;
}
updateVisibilityOfPlayerControlsButton();
});
}
function sponsorsLookup(id) {
v = document.querySelector('video') // Youtube video player
//check database for sponsor times
sendRequestToServer('GET', "/api/getVideoSponsorTimes?videoID=" + id, function(xmlhttp) {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
sponsorDataFound = true;
sponsorTimes = JSON.parse(xmlhttp.responseText).sponsorTimes;
UUIDs = JSON.parse(xmlhttp.responseText).UUIDs;
// If the sponsor data exists, add the event to run on the videos "ontimeupdate"
v.ontimeupdate = function () {
sponsorCheck(sponsorTimes);
};
} else if (xmlhttp.readyState == 4) {
sponsorDataFound = false;
//check if this video was uploaded recently
//use the invidious api to get the time published
sendRequestToCustomServer('GET', "https://invidio.us/api/v1/videos/" + id, function(xmlhttp, error) {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
let unixTimePublished = JSON.parse(xmlhttp.responseText).published;
//if less than 3 days old
if ((Date.now() / 1000) - unixTimePublished < 259200) {
setTimeout(() => sponsorsLookup(id), 10000);
}
}
});
}
});
}
function sponsorCheck(sponsorTimes) { // Video skipping
//see if any sponsor start time was just passed
for (let i = 0; i < sponsorTimes.length; i++) {
//this means part of the video was just skipped
if (Math.abs(v.currentTime - lastTime) > 1 && lastTime != -1) {
//make lastTime as if the video was playing normally
lastTime = v.currentTime - 0.0001;
}
let currentTime = Date.now();
//If the sponsor time is in between these times, skip it
//Checks if the last time skipped to is not too close to now, to make sure not to get too many
// sponsor times in a row (from one troll)
//the last term makes 0 second start times possible
if ((Math.abs(v.currentTime - sponsorTimes[i][0]) < 0.3 && sponsorTimes[i][0] >= lastTime && sponsorTimes[i][0] <= v.currentTime
&& (lastUnixTimeSkipped == -1 || currentTime - lastUnixTimeSkipped > 500)) || (lastTime == -1 && sponsorTimes[i][0] == 0)) {
//skip it
v.currentTime = sponsorTimes[i][1];
lastSponsorTimeSkipped = sponsorTimes[i][0];
let currentUUID = UUIDs[i];
lastSponsorTimeSkippedUUID = currentUUID;
//send out the message saying that a sponsor message was skipped
openSkipNotice(currentUUID);
setTimeout(() => closeSkipNotice(currentUUID), 7000);
//send telemetry that a this sponsor was skipped happened
if (trackViewCount) {
sendRequestToServer("GET", "/api/viewedVideoSponsorTime?UUID=" + currentUUID);
}
}
}
//don't keep track until they are loaded in
if (sponsorTimes.length > 0) {
lastTime = v.currentTime;
}
}
function goBackToPreviousTime(UUID) {
if (sponsorTimes != null) {
//add a tiny bit of time to make sure it is not skipped again
v.currentTime = sponsorTimes[UUIDs.indexOf(UUID)][0] + 0.001;
closeSkipNotice(UUID);
}
}
//Adds a sponsorship starts button to the player controls
function addPlayerControlsButton() {
if (document.getElementById("startSponsorButton") != null) {
//it's already added
return;
}
let startSponsorButton = document.createElement("button");
startSponsorButton.id = "startSponsorButton";
startSponsorButton.className = "ytp-button playerButton";
startSponsorButton.setAttribute("title", "Sponsor Starts Now");
startSponsorButton.addEventListener("click", startSponsorClicked);
let startSponsorImage = document.createElement("img");
startSponsorImage.id = "startSponsorImage";
startSponsorImage.className = "playerButtonImage";
startSponsorImage.src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png");
//add the image to the button
startSponsorButton.appendChild(startSponsorImage);
let referenceNode = document.getElementsByClassName("ytp-right-controls")[0];
referenceNode.prepend(startSponsorButton);
}
function removePlayerControlsButton() {
document.getElementById("startSponsorButton").style.display = "none";
document.getElementById("submitButton").style.display = "none";
}
//adds or removes the player controls button to what it should be
function updateVisibilityOfPlayerControlsButton() {
addPlayerControlsButton();
addInfoButton();
addSubmitButton();
if (hideVideoPlayerControls) {
removePlayerControlsButton();
}
}
function startSponsorClicked() {
//it can't update to this info yet
closeInfoMenu();
toggleStartSponsorButton();
//send back current time with message
chrome.runtime.sendMessage({
message: "addSponsorTime",
time: v.currentTime,
videoID: getYouTubeVideoID(document.URL)
});
}
function changeStartSponsorButton(showStartSponsor, uploadButtonVisible) {
if (showStartSponsor) {
showingStartSponsor = true;
document.getElementById("startSponsorImage").src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png");
document.getElementById("startSponsorButton").setAttribute("title", "Sponsor Starts Now");
if (document.getElementById("startSponsorImage").style.display != "none" && uploadButtonVisible) {
document.getElementById("submitButton").style.display = "unset";
} else if (!uploadButtonVisible) {
//disable submit button
document.getElementById("submitButton").style.display = "none";
}
} else {
showingStartSponsor = false;
document.getElementById("startSponsorImage").src = chrome.extension.getURL("icons/PlayerStopIconSponsorBlocker256px.png");
document.getElementById("startSponsorButton").setAttribute("title", "Sponsor Ends Now");
//disable submit button
document.getElementById("submitButton").style.display = "none";
}
}
function toggleStartSponsorButton() {
changeStartSponsorButton(!showingStartSponsor, true);
}
//shows the info button on the video player
function addInfoButton() {
if (document.getElementById("infoButton") != null) {
//it's already added
return;
}
//make a submit button
let infoButton = document.createElement("button");
infoButton.id = "infoButton";
infoButton.className = "ytp-button playerButton";
infoButton.setAttribute("title", "Open SponsorBlock Popup");
infoButton.addEventListener("click", openInfoMenu);
let infoImage = document.createElement("img");
infoImage.id = "infoButtonImage";
infoImage.className = "playerButtonImage";
infoImage.src = chrome.extension.getURL("icons/PlayerInfoIconSponsorBlocker256px.png");
//add the image to the button
infoButton.appendChild(infoImage);
let referenceNode = document.getElementsByClassName("ytp-right-controls")[0];
referenceNode.prepend(infoButton);
}
//shows the submit button on the video player
function addSubmitButton() {
if (document.getElementById("submitButton") != null) {
//it's already added
return;
}
//make a submit button
let submitButton = document.createElement("button");
submitButton.id = "submitButton";
submitButton.className = "ytp-button playerButton";
submitButton.setAttribute("title", "Submit Sponsor Times");
submitButton.addEventListener("click", submitSponsorTimes);
//hide it at the start
submitButton.style.display = "none";
let submitImage = document.createElement("img");
submitImage.id = "submitButtonImage";
submitImage.className = "playerButtonImage";
submitImage.src = chrome.extension.getURL("icons/PlayerUploadIconSponsorBlocker256px.png");
//add the image to the button
submitButton.appendChild(submitImage);
let referenceNode = document.getElementsByClassName("ytp-right-controls")[0];
referenceNode.prepend(submitButton);
}
function openInfoMenu() {
if (document.getElementById("sponsorBlockPopupContainer") != null) {
//it's already added
return;
}
popupInitialised = false;
//hide info button
document.getElementById("infoButton").style.display = "none";
let popup = document.createElement("div");
popup.id = "sponsorBlockPopupContainer";
let popupFrame = document.createElement("iframe");
popupFrame.id = "sponsorBlockPopupFrame"
popupFrame.src = chrome.extension.getURL("popup.html");
popupFrame.className = "popup";
//close button
let closeButton = document.createElement("div");
closeButton.innerText = "Close Popup";
closeButton.classList = "smallLink";
closeButton.setAttribute("align", "center");
closeButton.addEventListener("click", closeInfoMenu);
popup.appendChild(closeButton);
popup.appendChild(popupFrame);
let parentNode = document.getElementById("secondary");
parentNode.prepend(popup);
}
function closeInfoMenu() {
let popup = document.getElementById("sponsorBlockPopupContainer");
if (popup != null) {
popup.remove();
//show info button
document.getElementById("infoButton").style.display = "unset";
}
}
//Opens the notice that tells the user that a sponsor was just skipped
function openSkipNotice(UUID){
if (dontShowNotice) {
//don't show, return
return;
}
//check if page is loaded yet (for 0 second sponsors, the page might not be loaded yet)
//it looks for the view count div and sees if it is full yet
//querySelectorAll is being used like findElementById for multiple objects, because for
//some reason YouTube has put more than one object with one ID.
let viewCountNode = document.querySelectorAll("#count");
//check to see if the length is over zero, otherwise it's a different YouTube theme probably
if (viewCountNode.length > 0) {
//check if any of these have text
let viewCountVisible = false;
for (let i = 0; i < viewCountNode.length; i++) {
if (viewCountNode[i].innerText != null) {
viewCountVisible = true;
break;
}
}
if (!viewCountVisible) {
//this is the new YouTube layout and it is still loading
//wait a bit for opening the notice
setTimeout(() => openSkipNotice(UUID), 200);
return;
}
}
let amountOfPreviousNotices = document.getElementsByClassName("sponsorSkipNotice").length;
if (amountOfPreviousNotices > 0) {
//already exists
let previousNotice = document.getElementsByClassName("sponsorSkipNotice")[0];
previousNotice.classList.add("secondSkipNotice")
}
let noticeElement = document.createElement("div");
//what sponsor time this is about
noticeElement.id = "sponsorSkipNotice" + UUID;
noticeElement.classList.add("sponsorSkipObject");
noticeElement.classList.add("sponsorSkipNotice");
noticeElement.style.zIndex = 5 + amountOfPreviousNotices;
let logoElement = document.createElement("img");
logoElement.id = "sponsorSkipLogo" + UUID;
logoElement.className = "sponsorSkipLogo";
logoElement.src = chrome.extension.getURL("icons/LogoSponsorBlocker256px.png");
let noticeMessage = document.createElement("div");
noticeMessage.id = "sponsorSkipMessage" + UUID;
noticeMessage.classList.add("sponsorSkipMessage");
noticeMessage.classList.add("sponsorSkipObject");
noticeMessage.innerText = "Hey, you just skipped a sponsor!";
let noticeInfo = document.createElement("p");
noticeInfo.id = "sponsorSkipInfo" + UUID;
noticeInfo.classList.add("sponsorSkipInfo");
noticeInfo.classList.add("sponsorSkipObject");
noticeInfo.innerText = "This message will disapear in 7 seconds";
//thumbs up and down buttons
let voteButtonsContainer = document.createElement("div");
voteButtonsContainer.id = "sponsorTimesVoteButtonsContainer" + UUID;
voteButtonsContainer.setAttribute("align", "center");
let upvoteButton = document.createElement("img");
upvoteButton.id = "sponsorTimesUpvoteButtonsContainer" + UUID;
upvoteButton.className = "sponsorSkipObject voteButton";
upvoteButton.src = chrome.extension.getURL("icons/upvote.png");
upvoteButton.addEventListener("click", () => vote(1, UUID));
let downvoteButton = document.createElement("img");
downvoteButton.id = "sponsorTimesDownvoteButtonsContainer" + UUID;
downvoteButton.className = "sponsorSkipObject voteButton";
downvoteButton.src = chrome.extension.getURL("icons/downvote.png");
downvoteButton.addEventListener("click", () => vote(0, UUID));
//add thumbs up and down buttons to the container
voteButtonsContainer.appendChild(upvoteButton);
voteButtonsContainer.appendChild(downvoteButton);
let buttonContainer = document.createElement("div");
buttonContainer.setAttribute("align", "center");
let goBackButton = document.createElement("button");
goBackButton.innerText = "Go back";
goBackButton.className = "sponsorSkipButton";
goBackButton.addEventListener("click", () => goBackToPreviousTime(UUID));
let hideButton = document.createElement("button");
hideButton.innerText = "Dismiss";
hideButton.className = "sponsorSkipButton";
hideButton.addEventListener("click", () => closeSkipNotice(UUID));
let dontShowAgainButton = document.createElement("button");
dontShowAgainButton.innerText = "Don't Show This Again";
dontShowAgainButton.className = "sponsorSkipDontShowButton";
dontShowAgainButton.addEventListener("click", dontShowNoticeAgain);
buttonContainer.appendChild(goBackButton);
buttonContainer.appendChild(hideButton);
buttonContainer.appendChild(document.createElement("br"));
buttonContainer.appendChild(document.createElement("br"));
buttonContainer.appendChild(dontShowAgainButton);
noticeElement.appendChild(logoElement);
noticeElement.appendChild(noticeMessage);
noticeElement.appendChild(noticeInfo);
noticeElement.appendChild(voteButtonsContainer);
noticeElement.appendChild(buttonContainer);
let referenceNode = document.getElementById("info");
if (referenceNode == null) {
//old YouTube
referenceNode = document.getElementById("watch-header");
}
referenceNode.prepend(noticeElement);
}
function afterDownvote(UUID) {
//change text to say thanks for voting
//remove buttons
let upvoteButton = document.getElementById("sponsorTimesUpvoteButtonsContainer" + UUID);
let downvoteButton = document.getElementById("sponsorTimesDownvoteButtonsContainer" + UUID);
if (upvoteButton != null) {
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(upvoteButton);
}
if (downvoteButton != null) {
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(downvoteButton);
}
let previousInfoMessage = document.getElementById("sponsorTimesInfoMessage" + UUID);
if (previousInfoMessage != null) {
//remove it
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(previousInfoMessage);
}
//add thanks for voting text
let thanksForVotingText = document.createElement("p");
thanksForVotingText.id = "sponsorTimesThanksForVotingText";
thanksForVotingText.innerText = "Thanks for voting!"
//add extra info for voting
let thanksForVotingInfoText = document.createElement("p");
thanksForVotingInfoText.id = "sponsorTimesThanksForVotingInfoText";
thanksForVotingInfoText.innerText = "Hit go back to get to where you came from."
//add element to div
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).appendChild(thanksForVotingText);
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).appendChild(thanksForVotingInfoText);
}
function addLoadingInfo(message, UUID) {
//change text to say thanks for message
//remove buttons
let upvoteButton = document.getElementById("sponsorTimesUpvoteButtonsContainer" + UUID);
let downvoteButton = document.getElementById("sponsorTimesDownvoteButtonsContainer" + UUID);
if (upvoteButton != null) {
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(upvoteButton);
}
if (downvoteButton != null) {
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(downvoteButton);
}
let previousInfoMessage = document.getElementById("sponsorTimesInfoMessage" + UUID);
if (previousInfoMessage != null) {
//remove it
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(previousInfoMessage);
}
//add thanks for voting text
let thanksForVotingText = document.createElement("p");
thanksForVotingText.id = "sponsorTimesInfoMessage" + UUID;
thanksForVotingText.className = "sponsorTimesInfoMessage";
thanksForVotingText.innerText = message;
//add element to div
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).appendChild(thanksForVotingText);
}
function vote(type, UUID) {
//add loading info
addLoadingInfo("Loading...", UUID)
chrome.runtime.sendMessage({
message: "submitVote",
type: type,
UUID: UUID
}, function(response) {
if (response != undefined) {
//see if it was a success or failure
if (response.successType == 1) {
//success
if (type == 0) {
afterDownvote(UUID);
} else if (type == 1) {
closeSkipNotice(UUID);
}
} else if (response.successType == 0) {
//failure: duplicate vote
addLoadingInfo("It seems you've already voted before", UUID)
} else if (response.successType == -1) {
//failure: duplicate vote
addLoadingInfo("A connection error has occured.", UUID)
}
}
});
}
//Closes the notice that tells the user that a sponsor was just skipped for this UUID
function closeSkipNotice(UUID){
let notice = document.getElementById("sponsorSkipNotice" + UUID);
if (notice != null) {
notice.remove();
}
}
//Closes all notices that tell the user that a sponsor was just skipped
function closeAllSkipNotices(){
let notices = document.getElementsByClassName("sponsorSkipNotice");
for (let i = 0; i < notices.length; i++) {
notices[i].remove();
}
}
function dontShowNoticeAgain() {
chrome.storage.sync.set({"dontShowNoticeAgain": true});
dontShowNotice = true;
closeAllSkipNotices();
}
function sponsorMessageStarted(callback) {
let v = document.querySelector('video');
//send back current time
callback({
time: v.currentTime
})
//update button
toggleStartSponsorButton();
}
function submitSponsorTimes() {
if (document.getElementById("submitButton").style.display == "none") {
//don't submit, not ready
return;
}
//it can't update to this info yet
closeInfoMenu();
let currentVideoID = getYouTubeVideoID(document.URL);
let sponsorTimeKey = 'sponsorTimes' + currentVideoID;
chrome.storage.sync.get([sponsorTimeKey], function(result) {
let sponsorTimes = result[sponsorTimeKey];
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
let confirmMessage = "Are you sure you want to submit this?\n\n" + getSponsorTimesMessage(sponsorTimes);
confirmMessage += "\n\nTo see more information, open the popup by clicking the extensions icon in the top right corner."
if(!confirm(confirmMessage)) return;
sendSubmitMessage();
}
});
}
//send the message to the background js
//called after all the checks have been made that it's okay to do so
function sendSubmitMessage(){
//add loading animation
document.getElementById("submitButtonImage").src = chrome.extension.getURL("icons/PlayerUploadIconSponsorBlocker256px.png");
document.getElementById("submitButton").style.animation = "rotate 1s 0s infinite";
let currentVideoID = getYouTubeVideoID(document.URL);
chrome.runtime.sendMessage({
message: "submitTimes",
videoID: currentVideoID
}, function(response) {
if (response != undefined) {
if (response.statusCode == 200) {
//hide loading message
let submitButton = document.getElementById("submitButton");
//finish this animation
submitButton.style.animation = "rotate 1s";
//when the animation is over, hide the button
submitButton.addEventListener("animationend", function() {
submitButton.style.animation = "unset";
submitButton.style.display = "none";
});
//clear the sponsor times
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
chrome.storage.sync.set({[sponsorTimeKey]: []});
} else {
//for a more detailed error message, they should check the popup
//show that the upload failed
document.getElementById("submitButton").style.animation = "unset";
document.getElementById("submitButtonImage").src = chrome.extension.getURL("icons/PlayerUploadFailedIconSponsorBlocker256px.png");
}
}
});
}
//get the message that visually displays the video times
function getSponsorTimesMessage(sponsorTimes) {
let sponsorTimesMessage = "";
for (let i = 0; i < sponsorTimes.length; i++) {
for (let s = 0; s < sponsorTimes[i].length; s++) {
let timeMessage = getFormattedTime(sponsorTimes[i][s]);
//if this is an end time
if (s == 1) {
timeMessage = " to " + timeMessage;
} else if (i > 0) {
//add commas if necessary
timeMessage = ", " + timeMessage;
}
sponsorTimesMessage += timeMessage;
}
}
return sponsorTimesMessage;
}
//converts time in seconds to minutes:seconds
function getFormattedTime(seconds) {
let minutes = Math.floor(seconds / 60);
let secondsDisplay = Math.round(seconds - minutes * 60);
if (secondsDisplay < 10) {
//add a zero
secondsDisplay = "0" + secondsDisplay;
}
let formatted = minutes+ ":" + secondsDisplay;
return formatted;
}
function sendRequestToServer(type, address, callback) {
let xmlhttp = new XMLHttpRequest();
xmlhttp.open(type, serverAddress + address, true);
if (callback != undefined) {
xmlhttp.onreadystatechange = function () {
callback(xmlhttp, false);
};
xmlhttp.onerror = function(ev) {
callback(xmlhttp, true);
};
}
//submit this request
xmlhttp.send();
}
function sendRequestToCustomServer(type, fullAddress, callback) {
let xmlhttp = new XMLHttpRequest();
xmlhttp.open(type, fullAddress, true);
if (callback != undefined) {
xmlhttp.onreadystatechange = function () {
callback(xmlhttp, false);
};
xmlhttp.onerror = function(ev) {
callback(xmlhttp, true);
};
}
//submit this request
xmlhttp.send();
}
function getYouTubeVideoID(url) { // Returns with video id else returns false
var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
var match = url.match(regExp);
var id = new URL(url).searchParams.get("v");
return (match && match[7].length == 11) ? id : false;
}

10
crowdin.yml Normal file
View 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"

View File

@@ -1,62 +0,0 @@
{
"name": "SponsorBlock - YouTube Sponsorship Blocker",
"short_name": "SponsorBlock",
"version": "1.0.12",
"description": "Skip over sponsorship on YouTube videos. Report sponsors on videos you watch to save the time of others.",
"content_scripts": [
{
"matches": [
"https://*.youtube.com/*"
],
"js": [
"config.js",
"content.js"
],
"css": [
"content.css",
"./libs/Source+Sans+Pro.css"
]
}
],
"web_accessible_resources": [
"icons/LogoSponsorBlocker256px.png",
"icons/IconSponsorBlocker256px.png",
"icons/PlayerStartIconSponsorBlocker256px.png",
"icons/PlayerStopIconSponsorBlocker256px.png",
"icons/PlayerUploadIconSponsorBlocker256px.png",
"icons/PlayerUploadFailedIconSponsorBlocker256px.png",
"icons/upvote.png",
"icons/downvote.png",
"icons/PlayerInfoIconSponsorBlocker256px.png"
],
"permissions": [
"tabs",
"storage",
"notifications",
"https://sponsor.ajay.app/*"
],
"browser_action": {
"default_title": "SponsorBlock",
"default_popup": "popup.html"
},
"background": {
"scripts":[
"config.js",
"background.js"
]
},
"icons": {
"16": "icons/IconSponsorBlocker16px.png",
"32": "icons/IconSponsorBlocker32px.png",
"64": "icons/LogoSponsorBlocker64px.png",
"128": "icons/LogoSponsorBlocker128px.png",
"256": "icons/LogoSponsorBlocker256px.png"
},
"browser_specific_settings": {
"gecko": {
"id": "sponsorBlocker@ajay.app",
"strict_min_version": "57.0"
}
},
"manifest_version": 2
}

BIN
icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

8
jest.config.js Normal file
View File

@@ -0,0 +1,8 @@
module.exports = {
"roots": [
"src"
],
"transform": {
"^.+\\.ts$": "ts-jest"
},
};

View File

@@ -1,57 +0,0 @@
{
"name": "SponsorBlock for YouTube - Skip Sponsorships",
"short_name": "SponsorBlock",
"version": "1.0.15",
"description": "Skip over sponsorship on YouTube videos. Report sponsors on videos you watch to save the time of others.",
"content_scripts": [
{
"matches": [
"https://*.youtube.com/*"
],
"js": [
"config.js",
"content.js"
],
"css": [
"content.css",
"./libs/Source+Sans+Pro.css"
]
}
],
"web_accessible_resources": [
"icons/LogoSponsorBlocker256px.png",
"icons/IconSponsorBlocker256px.png",
"icons/PlayerStartIconSponsorBlocker256px.png",
"icons/PlayerStopIconSponsorBlocker256px.png",
"icons/PlayerUploadIconSponsorBlocker256px.png",
"icons/PlayerUploadFailedIconSponsorBlocker256px.png",
"icons/upvote.png",
"icons/downvote.png",
"icons/PlayerInfoIconSponsorBlocker256px.png",
"popup.html"
],
"permissions": [
"tabs",
"storage",
"notifications",
"https://sponsor.ajay.app/*"
],
"browser_action": {
"default_title": "SponsorBlock",
"default_popup": "popup.html"
},
"background": {
"scripts":[
"config.js",
"background.js"
]
},
"icons": {
"16": "icons/IconSponsorBlocker16px.png",
"32": "icons/IconSponsorBlocker32px.png",
"64": "icons/LogoSponsorBlocker64px.png",
"128": "icons/LogoSponsorBlocker128px.png",
"256": "icons/LogoSponsorBlocker256px.png"
},
"manifest_version": 2
}

View File

@@ -0,0 +1,4 @@
{
"name": "BETA - SponsorBlock"
}

View File

@@ -0,0 +1,8 @@
{
"optional_permissions": [
"declarativeContent"
],
"background": {
"persistent": false
}
}

View File

@@ -0,0 +1,8 @@
{
"browser_specific_settings": {
"gecko": {
"id": "sponsorBlockerBETA@ajay.app"
}
}
}

View File

@@ -0,0 +1,7 @@
{
"browser_specific_settings": {
"gecko": {
"id": "sponsorBlocker@ajay.app"
}
}
}

70
manifest/manifest.json Normal file
View File

@@ -0,0 +1,70 @@
{
"name": "__MSG_fullName__",
"short_name": "__MSG_Name__",
"version": "1.2.20",
"default_locale": "en",
"description": "__MSG_Description__",
"content_scripts": [{
"run_at": "document_start",
"matches": [
"https://*.youtube.com/*",
"https://www.youtube-nocookie.com/embed/*"
],
"all_frames": true,
"js": [
"./js/vendor.js",
"./js/content.js"
],
"css": [
"content.css",
"./libs/Source+Sans+Pro.css",
"popup.css"
]
}],
"web_accessible_resources": [
"icons/LogoSponsorBlocker256px.png",
"icons/IconSponsorBlocker256px.png",
"icons/PlayerStartIconSponsorBlocker256px.png",
"icons/PlayerStopIconSponsorBlocker256px.png",
"icons/PlayerUploadIconSponsorBlocker256px.png",
"icons/PlayerUploadFailedIconSponsorBlocker256px.png",
"icons/upvote.png",
"icons/downvote.png",
"icons/report.png",
"icons/close.png",
"icons/PlayerInfoIconSponsorBlocker256px.png",
"icons/PlayerDeleteIconSponsorBlocker256px.png",
"popup.html",
"content.css"
],
"permissions": [
"storage",
"notifications",
"https://sponsor.ajay.app/*"
],
"optional_permissions": [
"*://*/*"
],
"browser_action": {
"default_title": "__MSG_Name__",
"default_popup": "popup.html"
},
"background": {
"scripts":[
"./js/vendor.js",
"./js/background.js"
]
},
"icons": {
"16": "icons/IconSponsorBlocker16px.png",
"32": "icons/IconSponsorBlocker32px.png",
"64": "icons/LogoSponsorBlocker64px.png",
"128": "icons/LogoSponsorBlocker128px.png",
"256": "icons/LogoSponsorBlocker256px.png"
},
"options_ui": {
"page": "options/options.html",
"open_in_tab": true
},
"manifest_version": 2
}

12847
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

50
package.json Normal file
View File

@@ -0,0 +1,50 @@
{
"name": "sponsorblock",
"version": "1.0.0",
"description": "",
"main": "background.js",
"dependencies": {
"concurrently": "^5.1.0"
},
"devDependencies": {
"web-ext": "^4.0.0",
"@types/chrome": "0.0.91",
"@types/firefox-webext-browser": "70.0.1",
"@types/jest": "^24.0.23",
"@types/jquery": "^3.3.31",
"copy-webpack-plugin": "^5.0.5",
"jest": "^24.9.0",
"ts-jest": "^24.2.0",
"rimraf": "^3.0.0",
"ts-loader": "^6.2.1",
"typescript": "~3.7.3",
"webpack": "~4.41.2",
"webpack-cli": "~3.3.10",
"webpack-merge": "~4.2.2"
},
"scripts": {
"web-run": "npm run web-run:chrome",
"web-run:firefox": "cd dist && web-ext run --start-url https://addons.mozilla.org/firefox/addon/ublock-origin/",
"web-run:chrome": "cd dist && web-ext run --start-url https://chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm -t chromium",
"build": "npm run build:chrome",
"build:chrome": "webpack --env.browser=chrome --config webpack/webpack.prod.js",
"build:firefox": "webpack --env.browser=firefox --config webpack/webpack.prod.js",
"build:dev": "npm run build:dev:chrome",
"build:dev:chrome": "webpack --env.browser=chrome --config webpack/webpack.dev.js",
"build:dev:firefox": "webpack --env.browser=firefox --config webpack/webpack.dev.js",
"build:watch": "npm run build:watch:chrome",
"build:watch:chrome": "webpack --env.browser=chrome --config webpack/webpack.dev.js --watch",
"build:watch:firefox": "webpack --env.browser=firefox --config webpack/webpack.dev.js --watch",
"dev": "npm run build:dev && concurrently \"npm run web-run\" \"npm run build:watch\"",
"dev:firefox": "npm run build:dev:firefox && concurrently \"npm run web-run:firefox\" \"npm run build:watch:firefox\"",
"clean": "rimraf dist",
"test": "npx jest"
},
"repository": {
"type": "git",
"url": "git+https://github.com/ajayyy/SponsorBlock.git"
},
"author": "Ajay Ramachandran",
"license": "GPL-3.0-only",
"private": true
}

145
popup.css
View File

@@ -1,145 +0,0 @@
* {
font-family: 'Source Sans Pro', sans-serif;
}
h1 {
margin-top: 0px;
}
body {
font-size: 14px;
min-width: 300px;
background-color: #ffd9d9;
}
.recordingSubtitle {
margin-bottom: 10px;
}
.voteButton {
height: 32px;
margin-right: 15px;
cursor: pointer;
}
.voteButton:hover {
filter: brightness(80%);
}
#discordButtonContainer {
font-size: 12px;
}
.smallLink {
font-size: 10px;
text-decoration: underline;
cursor: pointer;
}
.greenButton {
background-color:#ec1c1c;
-moz-border-radius:28px;
-webkit-border-radius:28px;
border-radius:28px;
border:1px solid #d31919;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-size:16px;
padding:8px 37px;
text-decoration:none;
text-shadow:0px 0px 0px #662727;
}
.greenButton:hover {
background-color:#bf2a2a;
}
.greenButton:focus {
outline: none;
background-color:#bf2a2a;
}
.greenButton:active {
position:relative;
top:1px;
}
.dangerButton {
-moz-box-shadow:inset 0px 1px 0px 0px #cf866c;
-webkit-box-shadow:inset 0px 1px 0px 0px #cf866c;
box-shadow:inset 0px 1px 0px 0px #cf866c;
background-color:#d0451b;
-moz-border-radius:3px;
-webkit-border-radius:3px;
border-radius:3px;
border:1px solid #942911;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-size:13px;
padding:6px 24px;
text-decoration:none;
text-shadow:0px 1px 0px #854629;
}
.dangerButton:hover {
background-color:#bc3315;
}
.dangerButton:focus {
outline: none;
background-color:#bc3315;
}
.dangerButton:active {
position:relative;
top:1px;
}
.warningButton {
-moz-box-shadow:inset 0px 1px 0px 0px #cfbd6c;
-webkit-box-shadow:inset 0px 1px 0px 0px #cfbd6c;
box-shadow:inset 0px 1px 0px 0px #cfbd6c;
background-color:#d0821b;
-moz-border-radius:3px;
-webkit-border-radius:3px;
border-radius:3px;
border:1px solid #948b11;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-size:13px;
padding:6px 24px;
text-decoration:none;
text-shadow:0px 1px 0px #856829;
}
.warningButton:hover {
background-color:#bc8215;
}
.warningButton:focus {
outline: none;
background-color:#bc8215;
}
.warningButton:active {
position:relative;
top:1px;
}
.smallButton {
background-color:#f9902d;
-moz-border-radius:3px;
-webkit-border-radius:3px;
border-radius:3px;
border:1px solid #f9a72d;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-size:14px;
padding:6px 10px;
text-decoration:none;
}
.smallButton:hover {
background-color:#fa9806;
}
.smallButton:focus {
outline: none;
background-color:#fa9806;
}
.smallButton:active {
position:relative;
top:1px;
}

View File

@@ -1,164 +0,0 @@
<html>
<head>
<title>Set Page Color Popup</title>
<link rel="stylesheet" type="text/css" href="/libs/Source+Sans+Pro.css"/>
<link rel="stylesheet" type="text/css" href="popup.css"/>
</head>
<center>
<div id="app">
<img src="icons/LogoSponsorBlocker256px.png" height="64px"/>
<h1>SponsorBlock</h1>
<!-- Loading text -->
<p id="loadingIndicator">Loading...</p>
<!-- Hidden until loading complete -->
<div id="mainControls" class="main" style="display: none">
<!-- If the video was found in the database -->
<div id="videoFound">
</div>
<div id="downloadedSponsorMessageTimes">
</div>
<br/>
<button id="reportAnIssue" class="dangerButton">Vote On A Sponsor Time</button>
<div id="issueReporterContainer" style="display: none">
<h3 style="margin-top: 0px">Vote On A Sponsor Time</h3>
<div id="issueReporterTimeButtons">
</div>
</div>
<h2 class="recordingSubtitle">Record the times of a sponsorship</h2>
<p>
<span id=sponsorTimesContributionsContainer style="display: none">
So far, you've submitted
<span id="sponsorTimesContributionsDisplay">
0
</span>
<span id="sponsorTimesContributionsDisplayEndWord">
sponsors.
</span>
</span>
<span id=sponsorTimesViewsContainer style="display: none">
You have saved people from
<span id="sponsorTimesViewsDisplay">
0
</span>
<span id="sponsorTimesViewsDisplayEndWord">
sponsor segments.
</span>
</span>
</p>
<p>
Click the button below when the sponsorship starts and ends to record and
submit it to the database.
</p>
<div>
<button id="sponsorStart" class="greenButton">Sponsorship Starts Now</button>
</div>
<sub>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" style="display: none">
<h3>Latest Sponsor Message Times Chosen</h3>
<b>
<div id="sponsorMessageTimes">
</div>
</b>
<button id="clearTimes" class="smallButton">Clear Times</button>
<br/>
<br/>
<div id="submitTimesContainer" style="display: none">
<button id="submitTimes" class="smallButton">Submit Times</button>
<div id="submitTimesInfoMessageContainer" style="display: none">
<h3 id="submitTimesInfoMessage">
</h3>
</div>
</div>
</div>
<div id="discordButtonContainer" style="display: none">
<br/>
<a href="https://discord.gg/QnmVMpU" target="_blank"><img src="https://www.logolynx.com/images/logolynx/1b/1bcc0f0aefe71b2c8ce66ffe8645d365.png" height="32px"/></a>
<br/>
Come join the official discord server to give suggestions and feedback!
<br/>
<span id="hideDiscordButton" class="smallLink">Hide this</span>
</div>
<div id="optionsButtonContainer">
<br/>
<br/>
<button id="optionsButton" class="dangerButton">Options</button>
</div>
<div id="options" style="display: none">
<br/>
<h3>Options</h3>
<button id="hideVideoPlayerControls" class="warningButton">Hide Button On YouTube Player</button>
<button id="showVideoPlayerControls" style="display: none" class="warningButton">Show Button On YouTube Player</button>
<br/>
<sub>
This hides the button that appears 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>
<br/>
<br/>
<button id="disableSponsorViewTracking" class="warningButton">Disable Sponsor View Tracking</button>
<button id="enableSponsorViewTracking" style="display: none" class="warningButton">Enable Sponsor View Tracking</button>
<br/>
<sub>
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">Show Notice Again</button>
</div>
</div>
</div>
</center>
<!-- Scripts that need to load after the html -->
<script src="config.js"></script>
<script src="popup.js"></script>
</html>

818
popup.js
View File

@@ -1,818 +0,0 @@
// References
var SB = {};
SB.sponsorStart = document.getElementById("sponsorStart");
SB.clearTimes = document.getElementById("clearTimes");
SB.submitTimes = document.getElementById("submitTimes");
SB.showNoticeAgain = document.getElementById("showNoticeAgain");
SB.hideVideoPlayerControls = document.getElementById("hideVideoPlayerControls");
SB.showVideoPlayerControls = document.getElementById("showVideoPlayerControls");
SB.disableSponsorViewTracking = document.getElementById("disableSponsorViewTracking");
SB.enableSponsorViewTracking = document.getElementById("enableSponsorViewTracking");
SB.optionsButton = document.getElementById("optionsButton");
SB.reportAnIssue = document.getElementById("reportAnIssue");
// sponsorTimesContributions
SB.sponsorTimesContributionsContainer = document.getElementById("sponsorTimesContributionsContainer");
SB.sponsorTimesContributionsDisplay = document.getElementById("sponsorTimesContributionsDisplay");
SB.sponsorTimesContributionsDisplayEndWord = document.getElementById("sponsorTimesContributionsDisplayEndWord");
// sponsorTimesViewsDisplay
SB.sponsorTimesViewsContainer = document.getElementById("sponsorTimesViewsDisplayContainer");
SB.sponsorTimesViewsDisplay = document.getElementById("sponsorTimesViewsDisplayDisplay");
SB.sponsorTimesViewsDisplayEndWord = document.getElementById("sponsorTimesViewsDisplayDisplayEndWord");
// discordButtons
SB.discordButtonContainer = document.getElementById("discordButtonContainer");
SB.hideDiscordButton = document.getElementById("hideDiscordButton");
//setup click listeners
SB.sponsorStart.addEventListener("click", sendSponsorStartMessage);
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.disableSponsorViewTracking.addEventListener("click", disableSponsorViewTracking);
SB.enableSponsorViewTracking.addEventListener("click", enableSponsorViewTracking);
SB.optionsButton.addEventListener("click", openOptions);
SB.reportAnIssue.addEventListener("click", reportAnIssue);
SB.hideDiscordButton.addEventListener("click", hideDiscordButton);
//if true, the button now selects the end time
var startTimeChosen = false;
//the start and end time pairs (2d)
var sponsorTimes = [];
//current video ID of this tab
var currentVideoID = null;
//is this a YouTube tab?
var 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});
}
});
}
});
//if the don't show notice again variable 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 option
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";
}
});
//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 = "sponsors."
} else {
SB.sponsorTimesContributionsDisplayEndWord.innerText = "sponsor."
}
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 = "sponsor segments."
} else {
SB.sponsorTimesViewsDisplayEndWord.innerText = "sponsor segment."
}
SB.sponsorTimesViewsDisplay.innerText = viewCount;
SB.sponsorTimesViewsContainer.style.display = "unset";
}
}
});
}
});
}
});
chrome.tabs.query({
active: true,
currentWindow: true
}, loadTabData);
function loadTabData(tabs) {
//set current videoID
currentVideoID = getYouTubeVideoID(tabs[0].url);
if (!currentVideoID) {
//this isn't a YouTube video then
displayNoVideo();
return;
}
//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 = "Sponsorship Ends Now";
}
sponsorTimes = sponsorTimesStorage;
displaySponsorTimes();
//show submission section
document.getElementById("submissionSection").style.display = "unset";
showSubmitTimesIfNecessary();
}
});
//check if this video's sponsors are known
chrome.tabs.sendMessage(
tabs[0].id,
{message: 'isInfoFound'},
infoFound
);
}
function infoFound(request) {
if(chrome.runtime.lastError) {
//This page doesn't have the injected content script, or at least not yet
displayNoVideo();
return;
}
//if request is undefined, then the page currently being browsed is not YouTube
if (request != undefined) {
//this must be a YouTube video
//set variable
isYouTubeTab = true;
//remove loading text
document.getElementById("mainControls").style.display = "unset"
document.getElementById("loadingIndicator").innerHTML = "";
if (request.found) {
document.getElementById("videoFound").innerHTML = "This video's sponsors are in the database!"
displayDownloadedSponsorTimes(request);
} else {
document.getElementById("videoFound").innerHTML = "No sponsors found"
}
}
}
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({
active: true,
currentWindow: true
}, tabs => {
chrome.tabs.sendMessage(
tabs[0].id,
{from: 'popup', message: 'sponsorStart'},
startSponsorCallback
);
});
}
function startSponsorCallback(response) {
let sponsorTimesIndex = sponsorTimes.length - (startTimeChosen ? 1 : 0);
if (sponsorTimes[sponsorTimesIndex] == undefined) {
sponsorTimes[sponsorTimesIndex] = [];
}
sponsorTimes[sponsorTimesIndex][startTimeChosen ? 1 : 0] = response.time;
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
updateStartTimeChosen();
//display video times on screen
displaySponsorTimes();
//show submission section
document.getElementById("submissionSection").style.display = "unset";
showSubmitTimesIfNecessary();
}
//display the video times from the array
function displaySponsorTimes() {
//set it to the message
let sponsorMessageTimes = document.getElementById("sponsorMessageTimes");
//remove all children
while (sponsorMessageTimes.firstChild) {
sponsorMessageTimes.removeChild(sponsorMessageTimes.firstChild);
}
//add sponsor times
sponsorMessageTimes.appendChild(getSponsorTimesMessageDiv(sponsorTimes));
}
//display the video times from the array at the top, in a different section
function displayDownloadedSponsorTimes(request) {
if (request.sponsorTimes != undefined) {
//set it to the message
document.getElementById("downloadedSponsorMessageTimes").innerHTML = getSponsorTimesMessage(request.sponsorTimes);
//add them as buttons to the issue reporting container
let container = document.getElementById("issueReporterTimeButtons");
for (let i = 0; i < request.sponsorTimes.length; i++) {
let sponsorTimeButton = document.createElement("button");
sponsorTimeButton.className = "warningButton";
sponsorTimeButton.innerText = getFormattedTime(request.sponsorTimes[i][0]) + " to " + getFormattedTime(request.sponsorTimes[i][1]);
let votingButtons = document.createElement("div");
let UUID = request.UUIDs[i];
//thumbs up and down buttons
let voteButtonsContainer = document.createElement("div");
voteButtonsContainer.id = "sponsorTimesVoteButtonsContainer" + UUID;
voteButtonsContainer.setAttribute("align", "center");
voteButtonsContainer.style.display = "none"
let upvoteButton = document.createElement("img");
upvoteButton.id = "sponsorTimesUpvoteButtonsContainer" + UUID;
upvoteButton.className = "voteButton";
upvoteButton.src = chrome.extension.getURL("icons/upvote.png");
upvoteButton.addEventListener("click", () => vote(1, UUID));
let downvoteButton = document.createElement("img");
downvoteButton.id = "sponsorTimesDownvoteButtonsContainer" + UUID;
downvoteButton.className = "voteButton";
downvoteButton.src = chrome.extension.getURL("icons/downvote.png");
downvoteButton.addEventListener("click", () => vote(0, UUID));
//add thumbs up and down buttons to the container
voteButtonsContainer.appendChild(document.createElement("br"));
voteButtonsContainer.appendChild(document.createElement("br"));
voteButtonsContainer.appendChild(upvoteButton);
voteButtonsContainer.appendChild(downvoteButton);
//add click listener to open up vote panel
sponsorTimeButton.addEventListener("click", function() {
voteButtonsContainer.style.display = "unset";
});
container.appendChild(sponsorTimeButton);
container.appendChild(voteButtonsContainer);
//if it is not the last iteration
if (i != request.sponsorTimes.length - 1) {
container.appendChild(document.createElement("br"));
container.appendChild(document.createElement("br"));
}
}
}
}
//get the message that visually displays the video times
function getSponsorTimesMessage(sponsorTimes) {
let sponsorTimesMessage = "";
for (let i = 0; i < sponsorTimes.length; i++) {
for (let s = 0; s < sponsorTimes[i].length; s++) {
let timeMessage = getFormattedTime(sponsorTimes[i][s]);
//if this is an end time
if (s == 1) {
timeMessage = " to " + timeMessage;
} else if (i > 0) {
//add commas if necessary
timeMessage = ", " + timeMessage;
}
sponsorTimesMessage += timeMessage;
}
}
return sponsorTimesMessage;
}
//get the message that visually displays the video times
//this version is a div that contains each with delete buttons
function getSponsorTimesMessageDiv(sponsorTimes) {
// let sponsorTimesMessage = "";
let sponsorTimesContainer = document.createElement("div");
sponsorTimesContainer.id = "sponsorTimesContainer";
for (let i = 0; i < sponsorTimes.length; i++) {
let currentSponsorTimeContainer = document.createElement("div");
currentSponsorTimeContainer.id = "sponsorTimeContainer" + i;
let currentSponsorTimeMessage = "";
let deleteButton = document.createElement("span");
deleteButton.id = "sponsorTimeDeleteButton" + i;
deleteButton.innerText = "Delete";
deleteButton.className = "smallLink";
let index = i;
deleteButton.addEventListener("click", () => deleteSponsorTime(index));
let spacer = document.createElement("span");
spacer.innerText = " ";
let editButton = document.createElement("span");
editButton.id = "sponsorTimeEditButton" + i;
editButton.innerText = "Edit";
editButton.className = "smallLink";
editButton.addEventListener("click", () => editSponsorTime(index));
for (let s = 0; s < sponsorTimes[i].length; s++) {
let timeMessage = getFormattedTime(sponsorTimes[i][s]);
//if this is an end time
if (s == 1) {
timeMessage = " to " + timeMessage;
} else if (i > 0) {
//add commas if necessary
timeMessage = timeMessage;
}
currentSponsorTimeMessage += timeMessage;
}
currentSponsorTimeContainer.innerText = currentSponsorTimeMessage;
sponsorTimesContainer.appendChild(currentSponsorTimeContainer);
sponsorTimesContainer.appendChild(deleteButton);
//only if it is a complete sponsor time
if (sponsorTimes[i].length > 1) {
sponsorTimesContainer.appendChild(spacer);
sponsorTimesContainer.appendChild(editButton);
}
}
return sponsorTimesContainer;
}
function editSponsorTime(index) {
let sponsorTimeContainer = document.getElementById("sponsorTimeContainer" + index);
//get sponsor time minutes and seconds boxes
let startTimeMinutes = document.createElement("input");
startTimeMinutes.id = "startTimeMinutes" + index;
startTimeMinutes.type = "text";
startTimeMinutes.value = getTimeInMinutes(sponsorTimes[index][0]);
startTimeMinutes.style.width = "35";
let startTimeSeconds = document.createElement("input");
startTimeSeconds.id = "startTimeSeconds" + index;
startTimeSeconds.type = "text";
startTimeSeconds.value = getTimeInFormattedSeconds(sponsorTimes[index][0]);
startTimeSeconds.style.width = "42";
let endTimeMinutes = document.createElement("input");
endTimeMinutes.id = "endTimeMinutes" + index;
endTimeMinutes.type = "text";
endTimeMinutes.value = getTimeInMinutes(sponsorTimes[index][1]);
endTimeMinutes.style.width = "35";
let endTimeSeconds = document.createElement("input");
endTimeSeconds.id = "endTimeSeconds" + index;
endTimeSeconds.type = "text";
endTimeSeconds.value = getTimeInFormattedSeconds(sponsorTimes[index][1]);
endTimeSeconds.style.width = "42";
let colonText = document.createElement("span");
colonText.innerText = ":";
let toText = document.createElement("span");
toText.innerText = " to ";
//remove all children to replace
while (sponsorTimeContainer.firstChild) {
sponsorTimeContainer.removeChild(sponsorTimeContainer.firstChild);
}
sponsorTimeContainer.appendChild(startTimeMinutes);
sponsorTimeContainer.appendChild(colonText);
sponsorTimeContainer.appendChild(startTimeSeconds);
sponsorTimeContainer.appendChild(toText);
sponsorTimeContainer.appendChild(endTimeMinutes);
sponsorTimeContainer.appendChild(colonText);
sponsorTimeContainer.appendChild(endTimeSeconds);
//add save button and remove edit button
let saveButton = document.createElement("span");
saveButton.id = "sponsorTimeSaveButton" + index;
saveButton.innerText = "Save";
saveButton.className = "smallLink";
saveButton.addEventListener("click", () => saveSponsorTimeEdit(index));
let editButton = document.getElementById("sponsorTimeEditButton" + index);
let sponsorTimesContainer = document.getElementById("sponsorTimesContainer");
sponsorTimesContainer.removeChild(editButton);
sponsorTimesContainer.appendChild(saveButton);
}
function saveSponsorTimeEdit(index) {
let startTimeMinutes = document.getElementById("startTimeMinutes" + index);
let startTimeSeconds = document.getElementById("startTimeSeconds" + index);
let endTimeMinutes = document.getElementById("endTimeMinutes" + index);
let endTimeSeconds = document.getElementById("endTimeSeconds" + index);
sponsorTimes[index][0] = parseInt(startTimeMinutes.value) * 60 + parseFloat(startTimeSeconds.value);
sponsorTimes[index][1] = parseInt(endTimeMinutes.value) * 60 + parseFloat(endTimeSeconds.value);
//save this
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
displaySponsorTimes();
}
//deletes the sponsor time submitted at an index
function deleteSponsorTime(index) {
//if it is not a complete sponsor time
if (sponsorTimes[index].length < 2) {
chrome.tabs.query({
active: true,
currentWindow: true
}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {
message: "changeStartSponsorButton",
showStartSponsor: true,
uploadButtonVisible: false
});
});
resetStartTimeChosen();
}
sponsorTimes.splice(index, 1);
//save this
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
//update display
displaySponsorTimes();
//if they are all removed
if (sponsorTimes.length == 0) {
//update chrome tab
chrome.tabs.query({
active: true,
currentWindow: true
}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {
message: "changeStartSponsorButton",
showStartSponsor: true,
uploadButtonVisible: false
});
});
//hide submission section
document.getElementById("submissionSection").style.display = "none";
}
}
function clearTimes() {
//send new sponsor time state to tab
if (sponsorTimes.length > 0) {
chrome.tabs.query({
active: true,
currentWindow: true
}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {
message: "changeStartSponsorButton",
showStartSponsor: true,
uploadButtonVisible: false
});
});
}
//reset sponsorTimes
sponsorTimes = [];
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
displaySponsorTimes();
//hide submission section
document.getElementById("submissionSection").style.display = "none";
resetStartTimeChosen();
}
function submitTimes() {
//make info message say loading
document.getElementById("submitTimesInfoMessage").innerText = "Loading...";
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
if (sponsorTimes.length > 0) {
chrome.runtime.sendMessage({
message: "submitTimes",
videoID: currentVideoID
}, function(response) {
if (response != undefined) {
if (response.statusCode == 200) {
//hide loading message
document.getElementById("submitTimesInfoMessageContainer").style.display = "none";
clearTimes();
} else if(response.statusCode == 400) {
document.getElementById("submitTimesInfoMessage").innerText = "Server said this request was invalid";
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
} else if(response.statusCode == 429) {
document.getElementById("submitTimesInfoMessage").innerText = "You have submitted too many sponsor times for this one video, are you sure there are this many?";
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
} else if(response.statusCode == 409) {
document.getElementById("submitTimesInfoMessage").innerText = "This has already been submitted before";
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
} else {
document.getElementById("submitTimesInfoMessage").innerText = "There was an error submitting your sponsor times, please try again later. Error code " + response.statusCode;
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
}
}
});
}
}
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.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 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 variable
if (!startTimeChosen) {
startTimeChosen = true;
SB.sponsorStart.innerHTML = "Sponsorship Ends Now";
} else {
resetStartTimeChosen();
}
}
//set it to false
function resetStartTimeChosen() {
startTimeChosen = false;
SB.sponsorStart.innerHTML = "Sponsorship Starts Now";
}
//hides and shows the submit times button when needed
function showSubmitTimesIfNecessary() {
//check if an end time has been specified for the latest sponsor time
if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length > 1) {
//show submit times button
document.getElementById("submitTimesContainer").style.display = "unset";
} else {
//hide submit times button
document.getElementById("submitTimesContainer").style.display = "none";
}
}
//make the options div visisble
function openOptions() {
document.getElementById("optionsButtonContainer").style.display = "none";
document.getElementById("options").style.display = "unset";
}
//this is not a YouTube video page
function displayNoVideo() {
document.getElementById("loadingIndicator").innerHTML = "This probably isn't a YouTube tab, or you clicked too early. " +
"If you know this is a YouTube tab, close this popup and open it again.";
}
function reportAnIssue() {
document.getElementById("issueReporterContainer").style.display = "unset";
SB.reportAnIssue.style.display = "none";
}
function addVoteMessage(message, UUID) {
let container = document.getElementById("sponsorTimesVoteButtonsContainer" + UUID);
//remove all children
while (container.firstChild) {
container.removeChild(container.firstChild);
}
let thanksForVotingText = document.createElement("h2");
thanksForVotingText.innerText = message;
//there are already breaks there
thanksForVotingText.style.marginBottom = "0px";
container.appendChild(thanksForVotingText);
}
function vote(type, UUID) {
//add loading info
addVoteMessage("Loading...", UUID)
//send the vote message to the tab
chrome.runtime.sendMessage({
message: "submitVote",
type: type,
UUID: UUID
}, function(response) {
if (response != undefined) {
//see if it was a success or failure
if (response.successType == 1) {
//success
addVoteMessage("Thanks for voting!", UUID)
} else if (response.successType == 0) {
//failure: duplicate vote
addVoteMessage("You have already voted this way before.", UUID)
} else if (response.successType == -1) {
//failure: duplicate vote
addVoteMessage("A connection error has occured.", UUID)
}
}
});
}
function hideDiscordButton() {
chrome.storage.sync.set({"hideDiscordLink": false});
SB.discordButtonContainer.style.display = "none";
}
//converts time in seconds to minutes:seconds
function getFormattedTime(seconds) {
let minutes = Math.floor(seconds / 60);
let secondsDisplay = Math.round(seconds - minutes * 60);
if (secondsDisplay < 10) {
//add a zero
secondsDisplay = "0" + secondsDisplay;
}
let formatted = minutes+ ":" + secondsDisplay;
return formatted;
}
//converts time in seconds to minutes
function getTimeInMinutes(seconds) {
let minutes = Math.floor(seconds / 60);
return minutes;
}
//converts time in seconds to seconds past the last minute
function getTimeInFormattedSeconds(seconds) {
let secondsFormatted = (seconds % 60).toFixed(3);
if (secondsFormatted < 10) {
secondsFormatted = "0" + secondsFormatted;
}
return secondsFormatted;
}
function sendRequestToServer(type, address, callback) {
let xmlhttp = new XMLHttpRequest();
xmlhttp.open(type, serverAddress + address, true);
if (callback != undefined) {
xmlhttp.onreadystatechange = function () {
callback(xmlhttp, false);
};
xmlhttp.onerror = function(ev) {
callback(xmlhttp, true);
};
}
//submit this request
xmlhttp.send();
}
function getYouTubeVideoID(url) { // Return video id or false
var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
var match = url.match(regExp);
return (match && match[7].length == 11) ? match[7] : false;
}

View 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."
}
}

View File

@@ -0,0 +1,429 @@
{
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": {
"message": "SponsorBlock for YouTube - Skip Sponsorships",
"description": "Name of the extension."
},
"Description": {
"message": "Skip over sponsorship on YouTube videos. Report sponsors on videos you watch to save the time of others.",
"description": "Description of the extension."
},
"helpPage": {
"message": "index_en.html"
},
"400": {
"message": "Server said this request was invalid"
},
"429": {
"message": "You have submitted too many sponsor times for this one video, are you sure there are this many?"
},
"409": {
"message": "This has already been submitted before"
},
"channelWhitelisted": {
"message": "Channel Whitelisted!"
},
"Sponsor": {
"message": "sponsor"
},
"Sponsors": {
"message": "sponsors"
},
"Segment": {
"message": "sponsor segment"
},
"Segments": {
"message": "sponsor segments"
},
"noticeTitle": {
"message": "Sponsor Skipped"
},
"reportButtonTitle": {
"message": "Report"
},
"reportButtonInfo": {
"message": "Report this sponsor submission as incorrect."
},
"Dismiss": {
"message": "Dismiss"
},
"Loading": {
"message": "Loading..."
},
"Mins": {
"message": "Minutes"
},
"Secs": {
"message": "Seconds"
},
"Hide": {
"message": "Never Show"
},
"hitGoBack": {
"message": "Hit unskip to get to where you came from."
},
"unskip": {
"message": "Unskip"
},
"reskip": {
"message": "Reskip"
},
"paused": {
"message": "Paused"
},
"confirmMSG": {
"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"
},
"Unknown": {
"message": "There was an error submitting your sponsor times, please try again later."
},
"sponsorFound": {
"message": "This video's sponsors are in the database!"
},
"sponsor404": {
"message": "No sponsors found"
},
"sponsorStart": {
"message": "Sponsorship Starts Now"
},
"sponsorEnd": {
"message": "Sponsorship Ends Now"
},
"noVideoID": {
"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!"
},
"voted": {
"message": "Voted!"
},
"voteFail": {
"message": "You have already voted this way before."
},
"serverDown": {
"message": "It seems the sever is down. Contact the dev immediately."
},
"connectionError": {
"message": "A connection error has occured. Error code: "
},
"wantToSubmit": {
"message": "Do you want to submit the sponsor times for video id"
},
"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 to 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 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.",
"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."
},
"minDuration": {
"message": "Minimum duration (seconds):"
},
"minDurationDescription": {
"message": "Sponsor segments shorter than the set value will not be skipped or show in the player."
},
"shortCheck": {
"message": "The following submission is shorter than your minimum duration option. This could mean that this is already submitted, and just being ignored due to this option. Are you sure you would like to submit?"
},
"showUploadButton": {
"message": "Show Upload Button"
},
"whatUploadButton": {
"message": "This button appears on the YouTube player after you have selected a timestamp and are ready to submit."
},
"customServerAddress": {
"message": "SponsorBlock Server Address"
},
"customServerAddressDescription": {
"message": "The address SponsorBlock uses to make calls to the server.\nUnless you have your own server instance, this should not be changed."
},
"save": {
"message": "Save"
},
"reset": {
"message": "Reset"
},
"customAddressError": {
"message": "This address is not in the right form. Make sure you have http:// or https:// at the begining and no trailing slashes."
},
"areYouSureReset": {
"message": "Are you sure you would like to reset this?"
},
"confirmPrivacy": {
"message": "The video has been detected as unlisted. Click cancel if you do not want to check for sponsors."
},
"unlistedCheck": {
"message": "Ignore Unlisted Videos"
},
"whatUnlistedCheck": {
"message": "This setting will significantly slow down SponsorBlock. Sponsor lookups require sending the video ID to the server. If you are concerned about unlisted video IDs being sent over the internet, enable this option."
},
"mobileUpdateInfo": {
"message": "m.youtube.com is now supported"
}
}

View 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 : "
}
}

View 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"
}
}

View 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ć."
}
}

View 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"
}
}

View 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"
}
}

View File

@@ -0,0 +1,421 @@
{
"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": "Вы уверены, что хотите отправить эту информацию?"
},
"whitelistChannel": {
"message": "Добавить канал в белый список"
},
"removeFromWhitelist": {
"message": "Удалить канал из белого списка"
},
"voteOnTime": {
"message": "Проголосовать за время спонсорской вставки"
},
"recordTimes": {
"message": "Записать время спонсорской вставки"
},
"soFarUHSubmited": {
"message": "На данный момент Вы отправили"
},
"savedPeopleFrom": {
"message": "Вы помогли людям сэкономить "
},
"viewLeaderboard": {
"message": "Посмотреть доску почёта"
},
"here": {
"message": "здесь"
},
"recordTimesDescription": {
"message": "Нажмите кнопку ниже, когда спонсорская вставка начинается и заканчивается, чтобы записать\nи отправить её в базу данных."
},
"popupHint": {
"message": "Подсказка: нажмите ;, чтобы сообщить начало/конец спонсорской вставки, и \", чтобы отправить. (Это можно изменить в настройках)"
},
"lastTimes": {
"message": "Последнее выбранное время спонсорской вставки"
},
"clearTimesButton": {
"message": "Очистить время"
},
"submitTimesButton": {
"message": "Отправить время"
},
"publicStats": {
"message": "Оно используется на публичной странице статистики, чтобы показать Ваш вклад. Её можно посмотреть "
},
"setUsername": {
"message": "Установить имя пользователя"
},
"discordAdvert": {
"message": "Присоединяйтесь к официальному серверу Discord, чтобы оставить предложения и обратную связь!"
},
"hideThis": {
"message": "Скрыть это"
},
"Options": {
"message": "Настройки"
},
"showButtons": {
"message": "Показывать кнопки в плеере YouTube"
},
"hideButtons": {
"message": "Скрыть кнопки в плеере YouTube"
},
"hideButtonsDescription": {
"message": "Эта настройка скрывает кнопки для отправки спонсорских вставок, которые появляются в плеере YouTube. Они могут раздражать\n некоторых. Вместо кнопок для отправки спонсорских вставок можно использовать это всплывающее окно. Чтобы скрыть\nуведомление, нажмите кнопку \"Не показывать снова\" в уведомлении. Вы всегда сможете включить эти настройки обратно."
},
"showInfoButton": {
"message": "Показывать кнопку информации в плеере YouTube"
},
"hideInfoButton": {
"message": "Скрыть кнопку информации в плеере YouTube"
},
"whatInfoButton": {
"message": "Эта кнопка открывает всплывающее окно на странице YouTube."
},
"hideDeleteButton": {
"message": "Скрыть кнопку удаления в плеере YouTube"
},
"showDeleteButton": {
"message": "Показывать кнопку удаления в плеере YouTube"
},
"whatDeleteButton": {
"message": "Эта кнопка позволяет Вам очистить все спонсорские вставки в плеере YouTube."
},
"disableViewTracking": {
"message": "Отключить отслеживание количества пропусков спонсорских вставок"
},
"enableViewTracking": {
"message": "Включить отслеживание количества пропусков спонсорских вставок"
},
"whatViewTracking": {
"message": "Эта возможность отслеживает, какие спонсорские вставки Вы пропустили, чтобы помочь пользователям узнать, насколько их\nвклад помог другим, и используется как метрика, чтобы убедиться, что спам не попадает в базу данных. Расширение отправляет\nсообщение на сервер каждый раз, когда Вы пропускаете спонсорскую вставку. Надеемся, большая часть пользователей не поменяет эту настройку, так что у нас будет точная статистика просмотров :)"
},
"showNotice": {
"message": "Показывать уведомление снова"
},
"longDescription": {
"message": "SponsorBlock — это расширение, которое пропускает спонсорские вставки в видео на YouTube. SponsorBlock — это краудсорсинговое расширение, которое позволяет каждому отправить время начала и конца спонсорских сегментов в видео на YouTube. После того, как кто-нибудь отправляет эту информацию, все остальные пользователи расширения будут автоматически пропускать спонсорские сегменты.",
"description": "Полное описание расширения на страницах магазинов."
},
"website": {
"message": "Сайт",
"description": "Используется на странице магазина Firefox"
},
"sourceCode": {
"message": "Исходный код",
"description": "Используется на странице магазина Firefox"
},
"noticeUpdate": {
"message": "Уведомление было обновлено!",
"description": "The first line of the message displayed after the notice was upgraded."
},
"noticeUpdate2": {
"message": "Если оно Вам всё равно не нравится, нажмите \"не показывать\".",
"description": "The second line of the message displayed after the notice was upgraded."
},
"setStartSponsorShortcut": {
"message": "Назначить горячую клавишу для начала спонсорской вставки"
},
"setSubmitKeybind": {
"message": "Назначить горячую клавишу для отправки"
},
"keybindDescription": {
"message": "Нажмите клавишу, чтобы выбрать её"
},
"keybindDescriptionComplete": {
"message": "Клавиша назначена на: "
},
"0": {
"message": "Таймаут подключения. Проверьте ваше соединение с интернетом. Если ваш интернет работает, сервер, скорее всего, перегружен или лежит."
},
"disableSkipping": {
"message": "Отключить SponsorBlock"
},
"enableSkipping": {
"message": "Включить SponsorBlock"
},
"yourWork": {
"message": "Ваша работа",
"description": "Used to describe the section that will show you the statistics from your submissions."
},
"502": {
"message": "Похоже, сервер перегружен. Попробуйте ещё раз через несколько секунд."
},
"errorCode": {
"message": "Код ошибки: "
},
"noticeTitleNotSkipped": {
"message": "Пропустить спонсорскую вставку?"
},
"skip": {
"message": "Пропустить"
},
"disableAutoSkip": {
"message": "Отключить автоматический пропуск"
},
"enableAutoSkip": {
"message": "Включить автоматический пропуск"
},
"autoSkipDescription": {
"message": "Автоматический пропуск будет пропускать спонсорские вставки за Вас. Если выключено, будет показываться уведомление с предложением пропустить."
},
"youHaveSkipped": {
"message": "Вы пропустили "
},
"youHaveSaved": {
"message": "Вы сэкономили "
},
"minLower": {
"message": "минуту"
},
"minsLower": {
"message": "минут"
},
"hourLower": {
"message": "час"
},
"hoursLower": {
"message": "часов"
},
"youHaveSavedTime": {
"message": "Вы сэкономили людям"
},
"youHaveSavedTimeEnd": {
"message": " их жизней."
},
"guildlinesSummary": {
"message": "- Убедитесь, что Ваш сегмент содержит только платную интеграцию, и больше ничего.\n- Убедитесь, что пропуск этого сегмента не пропустит никакой ценный контент\n- Если всё видео целиком спонсорское, пожалуйста, не сообщайте о нём. Система для сообщения о целых видео скоро выйдет.\n- Пожалуйста, не сообщайте об отказах от ответственности, которые могут показать предвзятость (если видео с обзором проплачено, не пропускайте, когда они это упоминают)."
},
"statusReminder": {
"message": "Смотрите состояние сервера на status.sponsor.ajay.app."
},
"changeUserID": {
"message": "Импортировать/экспортировать Ваш идентификатор пользователя"
},
"whatChangeUserID": {
"message": "Это нужно держать в секрете. Это как пароль, не стоит им ни с кем делиться. Если он у кого-то есть, он сможет выдать себя за Вас."
},
"setUserID": {
"message": "Установить идентификатор пользователя"
},
"userIDChangeWarning": {
"message": "Внимание: изменение идентификатора пользователя необратимо. Вы действительно хотите это сделать? Сделайте резервную копию вашего старого на всякий случай."
},
"createdBy": {
"message": "Создано"
},
"autoSkip": {
"message": "Автоматический пропуск"
},
"showSkipNotice": {
"message": "Показывать уведомление после пропуска спонсорской вставки"
},
"keybindCurrentlySet": {
"message": ". Он сейчас назначен на:"
},
"supportInvidious": {
"message": "Поддержка Invidious"
},
"supportInvidiousDescription": {
"message": "Invidious (invidio.us) — это неофициальный клиент YouTube. Чтобы включить поддержку, Вам понадобится принять дополнительные разрешения. Это НЕ работает в приватном режиме в Chrome и других вариантах Chromium."
},
"optionsInfo": {
"message": "Включить поддержку Invidious, выключить автоматический пропуск, скрыть кнопки и не только."
},
"addInvidiousInstance": {
"message": "Добавить инстанс Invidious"
},
"addInvidiousInstanceDescription": {
"message": "Добавить свой инстанс Invidious. Формат: ТОЛЬКО домен. Например, invidious.ajay.app"
},
"add": {
"message": "Добавить"
},
"addInvidiousInstanceError": {
"message": "Это неправильный домен. Введите ТОЛЬКО домен. Например, invidious.ajay.app"
},
"resetInvidiousInstance": {
"message": "Сбросить список инстансов Invidious"
},
"resetInvidiousInstanceAlert": {
"message": "Вы собираетесь сбросить список инстансов Invidious"
},
"currentInstances": {
"message": "Текущие инстансы:"
},
"enableAutoUpvote": {
"message": "Автоматически голосовать \"за\""
},
"whatAutoUpvote": {
"message": "Если это включено, расширение будет голосовать \"за\" все предложения других пользователей, если Вы на них не пожалуетесь. Если уведомление отключено, это не будет происходить."
},
"minDuration": {
"message": "Минимальная длительность (секунд):"
},
"minDurationDescription": {
"message": "Спонсорские сегменты короче этого значения не будут пропускаться и не будут показаны в плеере."
},
"shortCheck": {
"message": "Следующий диапазон времени короче, чем Ваша настройка минимальной длительности. Это может означать, что он уже был отправлен, и просто игнорируется из-за этой настройки. Вы действительно хотите отправить?"
},
"showUploadButton": {
"message": "Показывать кнопку отправки"
},
"whatUploadButton": {
"message": "Эта кнопка появляется в плеере YouTube после того, как Вы выбрали отметку времени и готовы к отправке."
},
"customServerAddress": {
"message": "Адрес сервера SponsorBlock"
},
"customServerAddressDescription": {
"message": "Адрес, по которому SponsorBlock обращается к серверу.\nМеняйте только если Вы подняли свой сервер."
},
"save": {
"message": "Сохранить"
},
"reset": {
"message": "Сбросить"
},
"customAddressError": {
"message": "Этот адрес неправильного формата. Убедитесь, что он начинается с http:// или https://, и что на конце нет слэшей."
},
"areYouSureReset": {
"message": "Вы действительно хотите это сбросить?"
},
"confirmPrivacy": {
"message": "Было обнаружено, что это видео непубличное. Нажмите \"отмена\", если не хотите проверять его на спонсоров."
},
"unlistedCheck": {
"message": "Игнорировать непубличные видео"
},
"whatUnlistedCheck": {
"message": "Эта настройка значительно замедлит SponsorBlock. Поиск спонсоров требует отправки идентификатора видео на сервер. Если Вас беспокоит отправка идентификаторов непубличных видео по интернету, включите эту настройку."
},
"mobileUpdateInfo": {
"message": "m.youtube.com теперь поддерживается"
}
}

View File

@@ -1,3 +1,21 @@
#previewbar {
overflow: visible;
padding: 0;
margin: 0;
position: absolute;
width: 100%;
pointer-events: none;
height: 100%;
transform: scaleY(0.6) translateY(-30%) translateY(1.5px);
z-index: 40;
}
.previewbar {
display: inline-block;
height: 100%;
}
.popup {
z-index: 10;
width: 100%;
@@ -23,16 +41,16 @@
}
.sponsorSkipObject {
font-family: 'Source Sans Pro', sans-serif;
font-family: Roboto, Arial, Helvetica, sans-serif;
margin-left: 2px;
margin-right: 2px;
}
.sponsorSkipLogo {
height: 64px;
position: absolute;
top: 0;
bottom: 0;
margin: auto;
margin-left: 10px;
height: 18px;
float: left;
}
@keyframes fadeIn {
@@ -40,32 +58,119 @@
to { opacity: 1; }
}
@keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
.sponsorBlockSpacer {
background-color: rgb(100, 100, 100);
border-color: rgb(100, 100, 100);
margin-left: 5px;
}
.sponsorSkipNotice {
min-height: 165px;
min-width: 400px;
background-color: rgba(255, 217, 217, 0.8);
min-width: 350px;
background-color: rgba(28, 28, 28, 0.9);
position: absolute;
z-index: 1;
border: 3px solid rgba(0, 0, 0, 0.8);
margin-top: -50px;
right: 5px;
bottom: 100px;
right: 10px;
border-radius: 5px;
animation: fadeIn 0.5s;
border-spacing: 5px 10px;
padding-left: 5px;
padding-right: 5px;
}
.sponsorSkipNoticeFadeOut {
animation: fadeOut 3s cubic-bezier(0.55, 0.055, 0.675, 0.19);
}
.sponsorSkipNoticeTimeLeft {
color: #eeeeee;
border-radius: 4px;
padding: 2px 5px;
font-size: 12px;
border: 1px solid #eeeeee;
}
/* if two are very close to eachother */
.secondSkipNotice {
margin-left: 500px;
bottom: 250px;
transition: margin-left 0.2s;
transition: bottom 0.2s;
}
.sponsorSkipNoticeUnskipSection {
float: left;
border-left: 1px solid rgb(150, 150, 150);
}
.sponsorSkipNoticeButton {
background: none;
color: rgb(235, 235, 235);
border: none;
display: inline-block;
cursor: pointer;
margin-right: 10px;
padding: 2px 5px;
}
.sponsorSkipNoticeButton:hover {
background-color: rgba(235, 235, 235,0.2);
border-radius: 4px;
transition: background-color 0.4s;
}
.sponsorTimesVoteButtonsContainer {
float: left;
padding: 2px 5px;
margin-right: 4px;
}
.sponsorSkipNoticeRightSection {
right: 0;
position: absolute;
float: right;
margin-right: 5px;
}
.sponsorSkipNoticeRightButton {
margin-right: 0;
}
.sponsorSkipNoticeCloseButton {
height: 10px;
width: 10px;
padding: 2px 5px;
margin-left: 2px;
float: right;
}
.sponsorSkipMessage {
font-size: 18px;
color: #000000;
text-align: center;
margin-top: 10px;
font-size: 14px;
font-weight: bold;
margin-top: 4px;
color: rgb(235, 235, 235);
display: inline-block;
}
.sponsorSkipInfo {
@@ -92,16 +197,18 @@
margin-top: 0px;
}
.sponsorTimesVoteButtonMessage {
float: left;
}
.sponsorTimesInfoMessage {
font-size: 15px;
font-weight: bold;
color: #000000;
font-size: 13.3333px;
color: rgb(235, 235, 235);
text-align: center;
}
.voteButton {
height: 32px;
margin-right: 15px;
height: 17px;
cursor: pointer;
}
.voteButton:hover {

136
public/help/index_en.html Normal file
View File

@@ -0,0 +1,136 @@
<!DOCTYPE html>
<head>
<title> SponsorBlock </title>
<meta charset="utf-8">
<link href="styles.css" rel="stylesheet"/>
</head>
<body>
<div id="title">
<img src="../icons/LogoSponsorBlocker256px.png" height="80" class="profilepic"/>
SponsorBlock
</div>
<div class="container">
<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. Feel free to contact me if you have any questions.
</p>
<p class="projectPreview">
<span class="projectPreviewImage">
<a href="https://discord.gg/QnmVMpU"><img width="80" src="https://www.logolynx.com/images/logolynx/1b/1bcc0f0aefe71b2c8ce66ffe8645d365.png"/></a>
</span>
Come contribute, make some suggestions and help out in the Discord: <a href="https://discord.gg/QnmVMpU">https://discord.gg/QnmVMpU</a>
</p>
<div class="center">
<a class="bigText" href="/options/options.html">Enable optional features</a>
</div>
<p>
Some features, such as support for non third-party YouTube sites, are disabled by default and can be enabled in the options. These can be enabled or disabled at any time.
You can also hide/show all UI elements added to the YouTube page.
</p>
<h1>How skipping works</h1>
<p class="projectPreview">
<span class="projectPreviewImageLarge">
<img src="https://i.imgur.com/caf5Bju.png">
</span>
Videos will automatically be skipped if they are found in the database. You can open the popup by clicking the extension icon to get a preview of what they are.
<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 (this can be disabled in the options).
</p>
<div class="center"><img height="120px" src="https://user-images.githubusercontent.com/12688112/63067735-5a638700-bede-11e9-8147-f321b57527ec.gif"></div>
<h1>Submitting</h1>
<p class="projectPreview">
<span class="projectPreviewImageLargeRight">
<img src="https://i.imgur.com/A1ilk6x.gif">
</span>
Submitting can either be done in the popup by hitting the "Sponsorship Starts Now" button or in the video player with the buttons on the player.
<br/>
<br/>
Clicking the play button indicated the start of a sponsorship section and clicking the stop icon indicates the end. You can prepare multiple sponsors before hitting submit. Clicking the upload button will submit. Clicking the garbage can will delete.
</p>
<h1>Editing</h1>
<p class="projectPreview">
<span class="projectPreviewImageLarge">
<img src="https://i.imgur.com/DZHqbsx.gif">
</span>
If you messed up, you can edit or delete your sponsor times in the popup or in the info menu (by hitting the info icon).
</p>
<h1>This is too slow</h1>
<p>
There are hotkeys if you want to use them. You must be focused on the YouTube player to use them. Press the semicolon key to indicate the start/end of a sponsor segment and click the appostrophe to submit.
These can be changed in the options. If you don't use QWERTY, you should probably change the keybinds.
</p>
<h1>I hate these buttons, they are so ugly</h1>
<p>
All player buttons can be hidden in the options.
</p>
<h1>Can I get a copy of the Database? What happens if you disappear?</h1>
<p>
The database is public and available at <a href="https://sponsor.ajay.app/database.db">https://sponsor.ajay.app/database.db</a>. The source code is freely available. So, even if something happens to me, your submissions are not lost.
</p>
<h1>News and how it is made</h1>
<p>
See <a href="https://sponsor.ajay.app/news">https://sponsor.ajay.app/news</a>.
</p>
<h1>I want more features!</h1>
<p>
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>
<h4 style="display: inline">Client:</h4>
<!-- Github logo -->
<a href="https://github.com/ajayyy/SponsorBlock"><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>
<h4 style="display: inline; padding-left: 20px">Server:</h4>
<!-- 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>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>
<p>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></p>
<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>
</div>
</body>

179
public/help/styles.css Normal file
View File

@@ -0,0 +1,179 @@
.bigText {
font-size: 50px;
}
body {
background-color: #333333;
font-family: sans-serif;
}
.center {
text-align: center;
}
.container {
max-width: 60%;
margin: auto;
}
.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;
}
#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,a {
font-size: 20px;
color: #c4c4c4;
}
p,li,code,a {
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;
text-align: center;
}
svg {
text-decoration: none;
}

View File

Before

Width:  |  Height:  |  Size: 551 B

After

Width:  |  Height:  |  Size: 551 B

View File

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

BIN
public/icons/close.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
public/icons/report.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

326
public/options/options.css Normal file
View File

@@ -0,0 +1,326 @@
/* 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;
}
.text-label-container {
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;
}
.number-container:before {
content: attr(label-name);
padding-right: 4px;
width: max-content;
font-size: 14px;
color: white;
}

335
public/options/options.html Normal file
View File

@@ -0,0 +1,335 @@
<!DOCTYPE html>
<head>
<title>Options - SponsorBlock</title>
<meta charset="utf-8">
<link href="options.css" rel="stylesheet"/>
<script src="../js/vendor.js"></script>
<script src="../js/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="private-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="number-change" sync-option="minDuration">
<label class="number-container" label-name="__MSG_minDuration__">
<input type="number" step="0.1" min="0">
</label>
<br/>
<br/>
<div class="small-description">__MSG_minDurationDescription__</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>
<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" toggle-type="reverse" sync-option="hideUploadButtonPlayerControls">
<label class="switch-container" label-name="__MSG_showUploadButton__">
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>
</label>
<br/>
<br/>
<div class="small-description">__MSG_whatUploadButton__</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="toggle" sync-option="checkForUnlistedVideos">
<label class="switch-container" label-name="__MSG_unlistedCheck__">
<label class="switch">
<input type="checkbox">
<span class="slider round"></span>
</label>
</label>
<br/>
<br/>
<div class="small-description">__MSG_whatUnlistedCheck__</div>
</div>
<br/>
<br/>
<div option-type="private-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="text-change" sync-option="serverAddress">
<label class="text-label-container">
<div>__MSG_customServerAddress__</div>
<input class="option-text-box" type="text">
</label>
<div class="option-button text-change-set inline">
__MSG_save__
</div>
<div class="option-button text-change-reset inline">
__MSG_reset__
</div>
<br/>
<br/>
<div class="small-description">__MSG_customServerAddressDescription__</div>
</div>
</div>
</div>
</body>

237
public/popup.css Normal file
View File

@@ -0,0 +1,237 @@
/* reset some properties to default (youtube messes with them */
p.popupElement {
margin-block-start: 1em;
margin-block-end: 1em;
margin-inline-start: 0px;
margin-inline-end: 0px;
}
h1.popupElement {
margin-block-start: 0.67em;
margin-block-end: 0.67em;
margin-inline-start: 0px;
margin-inline-end: 0px;
font-weight: bold;
}
h2.popupElement {
margin-block-start: 0.83em;
margin-block-end: 0.83em;
margin-inline-start: 0px;
margin-inline-end: 0px;
font-weight: bold;
}
h3.popupElement {
margin-block-start: 1em;
margin-block-end: 1em;
margin-inline-start: 0px;
margin-inline-end: 0px;
font-weight: bold;
}
sub.popupElement {
font-size: smaller;
}
/* end reset */
#sponsorBlockPopupLogo {
vertical-align: text-bottom;
}
.popupElement {
font-family: 'Source Sans Pro', sans-serif;
color: black;
}
h1.popupElement {
margin-top: 0px;
margin-bottom: 10px;
}
.popupBody {
font-size: 14px;
background-color: #ffd9d9;
padding: 0px 5px;
}
.discreteLink.popupElement {
color: black;
}
.recordingSubtitle.popupElement {
margin-bottom: 10px;
}
.voteButton.popupElement {
height: 32px;
margin-right: 15px;
cursor: pointer;
}
.voteButton:hover.popupElement {
filter: brightness(80%);
}
#discordButtonContainer.popupElement {
font-size: 12px;
}
.sponsorTime.popupElement {
font-size: 20px;
}
.smallLink.popupElement {
font-size: 10px;
text-decoration: underline;
cursor: pointer;
}
.mediumLink.popupElement {
font-size: 15px;
margin-left: 25px;
margin-right: 25px;
text-decoration: underline;
cursor: pointer;
}
.tinyLink.popupElement {
font-size: 10px;
text-decoration: underline;
cursor: pointer;
}
.whitelistButton.popupElement {
background-color:#3acc3a;
-moz-border-radius:28px;
-webkit-border-radius:28px;
border-radius:28px;
border: none;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-size:16px;
padding:8px 37px;
text-decoration:none;
text-shadow:0px 0px 0px #27663c;
}
.whitelistButton:hover.popupElement {
background-color:#218b26;
}
.whitelistButton:focus.popupElement {
outline: none;
background-color:#218b26;
}
.whitelistButton:active.popupElement {
position:relative;
top:1px;
}
.greenButton.popupElement {
background-color:#ec1c1c;
-moz-border-radius:28px;
-webkit-border-radius:28px;
border-radius:28px;
border:1px solid #d31919;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-size:16px;
padding:8px 37px;
text-decoration:none;
text-shadow:0px 0px 0px #662727;
}
.greenButton:hover.popupElement {
background-color:#bf2a2a;
}
.greenButton:focus.popupElement {
outline: none;
background-color:#bf2a2a;
}
.greenButton:active.popupElement {
position:relative;
top:1px;
}
.dangerButton.popupElement {
-moz-box-shadow:inset 0px 1px 0px 0px #cf866c;
-webkit-box-shadow:inset 0px 1px 0px 0px #cf866c;
box-shadow:inset 0px 1px 0px 0px #cf866c;
background-color:#d0451b;
-moz-border-radius:3px;
-webkit-border-radius:3px;
border-radius:3px;
border:1px solid #942911;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-size:13px;
padding:6px 24px;
text-decoration:none;
text-shadow:0px 1px 0px #854629;
}
.dangerButton:hover.popupElement {
background-color:#bc3315;
}
.dangerButton:focus.popupElement {
outline: none;
background-color:#bc3315;
}
.dangerButton:active.popupElement {
position:relative;
top:1px;
}
.warningButton.popupElement {
-moz-box-shadow:inset 0px 1px 0px 0px #cfbd6c;
-webkit-box-shadow:inset 0px 1px 0px 0px #cfbd6c;
box-shadow:inset 0px 1px 0px 0px #cfbd6c;
background-color:#d0821b;
-moz-border-radius:3px;
-webkit-border-radius:3px;
border-radius:3px;
border:1px solid #948b11;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-size:13px;
padding:6px 24px;
text-decoration:none;
text-shadow:0px 1px 0px #856829;
}
.warningButton:hover.popupElement {
background-color:#bc8215;
}
.warningButton:focus.popupElement {
outline: none;
background-color:#bc8215;
}
.warningButton:active.popupElement {
position:relative;
top:1px;
}
.smallButton.popupElement {
background-color:#f9902d;
-moz-border-radius:3px;
-webkit-border-radius:3px;
border-radius:3px;
border:1px solid #f9a72d;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-size:14px;
padding:6px 10px;
text-decoration:none;
}
.smallButton:hover.popupElement {
background-color:#fa9806;
}
.smallButton:focus.popupElement {
outline: none;
background-color:#fa9806;
}
.smallButton:active.popupElement {
position:relative;
top:1px;
}

214
public/popup.html Normal file
View File

@@ -0,0 +1,214 @@
<html>
<head>
<title>__MSG_openPopup__</title>
<link id="sponsorBlockPopupFont" rel="stylesheet" type="text/css" href="/libs/Source+Sans+Pro.css"/>
<link id="sponsorBlockStyleSheet" rel="stylesheet" type="text/css" href="popup.css"/>
</head>
<body class="popupBody">
<center>
<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">__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>
<p class="popupElement">
__MSG_recordTimesDescription__
</p>
<div>
<button id="sponsorStart" class="greenButton popupElement">__MSG_sponsorStart__</button>
</div>
<sub class="popupElement">__MSG_popupHint__</sub>
<div id="submissionSection" class="popupElement" style="display: none">
<h3 class="popupElement">__MSG_lastTimes__</h3>
<b>
<div id="sponsorMessageTimes" class="popupElement">
</div>
</b>
<br/>
<button id="clearTimes" class="smallButton popupElement">__MSG_clearTimesButton__</button>
<div id="submitTimesContainer" class="popupElement" style="display: none">
<br/>
<br/>
<button id="submitTimes" class="smallButton popupElement">__MSG_submitTimesButton__</button>
<div id="submitTimesInfoMessageContainer" class="popupElement" style="display: none">
<h3 id="submitTimesInfoMessage" class="popupElement">
</h3>
</div>
</div>
</div>
<div id="discordButtonContainer" class="popupElement" style="display: none">
<br/>
<a href="https://discord.gg/QnmVMpU" class="popupElement" target="_blank"><img src="https://www.logolynx.com/images/logolynx/1b/1bcc0f0aefe71b2c8ce66ffe8645d365.png" height="32px"/></a>
<br/>
__MSG_discordAdvert__
<br/>
<span id="hideDiscordButton" class="smallLink popupElement">__MSG_hideThis__</span>
</div>
<div>
<br/>
<button id="whitelistChannel" class="whitelistButton popupElement">__MSG_whitelistChannel__</button>
<button id="unwhitelistChannel" class="whitelistButton popupElement" style="display: none">__MSG_removeFromWhitelist__</button>
</div>
<br/>
<button id="reportAnIssue" class="dangerButton popupElement">__MSG_voteOnTime__</button>
<div id="issueReporterContainer" class="popupElement" style="display: none">
<h3 style="margin-top: 0px" class="popupElement">__MSG_voteOnTime__</h3>
<div id="issueReporterTimeButtons" class="popupElement">
</div>
</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 February).
</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>.
</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>
<!-- Scripts that need to load after the html -->
<script src="./js/vendor.js"></script>
<script src="./js/popup.js"></script>
</html>

240
src/background.ts Normal file
View File

@@ -0,0 +1,240 @@
import * as Types from "./types";
import Config from "./config";
import Utils from "./utils";
var utils = new Utils({
registerFirefoxContentScript,
unregisterFirefoxContentScript
});
// Used only on Firefox, which does not support non persistent background pages.
var contentScriptRegistrations = {};
// Register content script if needed
if (utils.isFirefox()) {
utils.wait(() => Config.config !== null).then(function() {
if (Config.config.supportInvidious) utils.setupExtraSiteContentScripts();
});
}
chrome.tabs.onUpdated.addListener(function(tabId) {
chrome.tabs.sendMessage(tabId, {
message: 'update',
}, () => void chrome.runtime.lastError ); // Suppress error on Firefox
});
chrome.runtime.onMessage.addListener(function (request, sender, callback) {
switch(request.message) {
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
return true;
case "getSponsorTimes":
getSponsorTimes(request.videoID, function(sponsorTimes) {
callback({
sponsorTimes
});
});
//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":
unregisterFirefoxContentScript(request.id)
return false;
}
});
//add help page on install
chrome.runtime.onInstalled.addListener(function (object) {
// This let's the config sync to run fully before checking.
// This is required on Firefox
setTimeout(function() {
const userID = Config.config.userID;
// If there is no userID, then it is the first install.
if (!userID){
//open up the install page
chrome.tabs.create({url: chrome.extension.getURL("/help/index_en.html")});
//generate a userID
const newUserID = utils.generateUserID();
//save this UUID
Config.config.userID = newUserID;
//TODO: Remove when mobile support is old
// Don't show this to new users
// Config.config.mobileUpdateShowCount = 1;
}
}, 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));
}
/**
* Only works on Firefox.
* Firefox requires that this is handled by the background script
*
*/
function unregisterFirefoxContentScript(id: string) {
contentScriptRegistrations[id].unregister();
delete contentScriptRegistrations[id];
}
//gets the sponsor times from memory
function getSponsorTimes(videoID, callback) {
let sponsorTimes = [];
let sponsorTimesStorage = Config.config.sponsorTimes.get(videoID);
if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
sponsorTimes = sponsorTimesStorage;
}
callback(sponsorTimes);
}
function addSponsorTime(time, videoID, callback) {
getSponsorTimes(videoID, function(sponsorTimes) {
//add to sponsorTimes
if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) {
//it is an end time
sponsorTimes[sponsorTimes.length - 1][1] = time;
} else {
//it is a start time
let sponsorTimesIndex = sponsorTimes.length;
sponsorTimes[sponsorTimesIndex] = [];
sponsorTimes[sponsorTimesIndex][0] = time;
}
//save this info
Config.config.sponsorTimes.set(videoID, sponsorTimes);
callback();
});
}
function submitVote(type, UUID, callback) {
let userID = Config.config.userID;
if (userID == undefined || userID === "undefined") {
//generate one
userID = utils.generateUserID();
Config.config.userID = userID;
}
//publish this vote
utils.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
});
}
});
}
async function submitTimes(videoID, callback) {
//get the video times from storage
let sponsorTimes = Config.config.sponsorTimes.get(videoID);
let userID = Config.config.userID;
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
let durationResult = <Types.videoDurationResponse> 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));
});
});
//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
utils.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) {
//save the amount contributed
if (!increasedContributionAmount) {
increasedContributionAmount = true;
Config.config.sponsorTimesContributed = Config.config.sponsorTimesContributed + sponsorTimes.length;
}
} else if (error) {
callback({
statusCode: -1
});
}
}
});
}
}
}

253
src/config.ts Normal file
View File

@@ -0,0 +1,253 @@
import * as CompileConfig from "../config.json";
interface SBConfig {
userID: string,
sponsorTimes: SBMap<string, any>,
whitelistedChannels: Array<any>,
startSponsorKeybind: string,
submitKeybind: string,
minutesSaved: number,
skipCount: number,
sponsorTimesContributed: number,
disableSkipping: boolean,
disableAutoSkip: boolean,
trackViewCount: boolean,
dontShowNotice: boolean,
hideVideoPlayerControls: boolean,
hideInfoButtonPlayerControls: boolean,
hideDeleteButtonPlayerControls: boolean,
hideUploadButtonPlayerControls: boolean,
hideDiscordLaunches: number,
hideDiscordLink: boolean,
invidiousInstances: string[],
autoUpvote: boolean,
supportInvidious: boolean,
serverAddress: string,
minDuration: number,
checkForUnlistedVideos: boolean,
mobileUpdateShowCount: number
}
interface SBObject {
configListeners: Array<Function>;
defaults: SBConfig;
localConfig: SBConfig;
config: SBConfig;
}
// Allows a SBMap to be conveted into json form
// Currently used for local storage
class SBMap<T, U> extends Map {
id: string;
constructor(id: string, entries?: [T, U][]) {
super();
this.id = id;
// Import all entries if they were given
if (entries !== undefined) {
for (const item of entries) {
super.set(item[0], item[1])
}
}
}
set(key, value) {
const result = super.set(key, value);
// Store updated SBMap locally
chrome.storage.sync.set({
[this.id]: encodeStoredItem(this)
});
return result;
}
delete(key) {
const result = super.delete(key);
// Store updated SBMap locally
chrome.storage.sync.set({
[this.id]: encodeStoredItem(this)
});
return result;
}
clear() {
const result = super.clear();
chrome.storage.sync.set({
[this.id]: encodeStoredItem(this)
});
return result;
}
toJSON() {
return Array.from(this.entries());
}
}
var Config: SBObject = {
/**
* Callback function when an option is updated
*/
configListeners: [],
defaults: {
userID: null,
sponsorTimes: new SBMap("sponsorTimes"),
whitelistedChannels: [],
startSponsorKeybind: ";",
submitKeybind: "'",
minutesSaved: 0,
skipCount: 0,
sponsorTimesContributed: 0,
disableSkipping: false,
disableAutoSkip: false,
trackViewCount: true,
dontShowNotice: false,
hideVideoPlayerControls: false,
hideInfoButtonPlayerControls: false,
hideDeleteButtonPlayerControls: false,
hideUploadButtonPlayerControls: false,
hideDiscordLaunches: 0,
hideDiscordLink: false,
invidiousInstances: ["invidio.us", "invidiou.sh", "invidious.snopyta.org"],
autoUpvote: true,
supportInvidious: false,
serverAddress: CompileConfig.serverAddress,
minDuration: 0,
checkForUnlistedVideos: false,
mobileUpdateShowCount: 0
},
localConfig: null,
config: null
};
// Function setup
/**
* A SBMap 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 SBMap convert to json for storing
if(!(data instanceof SBMap)) return data;
return JSON.stringify(data);
}
/**
* An SBMap cannot be stored in the chrome storage.
* This data will be decoded from the array it is stored in
*
* @param {*} data
*/
function decodeStoredItem(id: string, data) {
if(typeof data !== "string") return data;
try {
let str = JSON.parse(data);
if(!Array.isArray(str)) return data;
return new SBMap(id, str);
} catch(e) {
// If all else fails, return the data
return data;
}
}
function configProxy(): any {
chrome.storage.onChanged.addListener((changes, namespace) => {
for (const key in changes) {
Config.localConfig[key] = decodeStoredItem(key, changes[key].newValue);
}
for (const callback of Config.configListeners) {
callback(changes);
}
});
var handler: ProxyHandler<any> = {
set(obj, prop, value) {
Config.localConfig[prop] = value;
chrome.storage.sync.set({
[prop]: encodeStoredItem(value)
});
return true;
},
get(obj, prop): any {
let data = Config.localConfig[prop];
return obj[prop] || data;
},
deleteProperty(obj, prop) {
chrome.storage.sync.remove(<string> prop);
return true;
}
};
return new Proxy({handler}, handler);
}
function fetchConfig() {
return new Promise((resolve, reject) => {
chrome.storage.sync.get(null, function(items) {
Config.localConfig = <SBConfig> <unknown> items; // Data is ready
resolve();
});
});
}
function migrateOldFormats() { // Convert sponsorTimes format
for (const key in Config.localConfig) {
if (key.startsWith("sponsorTimes") && key !== "sponsorTimes" && key !== "sponsorTimesContributed") {
Config.config.sponsorTimes.set(key.substr(12), Config.config[key]);
delete Config.config[key];
}
}
}
async function setupConfig() {
await fetchConfig();
addDefaults();
convertJSON();
Config.config = configProxy();
migrateOldFormats();
}
// Reset config
function resetConfig() {
Config.config = Config.defaults;
};
function convertJSON() {
Object.keys(Config.localConfig).forEach(key => {
Config.localConfig[key] = decodeStoredItem(key, Config.localConfig[key]);
});
}
// Add defaults
function addDefaults() {
for (const key in Config.defaults) {
if(!Config.localConfig.hasOwnProperty(key)) {
Config.localConfig[key] = Config.defaults[key];
}
}
};
// Sync config
setupConfig();
export default Config;

1430
src/content.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,107 @@
/*
This is based on code from VideoSegments.
https://github.com/videosegments/videosegments/commits/f1e111bdfe231947800c6efdd51f62a4e7fef4d4/segmentsbar/segmentsbar.js
*/
'use strict';
let barTypes = {
"undefined": {
color: "#00d400",
opacity: "0.5"
},
"sponsor": {
color: "#00d400",
opacity: "0.5"
},
"previewSponsor": {
color: "#0000d4",
opacity: "0.5"
}
};
class PreviewBar {
container: HTMLUListElement;
parent: any;
onMobileYouTube: boolean;
constructor(parent, onMobileYouTube) {
this.container = document.createElement('ul');
this.container.id = 'previewbar';
this.parent = parent;
this.onMobileYouTube = onMobileYouTube;
this.updatePosition(parent);
}
updatePosition(parent) {
//below the seek bar
// this.parent.insertAdjacentElement("afterEnd", this.container);
this.parent = parent;
if (this.onMobileYouTube) {
parent.style.backgroundColor = "rgba(255, 255, 255, 0.3)";
parent.style.opacity = "1";
this.container.style.transform = "none";
}
//on the seek bar
this.parent.insertAdjacentElement("afterBegin", this.container);
}
updateColor(segment, color, opacity) {
let bars = <NodeListOf<HTMLElement>> document.querySelectorAll('[data-vs-segment-type=' + segment + ']');
for (let bar of bars) {
bar.style.backgroundColor = color;
bar.style.opacity = opacity;
}
}
set(timestamps, types, duration) {
while (this.container.firstChild) {
this.container.removeChild(this.container.firstChild);
}
if (!timestamps || !types) {
return;
}
// to avoid rounding error resulting in width more than 100%
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;
let bar = this.createBar();
bar.setAttribute('data-vs-segment-type', types[i]);
bar.style.backgroundColor = barTypes[types[i]].color;
if (!this.onMobileYouTube) bar.style.opacity = barTypes[types[i]].opacity;
bar.style.width = width + '%';
bar.style.left = (timestamps[i][0] / duration * 100) + "%";
bar.style.position = "absolute"
this.container.insertAdjacentElement("beforeend", bar);
}
}
createBar() {
let bar = document.createElement('li');
bar.classList.add('previewbar');
bar.innerHTML = '&nbsp;';
return bar;
}
remove() {
this.container.remove();
this.container = undefined;
}
}
export default PreviewBar;

View File

@@ -0,0 +1,442 @@
'use strict';
/**
* The notice that tells the user that a sponsor was just skipped
*/
class SkipNotice {
parent: HTMLElement;
UUID: string;
manualSkip: boolean;
// Contains functions and variables from the content script needed by the skip notice
contentContainer: () => any;
maxCountdownTime: () => number;
countdownTime: any;
countdownInterval: NodeJS.Timeout;
unskipCallback: any;
idSuffix: any;
constructor(parent: HTMLElement, UUID: string, manualSkip: boolean = false, contentContainer) {
this.parent = parent;
this.UUID = UUID;
this.manualSkip = manualSkip;
this.contentContainer = contentContainer;
let noticeTitle = chrome.i18n.getMessage("noticeTitle");
if (manualSkip) {
noticeTitle = chrome.i18n.getMessage("noticeTitleNotSkipped");
}
this.maxCountdownTime = () => 4;
//the countdown until this notice closes
this.countdownTime = this.maxCountdownTime();
//the id for the setInterval running the countdown
this.countdownInterval = null;
//the unskip button's callback
this.unskipCallback = this.unskip.bind(this);
//add notice
let amountOfPreviousNotices = document.getElementsByClassName("sponsorSkipNotice").length;
//this is the suffix added at the end of every id
this.idSuffix = this.UUID + amountOfPreviousNotices;
if (amountOfPreviousNotices > 0) {
//already exists
let previousNotice = document.getElementsByClassName("sponsorSkipNotice")[0];
previousNotice.classList.add("secondSkipNotice")
}
let noticeElement = document.createElement("div");
//what sponsor time this is about
noticeElement.id = "sponsorSkipNotice" + this.idSuffix;
noticeElement.classList.add("sponsorSkipObject");
noticeElement.classList.add("sponsorSkipNotice");
noticeElement.style.zIndex = String(50 + amountOfPreviousNotices);
if (contentContainer().onMobileYouTube) {
noticeElement.style.bottom = "4em";
noticeElement.style.transform = "scale(0.8) translate(10%, 10%)";
}
//add mouse enter and leave listeners
noticeElement.addEventListener("mouseenter", this.pauseCountdown.bind(this));
noticeElement.addEventListener("mouseleave", this.startCountdown.bind(this));
//the row that will contain the info
let firstRow = document.createElement("tr");
firstRow.id = "sponsorSkipNoticeFirstRow" + this.idSuffix;
let logoColumn = document.createElement("td");
let logoElement = document.createElement("img");
logoElement.id = "sponsorSkipLogo" + this.idSuffix;
logoElement.className = "sponsorSkipLogo sponsorSkipObject";
logoElement.src = chrome.extension.getURL("icons/IconSponsorBlocker256px.png");
let noticeMessage = document.createElement("span");
noticeMessage.id = "sponsorSkipMessage" + this.idSuffix;
noticeMessage.classList.add("sponsorSkipMessage");
noticeMessage.classList.add("sponsorSkipObject");
noticeMessage.innerText = noticeTitle;
//create the first column
logoColumn.appendChild(logoElement);
logoColumn.appendChild(noticeMessage);
//add the x button
let closeButtonContainer = document.createElement("td");
closeButtonContainer.className = "sponsorSkipNoticeRightSection";
closeButtonContainer.style.top = "11px";
let timeLeft = document.createElement("span");
timeLeft.id = "sponsorSkipNoticeTimeLeft" + this.idSuffix;
timeLeft.innerText = this.countdownTime + "s";
timeLeft.className = "sponsorSkipObject sponsorSkipNoticeTimeLeft";
let hideButton = document.createElement("img");
hideButton.src = chrome.extension.getURL("icons/close.png");
hideButton.className = "sponsorSkipObject sponsorSkipNoticeButton sponsorSkipNoticeCloseButton sponsorSkipNoticeRightButton";
hideButton.addEventListener("click", this.close.bind(this));
closeButtonContainer.appendChild(timeLeft);
closeButtonContainer.appendChild(hideButton);
//add all objects to first row
firstRow.appendChild(logoColumn);
firstRow.appendChild(closeButtonContainer);
let spacer = document.createElement("hr");
spacer.id = "sponsorSkipNoticeSpacer" + this.idSuffix;
spacer.className = "sponsorBlockSpacer";
//the row that will contain the buttons
let secondRow = document.createElement("tr");
secondRow.id = "sponsorSkipNoticeSecondRow" + this.idSuffix;
//thumbs up and down buttons
let voteButtonsContainer = document.createElement("td");
voteButtonsContainer.id = "sponsorTimesVoteButtonsContainer" + this.idSuffix;
voteButtonsContainer.className = "sponsorTimesVoteButtonsContainer"
let reportText = document.createElement("span");
reportText.id = "sponsorTimesReportText" + this.idSuffix;
reportText.className = "sponsorTimesInfoMessage sponsorTimesVoteButtonMessage";
reportText.innerText = chrome.i18n.getMessage("reportButtonTitle");
reportText.style.marginRight = "5px";
reportText.setAttribute("title", chrome.i18n.getMessage("reportButtonInfo"));
let downvoteButton = document.createElement("img");
downvoteButton.id = "sponsorTimesDownvoteButtonsContainer" + this.idSuffix;
downvoteButton.className = "sponsorSkipObject voteButton";
downvoteButton.src = chrome.extension.getURL("icons/report.png");
downvoteButton.addEventListener("click", () => this.contentContainer().vote(0, this.UUID, this));
downvoteButton.setAttribute("title", chrome.i18n.getMessage("reportButtonInfo"));
//add downvote and report text to container
voteButtonsContainer.appendChild(reportText);
voteButtonsContainer.appendChild(downvoteButton);
//add unskip button
let unskipContainer = document.createElement("td");
unskipContainer.className = "sponsorSkipNoticeUnskipSection";
let unskipButton = document.createElement("button");
unskipButton.id = "sponsorSkipUnskipButton" + this.idSuffix;
unskipButton.innerText = chrome.i18n.getMessage("unskip");
unskipButton.className = "sponsorSkipObject sponsorSkipNoticeButton";
unskipButton.addEventListener("click", this.unskipCallback);
unskipButton.style.marginLeft = "4px";
unskipContainer.appendChild(unskipButton);
//add don't show again button
let dontshowContainer = document.createElement("td");
dontshowContainer.className = "sponsorSkipNoticeRightSection";
let dontShowAgainButton = document.createElement("button");
dontShowAgainButton.innerText = chrome.i18n.getMessage("Hide");
dontShowAgainButton.className = "sponsorSkipObject sponsorSkipNoticeButton sponsorSkipNoticeRightButton";
dontShowAgainButton.addEventListener("click", this.contentContainer().dontShowNoticeAgain);
// Don't let them hide it if manually skipping
if (!this.manualSkip) {
dontshowContainer.appendChild(dontShowAgainButton);
}
//add to row
secondRow.appendChild(voteButtonsContainer);
secondRow.appendChild(unskipContainer);
secondRow.appendChild(dontshowContainer);
noticeElement.appendChild(firstRow);
noticeElement.appendChild(spacer);
noticeElement.appendChild(secondRow);
//get reference node
let referenceNode = document.getElementById("player-container-id")
|| document.getElementById("movie_player") || document.querySelector("#player-container .video-js");
if (referenceNode == null) {
//for embeds
let player = document.getElementById("player");
referenceNode = <HTMLElement> player.firstChild;
let index = 1;
//find the child that is the video player (sometimes it is not the first)
while (!referenceNode.classList.contains("html5-video-player") || !referenceNode.classList.contains("ytp-embed")) {
referenceNode = <HTMLElement> player.children[index];
index++;
}
}
referenceNode.prepend(noticeElement);
if (manualSkip) {
this.unskippedMode(chrome.i18n.getMessage("skip"));
}
this.startCountdown();
}
//called every second to lower the countdown before hiding the notice
countdown() {
this.countdownTime--;
if (this.countdownTime <= 0) {
//remove this from setInterval
clearInterval(this.countdownInterval);
//time to close this notice
this.close();
return;
}
if (this.countdownTime == 3) {
//start fade out animation
let notice = document.getElementById("sponsorSkipNotice" + this.idSuffix);
notice.style.removeProperty("animation");
notice.classList.add("sponsorSkipNoticeFadeOut");
}
this.updateTimerDisplay();
}
pauseCountdown() {
//remove setInterval
clearInterval(this.countdownInterval);
this.countdownInterval = null;
//reset countdown
this.countdownTime = this.maxCountdownTime();
//inform the user
let timeLeft = document.getElementById("sponsorSkipNoticeTimeLeft" + this.idSuffix);
timeLeft.innerText = chrome.i18n.getMessage("paused");
//remove the fade out class if it exists
let notice = document.getElementById("sponsorSkipNotice" + this.idSuffix);
notice.classList.remove("sponsorSkipNoticeFadeOut");
notice.style.animation = "none";
}
startCountdown() {
//if it has already started, don't start it again
if (this.countdownInterval !== null) return;
this.countdownInterval = setInterval(this.countdown.bind(this), 1000);
this.updateTimerDisplay();
}
updateTimerDisplay() {
//update the timer display
let timeLeft = document.getElementById("sponsorSkipNoticeTimeLeft" + this.idSuffix);
timeLeft.innerText = this.countdownTime + "s";
}
unskip() {
this.contentContainer().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 = this.changeUnskipButton(buttonText);
//setup new callback
this.unskipCallback = this.reskip.bind(this);
unskipButton.addEventListener("click", this.unskipCallback);
//change max duration to however much of the sponsor is left
this.maxCountdownTime = function() {
let sponsorTime = this.contentContainer().sponsorTimes[this.contentContainer().UUIDs.indexOf(this.UUID)];
let duration = Math.round(sponsorTime[1] - this.contentContainer().v.currentTime);
return Math.max(duration, 4);
};
this.countdownTime = this.maxCountdownTime();
this.updateTimerDisplay();
}
reskip() {
this.contentContainer().reskipSponsorTime(this.UUID);
//change reskip button to a unskip button
let unskipButton = this.changeUnskipButton(chrome.i18n.getMessage("unskip"));
//setup new callback
this.unskipCallback = this.unskip.bind(this);
unskipButton.addEventListener("click", this.unskipCallback);
//reset duration
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"));
this.contentContainer().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() {
this.addVoteButtonInfo(chrome.i18n.getMessage("voted"));
this.addNoticeInfoMessage(chrome.i18n.getMessage("hitGoBack"));
//remove this sponsor from the sponsors looked up
//find which one it is
for (let i = 0; i < this.contentContainer().sponsorTimes.length; i++) {
if (this.contentContainer().UUIDs[i] == this.UUID) {
//this one is the one to hide
//add this as a hidden sponsorTime
this.contentContainer().hiddenSponsorTimes.push(i);
this.contentContainer().updatePreviewBar();
break;
}
}
}
changeNoticeTitle(title) {
let noticeElement = document.getElementById("sponsorSkipMessage" + this.idSuffix);
noticeElement.innerText = title;
}
addNoticeInfoMessage(message: string, message2: string = "") {
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() {
let previousInfoMessage = document.getElementById("sponsorTimesInfoMessage" + this.idSuffix);
if (previousInfoMessage != null) {
//remove it
document.getElementById("sponsorSkipNotice" + this.idSuffix).removeChild(previousInfoMessage);
}
}
addVoteButtonInfo(message) {
this.resetVoteButtonInfo();
//hide report button and text for it
let downvoteButton = document.getElementById("sponsorTimesDownvoteButtonsContainer" + this.idSuffix);
if (downvoteButton != null) {
downvoteButton.style.display = "none";
}
let downvoteButtonText = document.getElementById("sponsorTimesReportText" + this.idSuffix);
if (downvoteButtonText != null) {
downvoteButtonText.style.display = "none";
}
//add info
let thanksForVotingText = document.createElement("td");
thanksForVotingText.id = "sponsorTimesVoteButtonInfoMessage" + this.idSuffix;
thanksForVotingText.className = "sponsorTimesInfoMessage sponsorTimesVoteButtonMessage";
thanksForVotingText.innerText = message;
//add element to div
document.getElementById("sponsorSkipNoticeSecondRow" + this.idSuffix).prepend(thanksForVotingText);
}
resetVoteButtonInfo() {
let previousInfoMessage = document.getElementById("sponsorTimesVoteButtonInfoMessage" + this.idSuffix);
if (previousInfoMessage != null) {
//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 !== null) clearInterval(this.countdownInterval);
}
}
export default SkipNotice;

384
src/options.ts Normal file
View File

@@ -0,0 +1,384 @@
import Config from "./config";
import Utils from "./utils";
var utils = new Utils();
window.addEventListener('DOMContentLoaded', init);
async function init() {
utils.localizeHtmlPage();
if (!Config.configListeners.includes(optionsConfigUpdateListener)) {
Config.configListeners.push(optionsConfigUpdateListener);
}
await utils.wait(() => Config.config !== null);
// 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 = Config.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", () => {
Config.config[option] = reverse ? !checkbox.checked : checkbox.checked;
// See if anything extra must be run
switch (option) {
case "supportInvidious":
invidiousOnClick(checkbox, option);
break;
case "disableAutoSkip":
if (!checkbox.checked) {
// Enable the notice
Config.config["dontShowNotice"] = false;
let showNoticeSwitch = <HTMLInputElement> document.querySelector("[sync-option='dontShowNotice'] > label > label > input");
showNoticeSwitch.checked = true;
}
break;
}
});
break;
case "text-change":
let textChangeOption = optionsElements[i].getAttribute("sync-option");
let textChangeInput = <HTMLInputElement> optionsElements[i].querySelector(".option-text-box");
let textChangeSetButton = <HTMLElement> optionsElements[i].querySelector(".text-change-set");
textChangeInput.value = Config.config[textChangeOption];
textChangeSetButton.addEventListener("click", () => {
// See if anything extra must be done
switch (textChangeOption) {
case "serverAddress":
let result = validateServerAddress(textChangeInput.value);
if (result !== null) {
textChangeInput.value = result;
} else {
return;
}
break;
}
Config.config[textChangeOption] = textChangeInput.value;
});
// Reset to the default if needed
let textChangeResetButton = <HTMLElement> optionsElements[i].querySelector(".text-change-reset");
textChangeResetButton.addEventListener("click", () => {
if (!confirm(chrome.i18n.getMessage("areYouSureReset"))) return;
Config.config[textChangeOption] = Config.defaults[textChangeOption];
textChangeInput.value = Config.config[textChangeOption];
});
break;
case "private-text-change":
let button = optionsElements[i].querySelector(".trigger-button");
button.addEventListener("click", () => activatePrivateTextChange(<HTMLElement> optionsElements[i]));
let privateTextChangeOption = optionsElements[i].getAttribute("sync-option");
// See if anything extra must be done
switch (privateTextChangeOption) {
case "invidiousInstances":
invidiousInstanceAddInit(<HTMLElement> optionsElements[i], privateTextChangeOption);
}
break;
case "keybind-change":
let keybindButton = optionsElements[i].querySelector(".trigger-button");
keybindButton.addEventListener("click", () => activateKeybindChange(<HTMLElement> optionsElements[i]));
break;
case "display":
updateDisplayElement(<HTMLElement> optionsElements[i])
break;
case "number-change":
let numberChangeOption = optionsElements[i].getAttribute("sync-option");
let configValue = Config.config[numberChangeOption];
let numberInput = optionsElements[i].querySelector("input");
if (isNaN(configValue) || configValue < 0) {
numberInput.value = Config.defaults[numberChangeOption];
} else {
numberInput.value = configValue;
}
numberInput.addEventListener("input", () => {
Config.config[numberChangeOption] = numberInput.value;
});
break;
}
}
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(<HTMLElement> optionsElements[i])
}
}
}
/**
* Will set display elements to the proper text
*
* @param element
*/
function updateDisplayElement(element: HTMLElement) {
let displayOption = element.getAttribute("sync-option")
let displayText = Config.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 element
* @param option
*/
function invidiousInstanceAddInit(element: HTMLElement, option: string) {
let textBox = <HTMLInputElement> 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 = Config.config[option];
if (!instanceList) instanceList = [];
instanceList.push(textBox.value);
Config.config[option] = instanceList;
let checkbox = <HTMLInputElement> 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
Config.config[option] = Config.defaults[option].slice(0);
}
});
}
/**
* Run when the invidious button is being initialized
*
* @param checkbox
* @param option
*/
function invidiousInit(checkbox: HTMLInputElement, option: string) {
let permissions = ["declarativeContent"];
if (utils.isFirefox()) permissions = [];
chrome.permissions.contains({
origins: utils.getInvidiousInstancesRegex(),
permissions: permissions
}, function (result) {
if (result != checkbox.checked) {
Config.config[option] = result;
checkbox.checked = result;
}
});
}
/**
* Run whenever the invidious checkbox is clicked
*
* @param checkbox
* @param option
*/
function invidiousOnClick(checkbox: HTMLInputElement, option: string) {
if (checkbox.checked) {
utils.setupExtraSitePermissions(function (granted) {
if (!granted) {
Config.config[option] = false;
checkbox.checked = false;
}
});
} else {
utils.removeExtraSiteRegistration();
}
}
/**
* Will trigger the container to ask the user for a keybind.
*
* @param element
*/
function activateKeybindChange(element: HTMLElement) {
let button = element.querySelector(".trigger-button");
if (button.classList.contains("disabled")) return;
button.classList.add("disabled");
let option = element.getAttribute("sync-option");
let currentlySet = Config.config[option] !== null ? chrome.i18n.getMessage("keybindCurrentlySet") : "";
let status = <HTMLElement> element.querySelector(".option-hidden-section > .keybind-status");
status.innerText = chrome.i18n.getMessage("keybindDescription") + currentlySet;
if (Config.config[option] !== null) {
let statusKey = <HTMLElement> element.querySelector(".option-hidden-section > .keybind-status-key");
statusKey.innerText = Config.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 element
* @param e
*/
function keybindKeyPressed(element: HTMLElement, e: KeyboardEvent) {
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");
Config.config[option] = key;
let status = <HTMLElement> element.querySelector(".option-hidden-section > .keybind-status");
status.innerText = chrome.i18n.getMessage("keybindDescriptionComplete");
let statusKey = <HTMLElement> 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 element
*/
function activatePrivateTextChange(element: HTMLElement) {
let button = element.querySelector(".trigger-button");
if (button.classList.contains("disabled")) return;
button.classList.add("disabled");
let textBox = <HTMLInputElement> 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 = Config.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))) {
Config.config[option] = textBox.value;
}
});
element.querySelector(".option-hidden-section").classList.remove("hidden");
}
/**
* Validates the value used for the database server address.
* Returns null and alerts the user if there is an issue.
*
* @param input Input server address
*/
function validateServerAddress(input: string): string {
input = input.trim();
// Trim the trailing slashes
input = input.replace(/\/+$/, "");
// If it isn't HTTP protocol
if ((!input.startsWith("https://") && !input.startsWith("http://"))) {
alert(chrome.i18n.getMessage("customAddressError"));
return null;
}
return input;
}

1132
src/popup.ts Normal file

File diff suppressed because it is too large Load Diff

7
src/types.ts Normal file
View File

@@ -0,0 +1,7 @@
interface videoDurationResponse {
duration: number;
}
export {
videoDurationResponse
};

267
src/utils.ts Normal file
View File

@@ -0,0 +1,267 @@
import Config from "./config";
class Utils {
// Contains functions needed from the background script
backgroundScriptContainer: any = null;
// Used to add content scripts and CSS required
js = [
"./js/vendor.js",
"./js/content.js"
];
css = [
"content.css",
"./libs/Source+Sans+Pro.css",
"popup.css"
];
constructor(backgroundScriptContainer?: any) {
this.backgroundScriptContainer = backgroundScriptContainer;
}
// Function that can be used to wait for a condition before returning
async 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();
});
}
/**
* 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
*/
setupExtraSitePermissions(callback) {
// Request permission
let permissions = ["declarativeContent"];
if (this.isFirefox()) permissions = [];
let self = this;
chrome.permissions.request({
origins: this.getInvidiousInstancesRegex(),
permissions: permissions
}, async function (granted) {
if (granted) {
self.setupExtraSiteContentScripts();
} else {
self.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.
*/
setupExtraSiteContentScripts() {
let self = this;
if (this.isFirefox()) {
let firefoxJS = [];
for (const file of this.js) {
firefoxJS.push({file});
}
let firefoxCSS = [];
for (const file of this.css) {
firefoxCSS.push({file});
}
let registration = {
message: "registerContentScript",
id: "invidious",
allFrames: true,
js: firefoxJS,
css: firefoxCSS,
matches: this.getInvidiousInstancesRegex()
};
if (this.backgroundScriptContainer) {
this.backgroundScriptContainer.registerFirefoxContentScript(registration);
} else {
chrome.runtime.sendMessage(registration);
}
} else {
chrome.declarativeContent.onPageChanged.removeRules(["invidious"], function() {
let conditions = [];
for (const regex of self.getInvidiousInstancesRegex()) {
conditions.push(new chrome.declarativeContent.PageStateMatcher({
pageUrl: { urlMatches: regex }
}));
}
// Add page rule
let rule = {
id: "invidious",
conditions,
// This API is experimental and not visible by the TypeScript compiler
actions: [new (<any> chrome.declarativeContent).RequestContentScript({
allFrames: true,
js: self.js,
css: self.css
})]
};
chrome.declarativeContent.onPageChanged.addRules([rule]);
});
}
}
/**
* Removes the permission and content script registration.
*/
removeExtraSiteRegistration() {
if (this.isFirefox()) {
let id = "invidious";
if (this.backgroundScriptContainer) {
this.backgroundScriptContainer.unregisterFirefoxContentScript(id);
} else {
chrome.runtime.sendMessage({
message: "unregisterContentScript",
id: id
});
}
} else if (chrome.declarativeContent) {
// Only if we have permission
chrome.declarativeContent.onPageChanged.removeRules(["invidious"]);
}
chrome.permissions.remove({
origins: this.getInvidiousInstancesRegex()
});
}
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 = this.getLocalizedMessage(obj.innerHTML.toString());
if (localizedMessage) obj.innerHTML = localizedMessage;
}
}
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
*/
getInvidiousInstancesRegex() {
var invidiousInstancesRegex = [];
for (const url of Config.config.invidiousInstances) {
invidiousInstancesRegex.push("https://*." + url + "/*");
invidiousInstancesRegex.push("http://*." + url + "/*");
}
return invidiousInstancesRegex;
}
generateUserID(length = 36) {
let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let result = "";
if (window.crypto && window.crypto.getRandomValues) {
let values = new Uint32Array(length);
window.crypto.getRandomValues(values);
for (let 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
*/
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;
}
/**
* Sends a request to the SponsorBlock server with address added as a query
*
* @param type The request type. "GET", "POST", etc.
* @param address The address to add to the SponsorBlock server address
* @param callback
*/
sendRequestToServer(type: string, address: string, callback?: (xmlhttp: XMLHttpRequest, err: boolean) => any) {
let xmlhttp = new XMLHttpRequest();
xmlhttp.open(type, Config.config.serverAddress + address, true);
if (callback != undefined) {
xmlhttp.onreadystatechange = function () {
callback(xmlhttp, false);
};
xmlhttp.onerror = function(ev) {
callback(xmlhttp, true);
};
}
//submit this request
xmlhttp.send();
}
/**
* Is this Firefox (web-extensions)
*/
isFirefox() {
return typeof(browser) !== "undefined";
}
}
export default Utils;

12
tsconfig.json Normal file
View File

@@ -0,0 +1,12 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"noImplicitAny": false,
"sourceMap": false,
"outDir": "dist/js",
"noEmitOnError": true,
"typeRoots": [ "node_modules/@types" ],
"resolveJsonModule": true
}
}

49
webpack/webpack.common.js Normal file
View File

@@ -0,0 +1,49 @@
const webpack = require("webpack");
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
const BuildManifest = require('./webpack.manifest');
const srcDir = '../src/';
module.exports = env => ({
entry: {
popup: path.join(__dirname, srcDir + 'popup.ts'),
background: path.join(__dirname, srcDir + 'background.ts'),
content: path.join(__dirname, srcDir + 'content.ts'),
options: path.join(__dirname, srcDir + 'options.ts')
},
output: {
path: path.join(__dirname, '../dist/js'),
filename: '[name].js'
},
optimization: {
splitChunks: {
name: 'vendor',
chunks: "initial"
}
},
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
plugins: [
// exclude locale files in moment
new CopyPlugin([
{ from: '.', to: '../', ignore: ['manifest.json'] }
],
{context: 'public' }
),
new BuildManifest({
browser: env.browser,
pretty: env.mode === "production",
stream: env.stream
})
]
});

7
webpack/webpack.dev.js Normal file
View File

@@ -0,0 +1,7 @@
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = env => merge(common(env), {
devtool: 'inline-source-map',
mode: 'development'
});

View File

@@ -0,0 +1,80 @@
const webpack = require("webpack");
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
const validateOptions = require('schema-utils');
const fs = require('fs');
const manifest = require("../manifest/manifest.json");
const firefoxManifestExtra = require("../manifest/firefox-manifest-extra.json");
const chromeManifestExtra = require("../manifest/chrome-manifest-extra.json");
const betaManifestExtra = require("../manifest/beta-manifest-extra.json");
const firefoxBetaManifestExtra = require("../manifest/firefox-beta-manifest-extra.json");
// schema for options object
const schema = {
type: 'object',
properties: {
browser: {
type: 'string'
},
pretty: {
type: 'boolean'
},
steam: {
type: 'string'
}
}
};
class BuildManifest {
constructor (options = {}) {
validateOptions(schema, options, "Build Manifest Plugin");
this.options = options;
}
apply(compiler) {
const distFolder = path.resolve(__dirname, "../dist/");
const distManifestFile = path.resolve(distFolder, "manifest.json");
// Add missing manifest elements
if (this.options.browser.toLowerCase() === "firefox") {
mergeObjects(manifest, firefoxManifestExtra);
} else if (this.options.browser.toLowerCase() === "chrome" || this.options.browser.toLowerCase() === "chromium") {
mergeObjects(manifest, chromeManifestExtra);
}
if (this.options.stream === "beta") {
mergeObjects(manifest, betaManifestExtra);
if (this.options.browser.toLowerCase() === "firefox") {
mergeObjects(manifest, firefoxBetaManifestExtra);
}
}
let result = JSON.stringify(manifest);
if (this.options.pretty) result = JSON.stringify(manifest, null, 2);
fs.mkdirSync(distFolder, {recursive: true});
fs.writeFileSync(distManifestFile, result);
}
}
function mergeObjects(object1, object2) {
for (const key in object2) {
if (key in object1) {
if (Array.isArray(object1[key])) {
object1[key] = object1[key].concat(object2[key]);
} else if (typeof object1[key] == 'object') {
mergeObjects(object1[key], object2[key]);
} else {
object1[key] = object2[key];
}
} else {
object1[key] = object2[key];
}
}
}
module.exports = BuildManifest;

11
webpack/webpack.prod.js Normal file
View File

@@ -0,0 +1,11 @@
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = env => {
let mode = "production";
env.mode = mode;
return merge(common(env), {
mode
});
};