Compare commits

...

148 Commits

Author SHA1 Message Date
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
Official Noob
d75a7ca897 Added youtube-nocookie.com 2019-08-06 21:40:23 +01:00
17 changed files with 3437 additions and 2722 deletions

View File

@@ -1,16 +1,23 @@
![Logo](icons/LogoSponsorBlocker256px.png)
<br/><sub>Logo by [@munadikieh](https://github.com/munadikieh)</sub>
<p align="center">
<img src="icons/LogoSponsorBlocker256px.png" alt="Logo"></img>
<br/>
<sub>Logo by <a href="https://github.com/munadikieh">@munadikieh</a></sub>
</p>
# SponsorBlock
<h1 align="center">SponsorBlock</h1>
<p align="center">
<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>
[![](https://img.shields.io/amo/users/sponsorblock?label=Firefox%20Users)](https://addons.mozilla.org/addon/sponsorblock/?src=external-github) [![](https://img.shields.io/chrome-web-store/users/mnjggcdmjocbbbhaepdhchncahnbgone?label=Chome%20Users)](https://chrome.google.com/webstore/detail/mnjggcdmjocbbbhaepdhchncahnbgone)
SponsorBlock is an extension that will skip over sponsored segments of YouTube videos. SponsorBlock is a crowdsourced browser extension that lets anyone submit the start and end times of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment.
# Available for Chrome and Firefox
Chrome: https://chrome.google.com/webstore/detail/ajjollijmimolcncegpgkbilohbhjnhi
Firefox: https://addons.mozilla.org/addon/sponsorblock/
# Server
The backend server code is available here: https://github.com/ajayyy/SponsorBlockServer
@@ -25,10 +32,6 @@ Hopefully this project can be combined with projects like [this](https://github.
You can read the API docs [here](https://github.com/ajayyy/SponsorBlockServer#api-docs).
# Previous extension
This project is partially based off of [this experimental extension](https://github.com/OfficialNoob/YTSponsorSkip), which has the basic video skipping functionality.
# Build Yourself
You can load this project as an unpacked extension. Make sure to rename the `config.js.example` file to `config.js` before installing.

View File

@@ -1,115 +1,247 @@
{
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": {
"message": "SponsorBlock for YouTube - Skip Sponsorships",
"description": "Name of the extension."
},
"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"
},
"502": {
"message": "It seems the server is down. Contact the dev to inform them."
},
"channelWhitelisted": {
"message": "Channel Whitelisted!"
},
"Sponsor": {
"message": "Sponsor"
},
"Sponsors": {
"message": "Sponsors"
},
"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"
},
"502": {
"message": "It seems the server is down. Contact the dev to inform them."
},
"channelWhitelisted": {
"message": "Channel Whitelisted!"
},
"Sponsor": {
"message": "sponsor"
},
"Sponsors": {
"message": "sponsors"
},
"Segment": {
"message": "sponsor segment"
},
"Segments": {
"message": "sponsor segments"
},
"noticeTitle": {
"message": "Sponsor Skipped"
},
"noticeClosingMessage": {
"message": "closes in 7s"
},
"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."
},
"goBack": {
"message": "Unskip"
},
"confirmMSG": {
"message": "\n\nTo edit or delete individual values, click the info button or open the extension popup by clicking the extension icon in the top right corner."
},
"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."
},
"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": "\n\nTo edit or delete individual values, click the info button or open the extension popup by clicking the extension icon in the top right corner."
},
"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": "This probably isn't a YouTube tab, or you clicked too early. \n If you know this is a YouTube tab,\n close this popup and open it again."
},
"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)."
}
"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": "This probably isn't a YouTube tab, or you clicked too early. \n If you know this is a YouTube tab,\n close this popup and open it again."
},
"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"
},
"whitelistDescription": {
"message": "Whitelist the channels who do sponsorships ethically to encourage good behavior, or maybe if they are just entertaining and funny. Or don't, that's your call."
},
"voteOnTime": {
"message": "Vote On A Sponsor Time"
},
"recordTimes": {
"message": "Record the times of a sponsorship"
},
"soFarUHSubmited": {
"message": "So far, you've submitted"
},
"savedPeopleFrom": {
"message": "You have saved people from "
},
"viewLeaderboard": {
"message": "View the leaderboard"
},
"here": {
"message": "here"
},
"recordTimesDescription": {
"message": "Click the button below when the sponsorship starts and ends to record and\nsubmit it to the database."
},
"popupHint": {
"message": "Hint: Press the semicolon key while focused on a video report the start/end of a sponsor and quote to submit."
},
"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": "Hide Buttons On YouTube Player"
},
"hideButtons": {
"message": "Show 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 View Tracking"
},
"enableViewTracking": {
"message": "Enable Sponsor View Tracking"
},
"whatViewTracking": {
"message": "This feature tracks which sponsors you have skipped to let users know how much their submission has helped others and\nused as a metric along with upvotes to ensure that spam doesn't get into the database. The extension sends a message\nto the server each time you skip a sponsor. Hopefully most people don't change this setting so that the view numbers are accurate. :)"
},
"showNotice": {
"message": "Show Notice Again"
},
"longDescription": {
"message": "SponsorBlock is an extension that will skip over sponsored segments of YouTube videos. SponsorBlock is a crowdsourced browser extension that let's anyone submit the start and end time's of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment.",
"description": "Full description of the extension on the store pages."
},
"website": {
"message": "Website",
"description": "Used on Firefox Store Page"
},
"sourceCode": {
"message": "Source Code",
"description": "Used on Firefox Store Page"
}
}

