Compare commits

...

132 Commits

Author SHA1 Message Date
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
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
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
Ajay Ramachandran
32884372fa Unsubmitted sponsors are now in the preview. 2019-08-21 14:27:25 -04: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
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
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
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
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
Official Noob
afa260b733 Merge branch 'experimental' into patch-18 2019-08-12 21:02:55 +01: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
Official Noob
5347b9c935 Merge branch 'experimental' into patch-18 2019-08-12 15:59:25 +01: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
20 changed files with 3299 additions and 2494 deletions

View File

@@ -1,16 +1,22 @@
![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>
<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>
# SponsorBlock
SponsorBlock is an extension that will skip over sponsored segments of YouTube videos. SponsorBlock is a crowdsourced browser extension that lets anyone submit the start and end times of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment.
# Available for Chrome and Firefox
Chrome: https://chrome.google.com/webstore/detail/ajjollijmimolcncegpgkbilohbhjnhi
Firefox: https://addons.mozilla.org/addon/sponsorblock/
# Server
The backend server code is available here: https://github.com/ajayyy/SponsorBlockServer
@@ -25,10 +31,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.

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

@@ -0,0 +1,130 @@
{
"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"
},
"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": "\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."
},
"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)."
},
"submitCheck": {
"message": "Are you sure you want to submit this?"
}
}

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 endossements",
"description": "Name of the extension."
},
"Description": {
"message": "Enlève les endossements dans les vidéos YouTube. Soummettre les endossements 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 avez soummetez trop de endossements, il y a vraiment cette montant?"
},
"409": {
"message": "Déjas soummis"
},
"502": {
"message": "Le serveur ne fonctionne pas. Message le développeur."
},
"channelWhitelisted": {
"message": "Cette channel est sur la liste blanche!"
},
"Sponsor": {
"message": "endossement"
},
"Sponsors": {
"message": "endossements"
},
"Segment": {
"message": "section d'endossement"
},
"Segments": {
"message": "section d'endossements"
},
"noticeTitle": {
"message": "Endossement Passer"
},
"reportButtonTitle": {
"message": "Incorrect"
},
"reportButtonInfo": {
"message": "Informe que cette endossement est incorrect ou n'existe pas."
},
"Dismiss": {
"message": "Ferme"
},
"Loading": {
"message": "Chargement en cours..."
},
"Mins": {
"message": "Minutes"
},
"Secs": {
"message": "Seconds"
},
"Hide": {
"message": "Ne Montre Jaimais"
},
"hitGoBack": {
"message": "Clique retourne pour si vous avez manqué parti."
},
"unskip": {
"message": "Retourne"
},
"reskip": {
"message": "Resaute"
},
"paused": {
"message": "Pause"
},
"confirmMSG": {
"message": "\n\nPour modifier ou enlever des soumissions, clique sur le bouton d'info."
},
"clearThis": {
"message": "Êtes-vous certaines vous voulez enlever vos soumissions?\n\n"
},
"Unknown": {
"message": "Erreur, essayer encore plus tard."
},
"sponsorFound": {
"message": "Cette vidéo est dans le database!"
},
"sponsor404": {
"message": "Rien d'endossements trouvé"
},
"sponsorStart": {
"message": "Endossement Commence Maintenant"
},
"sponsorEnd": {
"message": "Endossement Arête Maintenant"
},
"noVideoID": {
"message": "Ceci n'est pas une tab de YouTube, ou vous avez cliqué trop tôt. \n Si vous savez que ceci est une tab YouTube, ferme ce menu et essayé encore."
},
"success": {
"message": "Succès!"
},
"voted": {
"message": "Voté!"
},
"voteFail": {
"message": "Vous avez déjà voté la même façon."
},
"serverDown": {
"message": "Le serveur ne fonctionne pas. Message le développeur."
},
"connectionError": {
"message": "Erreur. Code: "
},
"wantToSubmit": {
"message": "Voulez-vous soumettre les endossements sur le vidéo"
},
"leftTimes": {
"message": "Vous avez laissé les endossements qui n'étaient pas soumis. Retournez à la page pour les soumettre (Ils ne sont pas enlevés)."
},
"submitCheck": {
"message": "Êtes-vous certaines vous voulez soumettre?"
}
}

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

@@ -5,17 +5,18 @@ chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
});
chrome.runtime.onMessage.addListener(function (request, sender, callback) {
if (request.message == "submitTimes") {
switch(request.message) {
case "submitTimes":
submitTimes(request.videoID, callback);
//this allows the callback to be called later by the submitTimes function
return true;
} else if (request.message == "addSponsorTime") {
case "addSponsorTime":
addSponsorTime(request.time, request.videoID, callback);
//this allows the callback to be called later
return true;
} else if (request.message == "getSponsorTimes") {
case "getSponsorTimes":
getSponsorTimes(request.videoID, function(sponsorTimes) {
callback({
sponsorTimes: sponsorTimes
@@ -24,16 +25,16 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
//this allows the callback to be called later
return true;
} else if (request.message == "submitVote") {
case "submitVote":
submitVote(request.type, request.UUID, callback);
//this allows the callback to be called later
return true;
} else if (request.message == "alertPrevious") {
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).",
title: chrome.i18n.getMessage("wantToSubmit") + request.previousVideoID + "?",
message: chrome.i18n.getMessage("leftTimes"),
iconUrl: "./icons/LogoSponsorBlocker256px.png"
});
}
@@ -55,7 +56,7 @@ chrome.runtime.onInstalled.addListener(function (object) {
// TODO (shownInstallPage): remove this if statement, but leave contents
if (!shownInstallPage){
//open up the install page
chrome.tabs.create({url: chrome.extension.getURL("/help/index.html")});
chrome.tabs.create({url: chrome.extension.getURL("/help/"+chrome.i18n.getMessage("helpPage"))});
}
// TODO (shownInstallPage): delete if statement and contents
@@ -65,13 +66,10 @@ chrome.runtime.onInstalled.addListener(function (object) {
}
//generate a userID
const newUserID = generateUUID();
const newUserID = generateUserID();
//save this UUID
chrome.storage.sync.set({
"userID": newUserID,
//the last video id loaded, to make sure it is a video id change
"sponsorVideoID": null,
"previousVideoID": null
"userID": newUserID
});
}
});
@@ -115,6 +113,14 @@ function submitVote(type, UUID, callback) {
chrome.storage.sync.get(["userID"], function(result) {
let userID = result.userID;
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) {
@@ -199,10 +205,9 @@ function sendRequestToServer(type, address, callback) {
xmlhttp.send();
}
function generateUUID(length = 36) {
function generateUserID(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);

View File

@@ -41,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 {
@@ -58,33 +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: 300px;
background-color: rgba(28, 28, 28, 0.9);
position: absolute;
border: 3px solid rgba(0, 0, 0, 0.8);
right: 0;
bottom: 90px;
zoom: 85%;
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 {
bottom: 280px;
bottom: 250px;
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 {
@@ -111,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 {

View File

@@ -10,12 +10,17 @@ var sponsorVideoID = null;
//these are sponsors that have been downvoted
var hiddenSponsorTimes = [];
//the time this video is starting at when first played, if not zero
var youtubeVideoStartTime = null;
//the video
var v;
var listenerAdded;
//the video id of the last preview bar update
var lastPreviewBarUpdate;
//whether the duration listener listening for the duration changes of the video has been setup yet
var durationListenerSetUp = false;
//the channel this video is about
var channelURL;
@@ -23,19 +28,15 @@ var channelURL;
var channelWhitelisted = false;
// create preview bar
let progressBar = document.getElementsByClassName("ytp-progress-bar-container")[0] || document.getElementsByClassName("no-model cue-range-markers")[0];
var previewBar = new PreviewBar(progressBar);
var previewBar;
if(id = getYouTubeVideoID(document.URL)){ // Direct Links
if (id = getYouTubeVideoID(document.URL)) { // Direct Links
videoIDChange(id);
}
//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 amount of times the sponsor lookup has retried
//this only happens if there is an error
var sponsorLookupRetries = 0;
@@ -54,10 +55,6 @@ var hideVideoPlayerControls = false;
var hideInfoButtonPlayerControls = false;
var hideDeleteButtonPlayerControls = false;
//the downloaded sponsor times
var sponsorTimes = [];
var UUIDs = [];
//the sponsor times being prepared to be submitted
var sponsorTimesSubmitting = [];
@@ -93,7 +90,11 @@ function messageListener(request, sender, sendResponse) {
//messages from popup script
if (request.message == "update") {
if(id = getYouTubeVideoID(document.URL)) videoIDChange(id);
if(id = getYouTubeVideoID(document.URL)){
videoIDChange(id);
} else {
resetValues();
}
}
if (request.message == "sponsorStart") {
@@ -200,11 +201,33 @@ document.onkeydown = function(e){
}
}
function videoIDChange(id) {
function resetValues() {
//reset last sponsor times
lastTime = -1;
//reset sponsor times
sponsorTimes = null;
UUIDs = null;
sponsorVideoID = id;
sponsorLookupRetries = 0;
//empty the preview bar
previewBar.set([], [], 0);
//reset sponsor data found check
sponsorDataFound = false;
}
function videoIDChange(id) {
//not a url change
if (sponsorVideoID == id) return;
if (previewBar == null) {
//create it
let progressBar = document.getElementsByClassName("ytp-progress-bar-container")[0] || document.getElementsByClassName("no-model cue-range-markers")[0];
previewBar = new PreviewBar(progressBar);
}
//warn them if they had unsubmitted times
if (previousVideoID != null) {
//get the sponsor times from storage
@@ -231,21 +254,8 @@ function videoIDChange(id) {
//close popup
closeInfoMenu();
//reset last sponsor times
lastTime = -1;
lastUnixTimeSkipped = -1;
resetValues();
//reset sponsor times
sponsorTimes = null;
UUIDs = null;
sponsorVideoID = id;
sponsorLookupRetries = 0;
//see if there is a video start time
youtubeVideoStartTime = getYouTubeVideoStartTime(document.URL);
//reset sponsor data found check
sponsorDataFound = false;
sponsorsLookup(id);
//make sure everything is properly added
@@ -272,6 +282,8 @@ function videoIDChange(id) {
//see if this data should be saved in the sponsorTimesSubmitting variable
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
sponsorTimesSubmitting = sponsorTimes;
updatePreviewBar();
}
}
});
@@ -303,13 +315,19 @@ function videoIDChange(id) {
function sponsorsLookup(id) {
v = document.querySelector('video') // Youtube video player
//there is no video here
if (v == null) {
setTimeout(() => sponsorsLookup(id), 100);
return;
}
if (!durationListenerSetUp) {
durationListenerSetUp = true;
//wait until it is loaded
v.addEventListener('durationchange', updatePreviewBar);
}
//check database for sponsor times
sendRequestToServer('GET', "/api/getVideoSponsorTimes?videoID=" + id, function(xmlhttp) {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
@@ -320,7 +338,11 @@ function sponsorsLookup(id) {
//update the preview bar
//leave the type blank for now until categories are added
previewBar.set(sponsorTimes, [], v.duration);
if (lastPreviewBarUpdate == id || (lastPreviewBarUpdate == null && !isNaN(v.duration))) {
//set it now
//otherwise the listener can handle it
updatePreviewBar();
}
getChannelID();
@@ -342,7 +364,7 @@ function sponsorsLookup(id) {
});
sponsorLookupRetries = 0;
} else if (xmlhttp.readyState == 4 && sponsorLookupRetries < 15) {
} else if (xmlhttp.readyState == 4 && sponsorLookupRetries < 90) {
//some error occurred, try again in a second
setTimeout(() => sponsorsLookup(id), 1000);
@@ -356,6 +378,27 @@ function sponsorsLookup(id) {
};
}
function updatePreviewBar() {
let localSponsorTimes = sponsorTimes;
if (localSponsorTimes == null) localSponsorTimes = [];
let allSponsorTimes = localSponsorTimes.concat(sponsorTimesSubmitting);
//create an array of the sponsor types
let types = [];
for (let i = 0; i < localSponsorTimes.length; i++) {
types.push("sponsor");
}
for (let i = 0; i < sponsorTimesSubmitting.length; i++) {
types.push("previewSponsor");
}
previewBar.set(allSponsorTimes, types, v.duration);
//update last video id
lastPreviewBarUpdate = getYouTubeVideoID(document.URL);
}
function getChannelID() {
//get channel id
let channelContainers = document.querySelectorAll("#owner-name");
@@ -435,7 +478,7 @@ function checkSponsorTime(sponsorTimes, index, openNotice) {
lastTime = v.currentTime - 0.0001;
}
if (checkIfTimeToSkip(v.currentTime, sponsorTimes[index][0]) && !hiddenSponsorTimes.includes(index)) {
if (checkIfTimeToSkip(v.currentTime, sponsorTimes[index][0], sponsorTimes[index][1]) && !hiddenSponsorTimes.includes(index)) {
//skip it
skipToTime(v, index, sponsorTimes, openNotice);
@@ -446,15 +489,13 @@ function checkSponsorTime(sponsorTimes, index, openNotice) {
return false;
}
function checkIfTimeToSkip(currentVideoTime, startTime) {
let currentTime = Date.now();
function checkIfTimeToSkip(currentVideoTime, startTime, endTime) {
//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 only if the video is not setup to start at a different time from zero
return (Math.abs(currentVideoTime - startTime) < 0.3 && startTime >= lastTime && startTime <= currentVideoTime &&
(lastUnixTimeSkipped == -1 || currentTime - lastUnixTimeSkipped > 500)) || (lastTime == -1 && startTime == 0 && youtubeVideoStartTime == null)
return (Math.abs(currentVideoTime - startTime) < 3 && startTime >= lastTime && startTime <= currentVideoTime) ||
(lastTime == -1 && startTime == 0 && currentVideoTime < endTime)
}
//skip fromt he start time to the end time for a certain index sponsor time
@@ -468,23 +509,33 @@ function skipToTime(v, index, sponsorTimes, openNotice) {
if (openNotice) {
//send out the message saying that a sponsor message was skipped
openSkipNotice(currentUUID);
if (!dontShowNotice) {
new SkipNotice(this, currentUUID);
setTimeout(() => closeSkipNotice(currentUUID), 7000);
//auto-upvote this sponsor
if (trackViewCount) {
vote(1, currentUUID, null);
}
}
}
//send telemetry that a this sponsor was skipped happened
if (trackViewCount) {
sendRequestToServer("GET", "/api/viewedVideoSponsorTime?UUID=" + currentUUID);
}
}
}
function goBackToPreviousTime(UUID) {
function unskipSponsorTime(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);
function reskipSponsorTime(UUID) {
if (sponsorTimes != null) {
//add a tiny bit of time to make sure it is not skipped again
v.currentTime = sponsorTimes[UUIDs.indexOf(UUID)][1];
}
}
@@ -497,12 +548,14 @@ function addPlayerControlsButton() {
let startSponsorButton = document.createElement("button");
startSponsorButton.id = "startSponsorButton";
startSponsorButton.draggable = false;
startSponsorButton.className = "ytp-button playerButton";
startSponsorButton.setAttribute("title", "Sponsor Starts Now");
startSponsorButton.setAttribute("title", chrome.i18n.getMessage("sponsorStart"));
startSponsorButton.addEventListener("click", startSponsorClicked);
let startSponsorImage = document.createElement("img");
startSponsorImage.id = "startSponsorImage";
startSponsorImage.draggable = false;
startSponsorImage.className = "playerButtonImage";
startSponsorImage.src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png");
@@ -574,6 +627,8 @@ function updateSponsorTimesSubmitting() {
//see if this data should be saved in the sponsorTimesSubmitting variable
if (sponsorTimes != undefined) {
sponsorTimesSubmitting = sponsorTimes;
updatePreviewBar();
}
}
});
@@ -590,7 +645,7 @@ 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");
document.getElementById("startSponsorButton").setAttribute("title", chrome.i18n.getMessage("sponsorStart"));
if (document.getElementById("startSponsorImage").style.display != "none" && uploadButtonVisible && !hideInfoButtonPlayerControls) {
document.getElementById("submitButton").style.display = "unset";
@@ -601,7 +656,7 @@ function changeStartSponsorButton(showStartSponsor, uploadButtonVisible) {
} else {
showingStartSponsor = false;
document.getElementById("startSponsorImage").src = chrome.extension.getURL("icons/PlayerStopIconSponsorBlocker256px.png");
document.getElementById("startSponsorButton").setAttribute("title", "Sponsor Ends Now");
document.getElementById("startSponsorButton").setAttribute("title", chrome.i18n.getMessage("sponsorEND"));
//disable submit button
document.getElementById("submitButton").style.display = "none";
@@ -622,12 +677,14 @@ function addInfoButton() {
//make a submit button
let infoButton = document.createElement("button");
infoButton.id = "infoButton";
infoButton.draggable = false;
infoButton.className = "ytp-button playerButton";
infoButton.setAttribute("title", "Open SponsorBlock Popup");
infoButton.addEventListener("click", openInfoMenu);
let infoImage = document.createElement("img");
infoImage.id = "infoButtonImage";
infoImage.draggable = false;
infoImage.className = "playerButtonImage";
infoImage.src = chrome.extension.getURL("icons/PlayerInfoIconSponsorBlocker256px.png");
@@ -656,6 +713,7 @@ function addDeleteButton() {
//make a submit button
let deleteButton = document.createElement("button");
deleteButton.id = "deleteButton";
deleteButton.draggable = false;
deleteButton.className = "ytp-button playerButton";
deleteButton.setAttribute("title", "Clear Sponsor Times");
deleteButton.addEventListener("click", clearSponsorTimes);
@@ -664,6 +722,7 @@ function addDeleteButton() {
let deleteImage = document.createElement("img");
deleteImage.id = "deleteButtonImage";
deleteImage.draggable = false;
deleteImage.className = "playerButtonImage";
deleteImage.src = chrome.extension.getURL("icons/PlayerDeleteIconSponsorBlocker256px.png");
@@ -692,6 +751,7 @@ function addSubmitButton() {
//make a submit button
let submitButton = document.createElement("button");
submitButton.id = "submitButton";
submitButton.draggable = false;
submitButton.className = "ytp-button playerButton";
submitButton.setAttribute("title", "Submit Sponsor Times");
submitButton.addEventListener("click", submitSponsorTimes);
@@ -700,6 +760,7 @@ function addSubmitButton() {
let submitImage = document.createElement("img");
submitImage.id = "submitButtonImage";
submitImage.draggable = false;
submitImage.className = "playerButtonImage";
submitImage.src = chrome.extension.getURL("icons/PlayerUploadIconSponsorBlocker256px.png");
@@ -789,8 +850,8 @@ function clearSponsorTimes() {
let sponsorTimes = result[sponsorTimeKey];
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
let confirmMessage = "Are you sure you want to clear this?\n\n" + getSponsorTimesMessage(sponsorTimes);
confirmMessage += "\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."
let confirmMessage = chrome.i18n.getMessage("clearThis") + getSponsorTimesMessage(sponsorTimes);
confirmMessage += chrome.i18n.getMessage("confirmMSG")
if(!confirm(confirmMessage)) return;
//clear the sponsor times
@@ -800,205 +861,21 @@ function clearSponsorTimes() {
//clear sponsor times submitting
sponsorTimesSubmitting = [];
updatePreviewBar();
//set buttons to be correct
changeStartSponsorButton(true, false);
}
});
}
//Opens the notice that tells the user that a sponsor was just skipped
function openSkipNotice(UUID){
if (dontShowNotice) {
//don't show, return
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 = 50 + 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("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);
}
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);
//remove this sponsor from the sponsors looked up
//find which one it is
for (let i = 0; i < sponsorTimes.length; i++) {
if (UUIDs[i] == 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);
}
}
}
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) {
//if skipNotice is null, it will not affect the UI
function vote(type, UUID, skipNotice) {
if (skipNotice != null) {
//add loading info
addLoadingInfo("Loading...", UUID)
skipNotice.addVoteButtonInfo.bind(skipNotice)("Loading...")
skipNotice.resetNoticeInfoMessage.bind(skipNotice)();
}
chrome.runtime.sendMessage({
message: "submitVote",
@@ -1007,37 +884,31 @@ function vote(type, UUID) {
}, function(response) {
if (response != undefined) {
//see if it was a success or failure
if (skipNotice != null) {
if (response.successType == 1) {
//success
if (type == 0) {
afterDownvote(UUID);
} else if (type == 1) {
closeSkipNotice(UUID);
skipNotice.afterDownvote.bind(skipNotice)();
}
} else if (response.successType == 0) {
//failure: duplicate vote
addLoadingInfo("It seems you've already voted before", UUID)
skipNotice.addNoticeInfoMessage.bind(skipNotice)(chrome.i18n.getMessage("voteFail"))
skipNotice.resetVoteButtonInfo.bind(skipNotice)();
} else if (response.successType == -1) {
if (response.statusCode == 502) {
addLoadingInfo("It seems the sever is down. Contact the dev immediately.", UUID)
skipNotice.addNoticeInfoMessage.bind(skipNotice)(chrome.i18n.getMessage("serverDown"))
skipNotice.resetVoteButtonInfo.bind(skipNotice)();
} else {
//failure: unknown error
addLoadingInfo("A connection error has occured. Error code: " + response.statusCode, UUID)
skipNotice.addNoticeInfoMessage.bind(skipNotice)(chrome.i18n.getMessage("connectionError") + response.statusCode);
skipNotice.resetVoteButtonInfo.bind(skipNotice)();
}
}
}
}
});
}
//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");
@@ -1082,8 +953,8 @@ function submitSponsorTimes() {
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 edit or delete values, click the info button or open the extension popup by clicking the extension icon in the top right corner."
let confirmMessage = chrome.i18n.getMessage("submitCheck") + "\n\n" + getSponsorTimesMessage(sponsorTimes);
confirmMessage += "\n\n" + chrome.i18n.getMessage("confirmMSG");
if(!confirm(confirmMessage)) return;
sendSubmitMessage();
@@ -1129,21 +1000,14 @@ function sendSubmitMessage(){
//request the sponsors from the server again
sponsorsLookup(currentVideoID);
} 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");
if(response.statusCode == 400) {
alert("Server said this request was invalid");
} else if(response.statusCode == 429) {
alert("You have submitted too many sponsor times for this one video, are you sure there are this many?");
} else if(response.statusCode == 409) {
alert("This has already been submitted before");
} else if(response.statusCode == 502) {
alert("It seems the server is down. Contact the dev to inform them. Error code " + response.statusCode);
if([400,429,409,502].includes(response.statusCode)) {
alert(chrome.i18n.getMessage(response.statusCode));
} else {
alert("There was an error submitting your sponsor times, please try again later. Error code " + response.statusCode);
alert(chrome.i18n.getMessage("connectionError") + response.statusCode);
}
}
}

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

@@ -38,10 +38,11 @@
<br/>
<br/>
Whenever you skip a video, you will get a notice allowing you to vote on that submission. If it worked, upvote it! You can also vote in the popup.
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.
</p>
<center><img height="120px" src="https://i.imgur.com/1M0WZ99.gif"></center>
<center><img height="120px" src="https://user-images.githubusercontent.com/12688112/63067735-5a638700-bede-11e9-8147-f321b57527ec.gif"></center>
<h1>Submitting</h1>

BIN
icons/close.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
icons/report.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -1,8 +1,9 @@
{
"name": "SponsorBlock for YouTube - Skip Sponsorships",
"short_name": "SponsorBlock",
"version": "1.0.34",
"description": "Skip over sponsorship on YouTube videos. Report sponsors on videos you watch to save the time of others.",
"name": "__MSG_fullName__",
"short_name": "__MSG_Name__",
"version": "1.1.3",
"default_locale": "en",
"description": "__MSG_Description__",
"content_scripts": [
{
"matches": [
@@ -12,6 +13,7 @@
"js": [
"config.js",
"utils/previewBar.js",
"utils/skipNotice.js",
"utils.js",
"content.js",
"popup.js"
@@ -32,6 +34,8 @@
"icons/PlayerUploadFailedIconSponsorBlocker256px.png",
"icons/upvote.png",
"icons/downvote.png",
"icons/report.png",
"icons/close.png",
"icons/PlayerInfoIconSponsorBlocker256px.png",
"icons/PlayerDeleteIconSponsorBlocker256px.png",
"popup.html"
@@ -42,7 +46,7 @@
"https://sponsor.ajay.app/*"
],
"browser_action": {
"default_title": "SponsorBlock",
"default_title": "__MSG_Name__",
"default_popup": "popup.html"
},
"background": {

View File

@@ -51,6 +51,10 @@ h1.popupElement {
padding: 5px;
}
.discreteLink.popupElement {
color: black;
}
.recordingSubtitle.popupElement {
margin-bottom: 10px;
}
@@ -106,17 +110,17 @@ h1.popupElement {
text-decoration:none;
text-shadow:0px 0px 0px #27663c;
}
.whitelistButton:hover.popupElement {
.whitelistButton:hover.popupElement {
background-color:#218b26;
}
.whitelistButton:focus.popupElement {
}
.whitelistButton:focus.popupElement {
outline: none;
background-color:#218b26;
}
.whitelistButton:active.popupElement {
}
.whitelistButton:active.popupElement {
position:relative;
top:1px;
}
}
.greenButton.popupElement {
background-color:#ec1c1c;

View File

@@ -1,6 +1,6 @@
<html>
<head>
<title>Set Page Color Popup</title>
<title>SponsorBlock Popup</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>
@@ -73,6 +73,10 @@
sponsor segments.
</span>
</span>
<div class="popupElement">
View the leaderboard <a class="popupElement discreteLink" href="https://sponsor.ajay.app/stats" target="_blank">here</a>.
</div>
</p>
<p class="popupElement">
@@ -119,6 +123,10 @@
<br/>
<button id="setUsernameButton" class="warningButton popupElement">Set Username</button>
<br/>
<sub class="popupElement">
This is used on the public stats page to show off how much you've contributed. See it <a class="popupElement discreteLink" href="https://sponsor.ajay.app/stats" target="_blank">here</a>.
</sub>
</div>
<div id="setUsername" class="popupElement" style="display: none">

View File

@@ -92,15 +92,6 @@ function runThePopup() {
SB.reportAnIssue.addEventListener("click", reportAnIssue);
SB.hideDiscordButton.addEventListener("click", hideDiscordButton);
//setup error message languages
var EN_US = new Map();
EN_US.set(400, 'Server said this request was invalid"')
.set(429, 'You have submitted too many sponsor times for this one video, are you sure there are this many?')
.set(409, 'This has already been submitted before')
.set(502, 'It seems the server is down. Contact the dev to inform them.')
.set('Unknown', 'There was an error submitting your sponsor times, please try again later.');
//if true, the button now selects the end time
let startTimeChosen = false;
@@ -178,9 +169,9 @@ function runThePopup() {
chrome.storage.sync.get(["sponsorTimesContributed"], function(result) {
if (result.sponsorTimesContributed != undefined) {
if (result.sponsorTimesContributed > 1) {
SB.sponsorTimesContributionsDisplayEndWord.innerText = "sponsors."
SB.sponsorTimesContributionsDisplayEndWord.innerText = chrome.i18n.getMessage("Sponsors");
} else {
SB.sponsorTimesContributionsDisplayEndWord.innerText = "sponsor."
SB.sponsorTimesContributionsDisplayEndWord.innerText = chrome.i18n.getMessage("Sponsor");
}
SB.sponsorTimesContributionsDisplay.innerText = result.sponsorTimesContributed;
SB.sponsorTimesContributionsContainer.style.display = "unset";
@@ -196,9 +187,9 @@ function runThePopup() {
let viewCount = JSON.parse(xmlhttp.responseText).viewCount;
if (viewCount != 0) {
if (viewCount > 1) {
SB.sponsorTimesViewsDisplayEndWord.innerText = "sponsor segments."
SB.sponsorTimesViewsDisplayEndWord.innerText = chrome.i18n.getMessage("Segments");
} else {
SB.sponsorTimesViewsDisplayEndWord.innerText = "sponsor segment."
SB.sponsorTimesViewsDisplayEndWord.innerText = chrome.i18n.getMessage("Segment");
}
SB.sponsorTimesViewsDisplay.innerText = viewCount;
@@ -220,7 +211,6 @@ function runThePopup() {
chrome.tabs.sendMessage(tabs[0].id, {message: 'getVideoID'}, function(result) {
if (result != undefined && result.videoID) {
currentVideoID = result.videoID;
loadTabData(tabs);
} else if (result == undefined && chrome.runtime.lastError) {
//this isn't a YouTube video then, or at least the content script is not loaded
@@ -243,7 +233,7 @@ function runThePopup() {
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";
SB.sponsorStart.innerHTML = chrome.i18n.getMessage("sponsorEnd");
}
sponsorTimes = sponsorTimesStorage;
@@ -283,11 +273,11 @@ function runThePopup() {
SB.loadingIndicator.innerHTML = "";
if (request.found) {
SB.videoFound.innerHTML = "This video's sponsors are in the database!"
SB.videoFound.innerHTML = chrome.i18n.getMessage("sponsorFound");
displayDownloadedSponsorTimes(request);
} else {
SB.videoFound.innerHTML = "No sponsors found"
SB.videoFound.innerHTML = chrome.i18n.getMessage("sponsor404");
}
}
@@ -385,7 +375,7 @@ function runThePopup() {
function displayDownloadedSponsorTimes(request) {
if (request.sponsorTimes != undefined) {
//set it to the message
if (SB.downloadedSponsorMessageTimes.innerText != "Channel Whitelisted!") {
if (SB.downloadedSponsorMessageTimes.innerText != chrome.i18n.getMessage("channelWhitelisted")) {
SB.downloadedSponsorMessageTimes.innerText = getSponsorTimesMessage(request.sponsorTimes);
}
@@ -654,8 +644,8 @@ function runThePopup() {
tabs[0].id,
{message: "getCurrentTime"},
function (response) {
let minutes = document.getElementById(idStartName + "Minutes" + index);
let seconds = document.getElementById(idStartName + "Seconds" + index);
let minutes = document.getElementById(idStartName + chrome.i18n.getMessage("Mins") + index);
let seconds = document.getElementById(idStartName + chrome.i18n.getMessage("Secs") + index);
minutes.value = getTimeInMinutes(response.currentTime);
seconds.value = getTimeInFormattedSeconds(response.currentTime);
@@ -666,8 +656,8 @@ function runThePopup() {
//id start name is whether it is the startTime or endTime
//gives back the time in seconds
function getSponsorTimeEditTimes(idStartName, index) {
let minutes = document.getElementById(idStartName + "Minutes" + index);
let seconds = document.getElementById(idStartName + "Seconds" + index);
let minutes = document.getElementById(idStartName + chrome.i18n.getMessage("Mins") + index);
let seconds = document.getElementById(idStartName + chrome.i18n.getMessage("Secs") + index);
return parseInt(minutes.value) * 60 + parseFloat(seconds.value);
}
@@ -792,14 +782,9 @@ function runThePopup() {
resetStartTimeChosen();
}
function getErrorMessage(lang, statusCode) {
if(lang.has(statusCode)) return lang.get(statusCode);
return lang.get('Unknown').concat(" Error code: ") + statusCode;
}
function submitTimes() {
//make info message say loading
SB.submitTimesInfoMessage.innerText = "Loading...";
SB.submitTimesInfoMessage.innerText = chrome.i18n.getMessage("Loading");
SB.submitTimesInfoMessageContainer.style.display = "unset";
if (sponsorTimes.length > 0) {
@@ -814,7 +799,13 @@ function runThePopup() {
clearTimes();
} else {
let errorMessage = getErrorMessage(EN_US, response.statusCode);
let errorMessage = "";
if([400,429,409,502].includes(response.statusCode)) {
errorMessage = chrome.i18n.getMessage(response.statusCode);
} else {
errorMessage = chrome.i18n.getMessage("connectionError") + response.statusCode;
}
document.getElementById("submitTimesInfoMessage").innerText = errorMessage;
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
@@ -981,7 +972,7 @@ function runThePopup() {
//update startTimeChosen letiable
if (!startTimeChosen) {
startTimeChosen = true;
SB.sponsorStart.innerHTML = "Sponsorship Ends Now";
SB.sponsorStart.innerHTML = chrome.i18n.getMessage("sponsorEnd");
} else {
resetStartTimeChosen();
}
@@ -990,7 +981,7 @@ function runThePopup() {
//set it to false
function resetStartTimeChosen() {
startTimeChosen = false;
SB.sponsorStart.innerHTML = "Sponsorship Starts Now";
SB.sponsorStart.innerHTML = "SP_START";
}
//hides and shows the submit times button when needed
@@ -1025,11 +1016,14 @@ function runThePopup() {
SB.setUsernameContainer.style.display = "none";
SB.setUsername.style.display = "unset";
} else {
SB.setUsernameStatusContainer.style.display = "none";
} else if (xmlhttp.readyState == 4) {
SB.setUsername.style.display = "unset";
SB.submitUsername.style.display = "none";
SB.usernameInput.style.display = "none";
SB.setUsernameStatusContainer.style.display = "unset";
SB.setUsernameStatus.innerText = "Couldn't connect to server. Error code: " + xmlhttp.status;
}
});
@@ -1050,11 +1044,17 @@ function runThePopup() {
SB.submitUsername.style.display = "none";
SB.usernameInput.style.display = "none";
SB.setUsernameStatus.innerText = "Success!";
} else if (xmlhttp.readyState == 4 && xmlhttp.status == 400) {
SB.setUsernameStatus.innerText = "Bad Request";
SB.setUsernameStatus.innerText = chrome.i18n.getMessage("success");
} else if (xmlhttp.readyState == 4) {
let errorMessage = "";
if([400, 429, 409, 502].includes(xmlhttp.status)) {
errorMessage = chrome.i18n.getMessage(xmlhttp.status);
} else {
SB.setUsernameStatus.innerText = getErrorMessage(EN_US, xmlhttp.status);
errorMessage = chrome.i18n.getMessage("connectionError") + xmlhttp.status;
}
SB.setUsernameStatus.innerText = errorMessage;
}
});
});
@@ -1066,8 +1066,7 @@ function runThePopup() {
//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.";
document.getElementById("loadingIndicator").innerText = chrome.i18n.getMessage("noVideoID");
}
function reportAnIssue() {
@@ -1104,16 +1103,16 @@ function runThePopup() {
//see if it was a success or failure
if (response.successType == 1) {
//success
addVoteMessage("Thanks for voting!", UUID)
addVoteMessage(chrome.i18n.getMessage("voted"), UUID)
} else if (response.successType == 0) {
//failure: duplicate vote
addVoteMessage("You have already voted this way before.", UUID)
addVoteMessage(chrome.i18n.getMessage("voteFail"), UUID)
} else if (response.successType == -1) {
if (response.statusCode == 502) {
addVoteMessage("It seems the sever is down. Contact the dev immediately.", UUID)
addVoteMessage(chrome.i18n.getMessage("serverDown"), UUID)
} else {
//failure: unknown error
addVoteMessage("A connection error has occured. Error code: " + response.statusCode, UUID)
addVoteMessage(chrome.i18n.getMessage("connectionError") + response.statusCode, UUID)
}
}
}

View File

@@ -1,3 +1,17 @@
// 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);
const interval = setInterval(() => {
let result = condition();
if (result !== false) {
resolve(result);
clearInterval(interval);
};
}, check);
});
}
function getYouTubeVideoID(url) {
//Attempt to parse url
let urlObject = null;
@@ -5,7 +19,7 @@ function getYouTubeVideoID(url) {
urlObject = new URL(url);
} catch (e) {
console.error("[SB] Unable to parse URL: " + url);
return false
return false;
}
//Check if valid hostname
@@ -24,14 +38,3 @@ function getYouTubeVideoID(url) {
}
}
}
//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);
}
}