129
_locales/fr/messages.json Normal file
View File

@@ -0,0 +1,129 @@
{
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": {
"message": "SponsorBlock pour YouTube - Enlève 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, il y en a vraiment autant ?"
},
"409": {
"message": "Déja soumis"
},
"502": {
"message": "Le serveur ne fonctionne pas. Contactez le développeur."
},
"channelWhitelisted": {
"message": "Cette chaine est sur la liste blanche !"
},
"Sponsor": {
"message": "message commercial"
},
"Sponsors": {
"message": "messages commerciaux"
},
"Segment": {
"message": "segment de message commercial"
},
"Segments": {
"message": "segments de message commercial"
},
"noticeTitle": {
"message": "Message passé"
},
"reportButtonTitle": {
"message": "Incorrect"
},
"reportButtonInfo": {
"message": "Signaler que ce segment 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"
},
"unskip": {
"message": "Revenir en arrière"
},
"reskip": {
"message": "Sauter"
},
"paused": {
"message": "En pause"
},
"confirmMSG": {
"message": "\n\nPour modifier ou enlever des soumissions, cliquez sur le bouton d'info."
},
"clearThis": {
"message": "Êtes-vous certain(e) que vous voulez enlever vos soumissions ?\n\n"
},
"Unknown": {
"message": "Erreur, 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 trouvés"
},
"sponsorStart": {
"message": "Début du message"
},
"sponsorEnd": {
"message": "Fin du message"
},
"noVideoID": {
"message": "Ceci n'est pas un onglet YouTube, ou vous avez cliqué trop tôt. \n Si vous êtes sur(e) que c'est un onglet YouTube, fermez ce menu et réessayer."
},
"success": {
"message": "Succès !"
},
"voted": {
"message": "A voté !"
},
"voteFail": {
"message": "Vous avez déjà voté pour ce choix auparavant."
},
"serverDown": {
"message": "Le serveur ne fonctionne pas. Contactez le développeur."
},
"connectionError": {
"message": "Erreur de connexion, Code : "
},
"wantToSubmit": {
"message": "Voulez-vous soumettre les messages pour cette vidéo"
},
"leftTimes": {
"message": "Vous avez laissé des messages non soumis. Retournez sur la vidéo pour les soumettre (ils ont été conservés)."
},
"submitCheck": {
"message": "Soumettre ce(s) message(s) ?"
}
}

View File

@@ -0,0 +1,127 @@
{
"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"
},
"502": {
"message": "Parece que o servidor caiu. Contate o desenvolvedor para informá-los."
},
"channelWhitelisted": {
"message": "Canal adicionado a lista branca!"
},
"Sponsor": {
"message": "patrocinador"
},
"Sponsors": {
"message": "patrocinadores"
},
"Segment": {
"message": "segmento de patrocinador"
},
"Segments": {
"message": "segmento 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 fecha esse popup e abre 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ê esqueceu de enviar alguns segmentos. Volta pra página para enviar eles (não foram deletados)."
}
}

130
_locales/ru/messages.json Normal file
View File

@@ -0,0 +1,130 @@
{
"Name": {
"message": "SponsorBlock",
"description": "Название расширения, не переводится."
},
"fullName": {
"message": "SponsorBlock для YouTube - Пропускайте спонсорские вставки",
"description": "Название расширения."
},
"Description": {
"message": "Пропускайте спонсорские вставки в видео на YouTube. Сообщайте о спонсорских вставках в видео, которые Вы смотрите, чтобы сэкономить время других пользователей.",
"description": "Описание раширения."
},
"helpPage": {
"message": "index_en.html"
},
"400": {
"message": "Сервер отклонил этот запрос."
},
"429": {
"message": "Вы отправили слишком много спонсоров для этого видео. Вы уверены, что их так много?"
},
"409": {
"message": "Этот запрос был отправлен ранее."
},
"502": {
"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": "Вы уверены, что хотите отправить эту информацию?"
}
}

View File

@@ -1,221 +1,242 @@
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
chrome.tabs.sendMessage(tabId, {
message: 'update',
message: 'update',
});
});
chrome.runtime.onMessage.addListener(function (request, sender, callback) {
switch(request.message) {
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: 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":
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: 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: "Do you want to submit the sponsor times for video id " + request.previousVideoID + "?",
message: "You seem to have left some sponsor times unsubmitted. Go back to that page to submit them (they are not deleted).",
iconUrl: "./icons/LogoSponsorBlocker256px.png"
type: "basic",
title: chrome.i18n.getMessage("wantToSubmit") + request.previousVideoID + "?",
message: chrome.i18n.getMessage("leftTimes"),
iconUrl: "./icons/LogoSponsorBlocker256px.png"
});
}
});
//add help page on install
chrome.runtime.onInstalled.addListener(function (object) {
// TODO (shownInstallPage): remove shownInstallPage logic after sufficient amount of time,
// so that people have time to upgrade and move to shownInstallPage-free code.
chrome.storage.sync.get(["userID", "shownInstallPage"], function(result) {
const userID = result.userID;
// TODO (shownInstallPage): delete row below
const shownInstallPage = result.shownInstallPage;
// TODO (shownInstallPage): remove shownInstallPage logic after sufficient amount of time,
// so that people have time to upgrade and move to shownInstallPage-free code.
chrome.storage.sync.get(["userID", "shownInstallPage"], function(result) {
const userID = result.userID;
// TODO (shownInstallPage): delete row below
const shownInstallPage = result.shownInstallPage;
// If there is no userID, then it is the first install.
if (!userID){
// Show install page, if there is no user id
// and there is no shownInstallPage.
// TODO (shownInstallPage): remove this if statement, but leave contents
if (!shownInstallPage){
//open up the install page
chrome.tabs.create({url: chrome.extension.getURL("/help/"+chrome.i18n.getMessage("helpPage"))});
}
// If there is no userID, then it is the first install.
if (!userID){
// Show install page, if there is no user id
// and there is no shownInstallPage.
// TODO (shownInstallPage): remove this if statement, but leave contents
if (!shownInstallPage){
//open up the install page
chrome.tabs.create({url: chrome.extension.getURL("/help/"+chrome.i18n.getMessage("helpPage"))});
}
// TODO (shownInstallPage): delete if statement and contents
// If shownInstallPage is set, remove it.
if (!!shownInstallPage){
chrome.storage.sync.remove("shownInstallPage");
}
// TODO (shownInstallPage): delete if statement and contents
// If shownInstallPage is set, remove it.
if (!!shownInstallPage){
chrome.storage.sync.remove("shownInstallPage");
}
//generate a userID
const newUserID = generateUUID();
//save this UUID
chrome.storage.sync.set({
"userID": newUserID,
//the last video id loaded, to make sure it is a video id change
"sponsorVideoID": null,
"previousVideoID": null
});
}
});
//generate a userID
const newUserID = generateUserID();
//save this UUID
chrome.storage.sync.set({
"userID": newUserID
});
}
});
});
//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;
}
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)
});
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] = [];
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;
}
sponsorTimes[sponsorTimesIndex][0] = time;
}
//save this info
let sponsorTimeKey = "sponsorTimes" + videoID;
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes}, callback);
});
//save this info
let sponsorTimeKey = "sponsorTimes" + videoID;
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes}, callback);
});
}
function submitVote(type, UUID, callback) {
chrome.storage.sync.get(["userID"], function(result) {
let userID = result.userID;
chrome.storage.sync.get(["userID"], function(result) {
let userID = result.userID;
//publish this vote
sendRequestToServer("GET", "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + "&type=" + type, function(xmlhttp, error) {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
callback({
successType: 1
});
} else if (xmlhttp.readyState == 4 && xmlhttp.status == 405) {
//duplicate vote
callback({
successType: 0,
statusCode: xmlhttp.status
});
} else if (error) {
//error while connect
callback({
successType: -1,
statusCode: xmlhttp.status
});
}
if (userID == undefined || userID === "undefined") {
//generate one
userID = generateUserID();
chrome.storage.sync.set({
"userID": userID
});
}
//publish this vote
sendRequestToServer("GET", "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + "&type=" + type, function(xmlhttp, error) {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
callback({
successType: 1
});
} else if (xmlhttp.readyState == 4 && xmlhttp.status == 405) {
//duplicate vote
callback({
successType: 0,
statusCode: xmlhttp.status
});
} else if (error) {
//error while connect
callback({
successType: -1,
statusCode: xmlhttp.status
});
}
})
})
})
}
function submitTimes(videoID, callback) {
//get the video times from storage
let sponsorTimeKey = 'sponsorTimes' + videoID;
chrome.storage.sync.get([sponsorTimeKey, "userID"], function(result) {
let sponsorTimes = result[sponsorTimeKey];
let userID = result.userID;
//get the video times from storage
let sponsorTimeKey = 'sponsorTimes' + videoID;
chrome.storage.sync.get([sponsorTimeKey, "userID"], async function(result) {
let sponsorTimes = result[sponsorTimeKey];
let userID = result.userID;
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
//submit these times
for (let i = 0; i < sponsorTimes.length; i++) {
//submit the sponsorTime
sendRequestToServer("GET", "/api/postVideoSponsorTimes?videoID=" + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1]
+ "&userID=" + userID, function(xmlhttp, error) {
if (xmlhttp.readyState == 4 && !error) {
callback({
statusCode: xmlhttp.status
});
if (xmlhttp.status == 200) {
//add these to the storage log
chrome.storage.sync.get(["sponsorTimesContributed"], function(result) {
let currentContributionAmount = 0;
if (result.sponsorTimesContributed != undefined) {
//current contribution amount is known
currentContributionAmount = result.sponsorTimesContributed;
}
//save the amount contributed
chrome.storage.sync.set({"sponsorTimesContributed": currentContributionAmount + sponsorTimes.length});
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
let durationResult = await new Promise((resolve, reject) => {
chrome.tabs.query({
active: true,
currentWindow: true
}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {
message: "getVideoDuration"
}, (response) => resolve(response));
});
}
} else if (error) {
callback({
statusCode: -1
});
});
//check if a sponsor exceeds the duration of the video
for (let i = 0; i < sponsorTimes.length; i++) {
if (sponsorTimes[i][1] > durationResult.duration) {
sponsorTimes[i][1] = durationResult.duration;
}
}
});
}
}
});
//submit these times
for (let i = 0; i < sponsorTimes.length; i++) {
//submit the sponsorTime
sendRequestToServer("GET", "/api/postVideoSponsorTimes?videoID=" + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1]
+ "&userID=" + userID, function(xmlhttp, error) {
if (xmlhttp.readyState == 4 && !error) {
callback({
statusCode: xmlhttp.status
});
if (xmlhttp.status == 200) {
//add these to the storage log
chrome.storage.sync.get(["sponsorTimesContributed"], function(result) {
let currentContributionAmount = 0;
if (result.sponsorTimesContributed != undefined) {
//current contribution amount is known
currentContributionAmount = result.sponsorTimesContributed;
}
//save the amount contributed
chrome.storage.sync.set({"sponsorTimesContributed": currentContributionAmount + sponsorTimes.length});
});
}
} else if (error) {
callback({
statusCode: -1
});
}
});
}
}
});
}
function sendRequestToServer(type, address, callback) {
let xmlhttp = new XMLHttpRequest();
let xmlhttp = new XMLHttpRequest();
xmlhttp.open(type, serverAddress + address, true);
xmlhttp.open(type, serverAddress + address, true);
if (callback != undefined) {
xmlhttp.onreadystatechange = function () {
callback(xmlhttp, false);
};
if (callback != undefined) {
xmlhttp.onreadystatechange = function () {
callback(xmlhttp, false);
};
xmlhttp.onerror = function(ev) {
callback(xmlhttp, true);
};
}
//submit this request
xmlhttp.send();
}
function generateUUID(length = 36) {
let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let result = "";
let isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
if (window.crypto && window.crypto.getRandomValues) {
values = new Uint32Array(length);
window.crypto.getRandomValues(values);
for (i = 0; i < length; i++) {
result += charset[values[i] % charset.length];
}
return result;
} else {
for (let i = 0; i < length; i++) {
result += charset[Math.floor(Math.random() * charset.length)];
}
return result;
xmlhttp.onerror = function(ev) {
callback(xmlhttp, true);
};
}
//submit this request
xmlhttp.send();
}
function generateUserID(length = 36) {
let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let result = "";
if (window.crypto && window.crypto.getRandomValues) {
values = new Uint32Array(length);
window.crypto.getRandomValues(values);
for (i = 0; i < length; i++) {
result += charset[values[i] % charset.length];
}
return result;
} else {
for (let i = 0; i < length; i++) {
result += charset[Math.floor(Math.random() * charset.length)];
}
return result;
}
}

View File

@@ -58,6 +58,11 @@
to { opacity: 1; }
}
@keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
.sponsorBlockSpacer {
background-color: rgb(100, 100, 100);
border-color: rgb(100, 100, 100);
@@ -66,7 +71,7 @@
}
.sponsorSkipNotice {
min-width: 280px;
min-width: 300px;
background-color: rgba(28, 28, 28, 0.9);
position: absolute;
right: 5px;
@@ -82,6 +87,10 @@
padding-right: 5px;
}
.sponsorSkipNoticeFadeOut {
animation: fadeOut 3s cubic-bezier(0.55, 0.055, 0.675, 0.19);
}
.sponsorSkipNoticeTimeLeft {
color: #eeeeee;
@@ -105,11 +114,6 @@
border-left: 1px solid rgb(150, 150, 150);
}
.sponsorSkipNoticeCloseButton {
height: 10px;
width: 10px;
}
.sponsorSkipNoticeButton {
background: none;
color: rgb(235, 235, 235);
@@ -119,6 +123,23 @@
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 {
@@ -131,8 +152,17 @@
}
.sponsorSkipNoticeRightButton {
margin-left: 7px;
padding: 0px;
margin-right: 0;
}
.sponsorSkipNoticeCloseButton {
height: 10px;
width: 10px;
padding: 2px 5px;
margin-left: 2px;
float: right;
}
.sponsorSkipMessage {
@@ -178,7 +208,7 @@
}
.voteButton {
height: 18px;
height: 17px;
cursor: pointer;
}
.voteButton:hover {

1833
content.js

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,68 +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",
"popup.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/PlayerInfoIconSponsorBlocker256px.png",
"icons/PlayerDeleteIconSponsorBlocker256px.png",
"popup.html",
"help/index.html",
"help/style.css"
],
"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
}

View File

@@ -1,18 +1,20 @@
{
"name": "__MSG_fullName__",
"short_name": "__MSG_Name__",
"version": "1.0.37",
"version": "1.1.8",
"default_locale": "en",
"description": "__MSG_Description__",
"content_scripts": [
{
"matches": [
"https://*.youtube.com/*"
"https://*.youtube.com/*",
"https://www.youtube-nocookie.com/embed/*"
],
"all_frames": true,
"js": [
"config.js",
"utils/previewBar.js",
"utils/skipNotice.js",
"utils.js",
"content.js",
"popup.js"

View File

@@ -10,8 +10,8 @@ h1.popupElement {
margin-block-start: 0.67em;
margin-block-end: 0.67em;
margin-inline-start: 0px;
margin-inline-end: 0px;
font-weight: bold;
margin-inline-end: 0px;
font-weight: bold;
}
h2.popupElement {
@@ -36,9 +36,9 @@ sub.popupElement {
/* end reset */
.popupElement {
font-family: 'Source Sans Pro', sans-serif;
font-family: 'Source Sans Pro', sans-serif;
color: black;
color: black;
}
h1.popupElement {
@@ -109,43 +109,43 @@ h1.popupElement {
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;
}
}
.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;
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;
background-color:#bf2a2a;
}
.greenButton:focus.popupElement {
outline: none;
background-color:#bf2a2a;
}
.greenButton:active.popupElement {
position:relative;
top:1px;
position:relative;
top:1px;
}
.dangerButton.popupElement {

View File

@@ -1,6 +1,6 @@
<html>
<head>
<title>SponsorBlock Popup</title>
<title>__MSG_openPopup__</title>
<link id="sponorBlockPopupFont" rel="stylesheet" type="text/css" href="/libs/Source+Sans+Pro.css"/>
<link id="sponorBlockStyleSheet" rel="stylesheet" type="text/css" href="popup.css"/>
</head>
@@ -10,10 +10,10 @@
<div id="app" class="popupBody">
<img src="icons/LogoSponsorBlocker256px.png" height="64px" id="sponsorBlockPopupLogo"/>
<h1 class="popupElement">SponsorBlock</h1>
<h1 class="popupElement">__MSG_Name__</h1>
<!-- Loading text -->
<p id="loadingIndicator" class="popupElement">Loading...</p>
<p id="loadingIndicator" class="popupElement">__MSG_Loading__</p>
<!-- Hidden until loading complete -->
<div id="mainControls" class="main popupElement" style="display: none">
@@ -29,21 +29,21 @@
<br/>
<div>
<button id="whitelistChannel" class="whitelistButton popupElement">Whitelist Channel</button>
<button id="unwhitelistChannel" class="whitelistButton popupElement" style="display: none">Remove Channel From Whitelist</button>
<button id="whitelistChannel" class="whitelistButton popupElement">__MSG_whitelistChannel__</button>
<button id="unwhitelistChannel" class="whitelistButton popupElement" style="display: none">__MSG_removeFromWhitelist__</button>
</div>
<sub class="popupElement">
Whitelist the channels who do sponsorships ethically to encourage good behavior, or maybe if they are just entertaining and funny. Or don't, that's your call.
__MSG_whitelistDescription__
</sub>
<br/>
<br/>
<button id="reportAnIssue" class="dangerButton popupElement">Vote On A Sponsor Time</button>
<button id="reportAnIssue" class="dangerButton popupElement">__MSG_voteOnTime__</button>
<div id="issueReporterContainer" class="popupElement" style="display: none">
<h3 style="margin-top: 0px" class="popupElement">Vote On A Sponsor Time</h3>
<h3 style="margin-top: 0px" class="popupElement">__MSG_voteOnTime__</h3>
<div id="issueReporterTimeButtons" class="popupElement">
@@ -51,47 +51,47 @@
</div>
<h2 class="recordingSubtitle popupElement">Record the times of a sponsorship</h2>
<h2 class="recordingSubtitle popupElement">__MSG_recordTimes__</h2>
<p class="popupElement">
<span id=sponsorTimesContributionsContainer class="popupElement" style="display: none">
So far, you've submitted
__MSG_soFarUHSubmited__
<span id="sponsorTimesContributionsDisplay" class="popupElement">
0
</span>
<span id="sponsorTimesContributionsDisplayEndWord" class="popupElement">
sponsors.
__MSG_Sponsors__.
</span>
</span>
<span id=sponsorTimesViewsContainer class="popupElement" style="display: none">
You have saved people from
__MSG_savedPeopleFrom__
<span id="sponsorTimesViewsDisplay" class="popupElement">
0
</span>
<span id="sponsorTimesViewsDisplayEndWord" class="popupElement">
sponsor segments.
__MSG_Segments__.
__MSG_savedPeopleFrom__
</span>
</span>
<div class="popupElement">
View the leaderboard <a class="popupElement discreteLink" href="https://sponsor.ajay.app/stats" target="_blank">here</a>.
__MSG_viewLeaderboard__ <a class="popupElement discreteLink" href="https://sponsor.ajay.app/stats" target="_blank">__MSG_here__</a>.
</div>
</p>
<p class="popupElement">
Click the button below when the sponsorship starts and ends to record and
submit it to the database.
__MSG_recordTimesDescription__
</p>
<div>
<button id="sponsorStart" class="greenButton popupElement">Sponsorship Starts Now</button>
<button id="sponsorStart" class="greenButton popupElement">__MSG_sponsorStart__</button>
</div>
<sub class="popupElement">Hint: Press the semicolon key while focused on a video report the start/end of a sponsor and quote to submit.</sub>
<sub class="popupElement">__MSG_popupHint__</sub>
<div id="submissionSection" class="popupElement" style="display: none">
<h3 class="popupElement">Latest Sponsor Message Times Chosen</h3>
<h3 class="popupElement">__MSG_lastTimes__</h3>
<b>
<div id="sponsorMessageTimes" class="popupElement">
@@ -100,13 +100,13 @@
<br/>
<button id="clearTimes" class="smallButton popupElement">Clear Times</button>
<button id="clearTimes" class="smallButton popupElement">__MSG_clearTimesButton__</button>
<br/>
<br/>
<div id="submitTimesContainer" class="popupElement" style="display: none">
<button id="submitTimes" class="smallButton popupElement">Submit Times</button>
<button id="submitTimes" class="smallButton popupElement">__MSG_submitTimesButton__</button>
<div id="submitTimesInfoMessageContainer" class="popupElement" style="display: none">
<h3 id="submitTimesInfoMessage" class="popupElement">
@@ -122,17 +122,17 @@
<br/>
<br/>
<button id="setUsernameButton" class="warningButton popupElement">Set Username</button>
<button id="setUsernameButton" class="warningButton popupElement">__MSG_setUsername__</button>
<br/>
<sub class="popupElement">
This is used on the public stats page to show off how much you've contributed. See it <a class="popupElement discreteLink" href="https://sponsor.ajay.app/stats" target="_blank">here</a>.
__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">
<br/>
<h3>Set Username</h3>
<h3>__MSG_setUsername__</h3>
<div id="setUsernameStatusContainer" style="display: none">
<h2 id="setUsernameStatus"></h2>
@@ -154,72 +154,66 @@
<br/>
Come join the official discord server to give suggestions and feedback!
__MSG_discordAdvert__
<br/>
<span id="hideDiscordButton" class="smallLink popupElement">Hide this</span>
<span id="hideDiscordButton" class="smallLink popupElement">__MSG_hideThis__</span>
</div>
<div id="optionsButtonContainer" class="popupElement">
<br/>
<br/>
<button id="optionsButton" class="dangerButton popupElement">Options</button>
<button id="optionsButton" class="dangerButton popupElement">__MSG_Options__</button>
</div>
<div id="options" class="popupElement" style="display: none">
<br/>
<h3>Options</h3>
<h3>__MSG_Options__</h3>
<button id="hideVideoPlayerControls" class="warningButton popupElement">Hide Buttons On YouTube Player</button>
<button id="showVideoPlayerControls" style="display: none" class="warningButton popupElement">Show Buttons On YouTube Player</button>
<button id="hideVideoPlayerControls" class="warningButton popupElement">__MSG_hideButtons__</button>
<button id="showVideoPlayerControls" style="display: none" class="warningButton popupElement">__MSG_showButtons__</button>
<br/>
<sub class="popupElement">
This hides the buttons that appear on the YouTube player to submit sponsors. I can see this being annoying for some
people. Instead of using the button there, this popup can be used to submit sponsors. To hide the notice that appears,
use the button that appears on the notice saying "Don't show this again". You can always enable these settings again
later.
__MSG_hideButtonsDescription__
</sub>
<br/>
<br/>
<button id="hideInfoButtonPlayerControls" class="warningButton popupElement">Hide Info Button On YouTube Player</button>
<button id="showInfoButtonPlayerControls" style="display: none" class="warningButton popupElement">Show Info Button On YouTube Player</button>
<button id="hideInfoButtonPlayerControls" class="warningButton popupElement">__MSG_hideInfoButton__</button>
<button id="showInfoButtonPlayerControls" style="display: none" class="warningButton popupElement">__MSG_showInfoButton__</button>
<br/>
<sub class="popupElement">
This is the button that opens up a popup in the YouTube page.
__MSG_whatInfoButton__
</sub>
<br/>
<br/>
<button id="hideDeleteButtonPlayerControls" class="warningButton popupElement">Hide Delete Button On YouTube Player</button>
<button id="showDeleteButtonPlayerControls" style="display: none" class="warningButton popupElement">Show Delete Button On YouTube Player</button>
<button id="hideDeleteButtonPlayerControls" class="warningButton popupElement">__MSG_hideDeleteButton__</button>
<button id="showDeleteButtonPlayerControls" style="display: none" class="warningButton popupElement">__MSG_showDeleteButton__</button>
<br/>
<sub class="popupElement">
This is the button that allows you to clear all sponsors on the YouTube player.
__MSG_whatDeleteButton__
</sub>
<br/>
<br/>
<button id="disableSponsorViewTracking" class="warningButton popupElement">Disable Sponsor View Tracking</button>
<button id="enableSponsorViewTracking" style="display: none" class="warningButton popupElement">Enable Sponsor View Tracking</button>
<button id="disableSponsorViewTracking" class="warningButton popupElement">__MSG_disableViewTracking__</button>
<button id="enableSponsorViewTracking" style="display: none" class="warningButton popupElement">__MSG_enableViewTracking__</button>
<br/>
<sub class="popupElement">
This feature tracks which sponsors you have skipped to let users know how much their submission has helped others and
used as a metric along with upvotes to ensure that spam doesn't get into the database. The extension sends a message
to the server each time you skip a sponsor. Hopefully most people don't change this setting so that the view numbers
are accurate. :)
__MSG_whatViewTracking__
</sub>
<br/>
<br/>
<button id="showNoticeAgain" style="display: none" class="dangerButton popupElement">Show Notice Again</button>
<button id="showNoticeAgain" style="display: none" class="dangerButton popupElement">__MSG_showNotice__</button>
</div>
</div>
</div>

2460
popup.js

File diff suppressed because it is too large Load Diff

View File

@@ -1,37 +1,68 @@
// Function that can be used to wait for a condition before returning
async function wait(condition, timeout = 5000, check = 100) {
return await new Promise((resolve, reject) => {
setTimeout(() => reject("TIMEOUT"), timeout);
let intervalCheck = () => {
let result = condition();
if (result !== false) {
resolve(result);
clearInterval(interval);
};
};
let interval = setInterval(intervalCheck, check);
//run the check once first, this speeds it up a lot
intervalCheck();
});
}
function getYouTubeVideoID(url) {
//Attempt to parse url
let urlObject = null;
try {
urlObject = new URL(url);
urlObject = new URL(url);
} catch (e) {
console.error("[SB] Unable to parse URL: " + url);
return false
console.error("[SB] Unable to parse URL: " + url);
return false;
}
//Check if valid hostname
if(!["www.youtube.com","www.youtube-nocookie.com"].includes(urlObject.host)) return false;
//Get ID from searchParam
if ((urlObject.pathname == "/watch" || urlObject.pathname == "/watch/") && urlObject.searchParams.has("v")) {
id = urlObject.searchParams.get("v");
return id.length == 11 ? id : false;
id = urlObject.searchParams.get("v");
return id.length == 11 ? id : false;
} else if (urlObject.pathname.startsWith("/embed/")) {
try {
return urlObject.pathname.substr(7, 11);
} catch (e) {
console.error("[SB] Video ID not valid for " + url);
return false;
}
try {
return urlObject.pathname.substr(7, 11);
} catch (e) {
console.error("[SB] Video ID not valid for " + url);
return false;
}
}
return false;
}
function localizeHtmlPage() {
//Localize by replacing __MSG_***__ meta tags
var objects = document.getElementsByClassName("popupBody")[0].children;
for (var j = 0; j < objects.length; j++) {
var obj = objects[j];
var valStrH = obj.innerHTML.toString();
var valNewH = valStrH.replace(/__MSG_(\w+)__/g, function(match, v1)
{
return v1 ? chrome.i18n.getMessage(v1) : "";
});
if(valNewH != valStrH)
{
obj.innerHTML = valNewH;
}
}
}
//returns the start time of the video if there was one specified (ex. ?t=5s)
function getYouTubeVideoStartTime(url) {
let searchParams = new URL(url).searchParams;
let startTime = searchParams.get("t");
if (startTime == null) {
startTime = searchParams.get("time_continue");
}
return startTime;
}

View File

@@ -13,6 +13,10 @@ let barTypes = {
"sponsor": {
color: "#00d400",
opacity: "0.5"
},
"previewSponsor": {
color: "#0000d4",
opacity: "0.5"
}
};

367
utils/skipNotice.js Normal file
View File

@@ -0,0 +1,367 @@
'use strict';
//The notice that tells the user that a sponsor was just skipped
class SkipNotice {
constructor(parent, UUID) {
this.parent = parent;
this.UUID = UUID;
this.maxCountdownTime = () => 4;
//the countdown until this notice closes
this.countdownTime = this.maxCountdownTime();
//the id for the setInterval running the countdown
this.countdownInterval = -1;
//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 = 50 + amountOfPreviousNotices;
//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 = chrome.i18n.getMessage("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", () => 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", dontShowNoticeAgain);
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("movie_player");
if (referenceNode == null) {
//for embeds
let player = document.getElementById("player");
referenceNode = 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 = player.children[index];
index++;
}
}
referenceNode.prepend(noticeElement);
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 = -1;
//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 != -1) 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() {
unskipSponsorTime(this.UUID);
//change unskip button to a reskip button
let unskipButton = document.getElementById("sponsorSkipUnskipButton" + this.idSuffix);
unskipButton.innerText = chrome.i18n.getMessage("reskip");
unskipButton.removeEventListener("click", this.unskipCallback);
//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 = sponsorTimes[UUIDs.indexOf(this.UUID)];
let duration = Math.round(sponsorTime[1] - v.currentTime);
return Math.max(duration, 4);
};
this.countdownTime = this.maxCountdownTime();
this.updateTimerDisplay();
}
reskip() {
reskipSponsorTime(this.UUID);
//change unskip button to a reskip button
let unskipButton = document.getElementById("sponsorSkipUnskipButton" + this.idSuffix);
unskipButton.innerText = chrome.i18n.getMessage("unskip");
unskipButton.removeEventListener("click", this.unskipCallback);
//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();
}
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 < sponsorTimes.length; i++) {
if (UUIDs[i] == this.UUID) {
//this one is the one to hide
//add this as a hidden sponsorTime
hiddenSponsorTimes.push(i);
let sponsorTimesLeft = sponsorTimes.slice();
for (let j = 0; j < hiddenSponsorTimes.length; j++) {
//remove this sponsor time
sponsorTimesLeft.splice(hiddenSponsorTimes[j], 1);
}
//update the preview
previewBar.set(sponsorTimesLeft, [], v.duration);
break;
}
}
}
addNoticeInfoMessage(message) {
let previousInfoMessage = document.getElementById("sponsorTimesInfoMessage" + this.idSuffix);
if (previousInfoMessage != null) {
//remove it
document.getElementById("sponsorSkipNotice" + this.idSuffix).removeChild(previousInfoMessage);
}
//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));
}
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() {
let notice = document.getElementById("sponsorSkipNotice" + this.idSuffix);
if (notice != null) {
notice.remove();
}
//remove setInterval
if (this.countdownInterval != -1) clearInterval(this.countdownInterval);
}
}