Compare commits

...

63 Commits
2.0 ... 2.0.4

Author SHA1 Message Date
Ajay Ramachandran
e9e53d1d43 Merge pull request #401 from ajayyy/react
Improvements
2020-07-12 23:09:43 -04:00
Ajay Ramachandran
07ab99a8d0 New Crowdin updates (#400)
* New translations messages.json (Romanian)

* New translations messages.json (German)

* New translations messages.json (Portuguese)

* New translations messages.json (Polish)

* New translations messages.json (Italian)

* New translations messages.json (French)

* New translations messages.json (Finnish)

* New translations messages.json (Spanish)

* New translations messages.json (Russian)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Ukrainian)

* New translations messages.json (Turkish)

* New translations messages.json (Swedish)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (German)
2020-07-12 23:08:04 -04:00
Ajay Ramachandran
896120d311 Update version number 2020-07-12 23:07:55 -04:00
Ajay Ramachandran
3dc6563048 Default to blank category when submitting 2020-07-12 20:59:35 -04:00
Ajay Ramachandran
2d74ce2093 Added hours to time with skips 2020-07-12 18:52:36 -04:00
Ajay Ramachandran
eac4ca4d71 Add edge 2020-07-08 21:43:26 -04:00
Ajay Ramachandran
399a5af990 Update README.md 2020-07-07 17:48:36 -04:00
Ajay Ramachandran
48861439b7 Don't run time without skips on mobile or invidious 2020-07-05 00:21:26 -04:00
Ajay Ramachandran
bd60875c66 Fix invidious css issues 2020-07-05 00:17:54 -04:00
Ajay Ramachandran
fe8f25fe23 Hide submit button on invidious 2020-07-05 00:11:29 -04:00
Ajay Ramachandran
87f3cf3881 Fixed invidious preview bar 2020-07-05 00:09:18 -04:00
Ajay Ramachandran
0b9df8a45c Remove submitting on mobile 2020-07-05 00:07:10 -04:00
Ajay Ramachandran
59c5b7eefe Remove unused function 2020-07-05 00:05:36 -04:00
Ajay Ramachandran
dea9dac20a Fix crashing on mobile youtube 2020-07-05 00:03:52 -04:00
Ajay Ramachandran
684cd676e5 Delete empty unsubmitted submissions when delete is called 2020-07-04 15:34:29 -04:00
Ajay Ramachandran
929e3396cd New Crowdin updates (#386)
* New translations messages.json (Romanian)

* New translations messages.json (German)

* New translations messages.json (Turkish)

* New translations messages.json (Ukrainian)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Slovak)

* New translations messages.json (Russian)

* New translations messages.json (French)

* New translations messages.json (Dutch)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Finnish)

* New translations messages.json (Hungarian)

* New translations messages.json (Swedish)

* New translations messages.json (Bulgarian)

* New translations messages.json (Spanish)

* New translations messages.json (Gujarati)

* New translations messages.json (Polish)

* New translations messages.json (German)

* New translations messages.json (French)

* New translations messages.json (German)

* New translations messages.json (Swedish)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (German)

* New translations messages.json (Russian)

* New translations messages.json (Chinese Simplified)
2020-07-03 21:25:13 -04:00
Ajay Ramachandran
fad3284c4f Merge pull request #399 from ajayyy/react
Save category in preview submissions and other fixes
2020-07-03 21:20:53 -04:00
Ajay Ramachandran
c69047c7f9 Show short names when hovering the preview bar 2020-07-03 21:16:38 -04:00
Ajay Ramachandran
4fc7a69dd5 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into react 2020-07-03 20:58:15 -04:00
Ajay Ramachandran
dd4c903c6a Merge pull request #395 from NDevTK/patch-1
Added config option for excluding skipped content from the video duration
2020-07-03 20:58:01 -04:00
Ajay Ramachandran
c9a2edaf3d Remove unused function 2020-07-03 20:56:45 -04:00
Ajay Ramachandran
8d41af073d Added option to options page 2020-07-03 20:55:58 -04:00
Ajay Ramachandran
bfafcd07cc Fix font issue, NaN issue and remove hide real time 2020-07-03 19:56:08 -04:00
Ajay Ramachandran
77abc1d031 Reuse existing functions 2020-07-03 19:44:15 -04:00
Ajay Ramachandran
809de0e0fd Increased version number 2020-07-03 19:31:18 -04:00
Ajay Ramachandran
e55d1f5115 Removed intermission category and renamed intro to intermission. 2020-07-03 19:31:00 -04:00
Ajay Ramachandran
037bd511b0 Remove keybind restriction.
Closes https://github.com/ajayyy/SponsorBlock/issues/379
2020-07-03 19:07:05 -04:00
Ajay Ramachandran
1265eeb941 Save category with the preview submissions. 2020-07-02 23:34:13 -04:00
Ajay Ramachandran
b3a94142c3 Allow colon on invidious options 2020-07-02 21:39:00 -04:00
Ajay Ramachandran
367657e44e Added intermission category 2020-07-02 21:37:38 -04:00
Ajay Ramachandran
955ee32b46 Remove category update message 2020-07-02 21:13:07 -04:00
Ajay Ramachandran
cd0b1f4a31 Wait for permissions before reloading 2020-07-02 20:56:41 -04:00
Ajay Ramachandran
5c4f0c960c Reload after importing options 2020-07-02 20:50:06 -04:00
Ajay Ramachandran
5ac6dd1a7f Update description 2020-07-02 20:48:39 -04:00
NDevTK
8d53e776b8 Do not show if skipDuration is 0 2020-06-29 19:35:11 +01:00
NDevTK
ec2950786f Skip if skipDuration is 0 2020-06-29 17:52:28 +01:00
Ajay Ramachandran
f33fa2f621 Moved Android to official 2020-06-27 11:38:49 -04:00
NDevTK
fd77748b15 Updated config 2020-06-27 15:20:00 +01:00
NDevTK
3b59389cab Added different ui option 2020-06-27 15:16:36 +01:00
Ajay Ramachandran
e6f53a3ef9 Update README.md 2020-06-27 00:49:55 -04:00
Ajay Ramachandran
b2f1a737f5 Remove port without pre-built release 2020-06-27 00:44:38 -04:00
Ajay Ramachandran
e2c7f4d16f Merge pull request #397 from daniel11420/patch-2
Add more unofficial ports to the Unofficial Ports section in the README
2020-06-27 00:44:00 -04:00
Ajay Ramachandran
4a89dfaac5 Merge pull request #396 from daniel11420/patch-1
Fix typo in README
2020-06-27 00:42:50 -04:00
daniel11420
e47330a79c Add more unofficial ports to the Unofficial Ports section in the README 2020-06-27 06:38:29 +02:00
daniel11420
72fc3620bc Fix typo in README 2020-06-27 06:32:21 +02:00
NDevTK
0ebd7f4f8d Added duration override 2020-06-26 19:33:19 +01:00
NDevTK
beea8181a1 Added config option 2020-06-26 19:19:51 +01:00
Ajay Ramachandran
f0716e8bbb Merge pull request #389 from kittenparry/patch-1
Fix typo in Chrome Users badge
2020-06-22 18:51:02 -04:00
Edvin Boul
783ea5cf5b Fix typo in Chrome Users badge
Chome -> Chrome
2020-06-22 18:29:08 +03:00
Ajay Ramachandran
42a813d325 Merge pull request #388 from ajayyy/react
Another hotfix for name string issue
2020-06-21 15:54:25 -04:00
Ajay Ramachandran
e6dfb5041e Another hotfix for name string issue 2020-06-21 15:53:26 -04:00
Ajay Ramachandran
c857308038 Merge pull request #387 from ajayyy/react
Fixed wrong string removed
2020-06-21 12:55:27 -04:00
Ajay Ramachandran
f73abdbabc Fixed wrong string removed 2020-06-21 12:55:10 -04:00
Ajay Ramachandran
43184e466f Merge pull request #385 from ajayyy/react
Fixed options page issues
2020-06-20 00:20:01 -04:00
Ajay Ramachandran
627c7769b0 New Crowdin updates (#380)
* New translations messages.json (French)

* New translations messages.json (French)

* New translations messages.json (French)

* New translations messages.json (French)
2020-06-19 18:54:17 -04:00
Ajay Ramachandran
759dba9cd3 Increased version number 2020-06-19 18:53:39 -04:00
Ajay Ramachandran
7cac2c4045 Fix help page not hiding options title bar 2020-06-19 18:53:24 -04:00
Ajay Ramachandran
27bb44189f Remove name from localisation 2020-06-19 18:49:49 -04:00
Ajay Ramachandran
4c44f3da25 Merge pull request #378 from ajayyy/react
Fixed missing options from options page
2020-06-16 22:01:55 -04:00
Ajay Ramachandran
e917a3e94a New Crowdin translations (#369)
* New translations messages.json (French)

* New translations messages.json (French)

* New translations messages.json (Dutch)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Finnish)

* New translations messages.json (German)

* New translations messages.json (German)

* New translations messages.json (Hungarian)

* New translations messages.json (Swedish)

* New translations messages.json (Swedish)

* New translations messages.json (Bulgarian)

* New translations messages.json (Finnish)

* New translations messages.json (French)
2020-06-16 22:01:08 -04:00
Ajay Ramachandran
1570bfdd0a Fixed missing options from options page 2020-06-16 22:00:49 -04:00
Ajay Ramachandran
e511de9f88 Update README.md 2020-06-14 20:29:12 -04:00
drlellinger
e694393edc Improve German translation (#371) 2020-06-10 19:53:35 -04:00
34 changed files with 720 additions and 457 deletions

View File

@@ -11,19 +11,23 @@
<b>Download:</b> <b>Download:</b>
<a href="https://chrome.google.com/webstore/detail/mnjggcdmjocbbbhaepdhchncahnbgone">Chrome/Chromium</a> | <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://addons.mozilla.org/addon/sponsorblock/?src=external-github">Firefox</a> |
<a href="https://github.com/ajayyy/SponsorBlock/wiki/Android">Android</a> |
<a href="https://github.com/ajayyy/SponsorBlock/wiki/Edge">Edge</a> |
<a href="https://sponsor.ajay.app">Website</a> | <a href="https://sponsor.ajay.app">Website</a> |
<a href="https://sponsor.ajay.app/stats">Stats</a> <a href="https://sponsor.ajay.app/stats">Stats</a>
</p> </p>
<p align="center"> <p align="center">
<b>Unofficial Ports:</b> <b>Unofficial Ports:</b>
<a href="https://github.com/ajayyy/SponsorBlock/wiki/Unofficial-Ports#mpv-media-player">MPV</a> <a href="https://github.com/ajayyy/SponsorBlock/wiki/Unofficial-Ports#mpv-media-player">MPV</a> |
<a href="https://github.com/ajayyy/SponsorBlock/wiki/Unofficial-Ports#kodi">Kodi</a> |
<a href="https://github.com/ajayyy/SponsorBlock/wiki/Unofficial-Ports#ios">iOS</a>
</p> </p>
<p align="center"> <p align="center">
<a href="https://addons.mozilla.org/addon/sponsorblock/?src=external-github"><img src="https://img.shields.io/amo/users/sponsorblock?label=Firefox%20Users" alt="Badge"></img></a> <a href="https://addons.mozilla.org/addon/sponsorblock/?src=external-github"><img src="https://img.shields.io/amo/users/sponsorblock?label=Firefox%20Users" alt="Badge"></img></a>
<a href="https://chrome.google.com/webstore/detail/mnjggcdmjocbbbhaepdhchncahnbgone"><img src="https://img.shields.io/chrome-web-store/users/mnjggcdmjocbbbhaepdhchncahnbgone?label=Chome%20Users" alt="Badge"></img></a> <a href="https://chrome.google.com/webstore/detail/mnjggcdmjocbbbhaepdhchncahnbgone"><img src="https://img.shields.io/chrome-web-store/users/mnjggcdmjocbbbhaepdhchncahnbgone?label=Chrome%20Users" alt="Badge"></img></a>
<a href="https://sponsor.ajay.app/stats"><img src="https://img.shields.io/badge/dynamic/json?label=Sponsors%20Submitted&query=totalSubmissions&suffix=%20sponsors&url=http%3A%2F%2Fsponsor.ajay.app%2Fapi%2FgetTotalStats&color=darkred" alt="Badge"></img></a> <a href="https://sponsor.ajay.app/stats"><img src="https://img.shields.io/badge/dynamic/json?label=Submissions&query=totalSubmissions&suffix=%20segments&url=http%3A%2F%2Fsponsor.ajay.app%2Fapi%2FgetTotalStats&color=darkred" alt="Badge"></img></a>
<a href="https://sponsor.ajay.app/stats"><img src="https://img.shields.io/badge/dynamic/json?label=Contributing%20Users&query=userCount&url=http%3A%2F%2Fsponsor.ajay.app%2Fapi%2FgetTotalStats&color=darkblue" alt="Badge"></img></a> <a href="https://sponsor.ajay.app/stats"><img src="https://img.shields.io/badge/dynamic/json?label=Contributing%20Users&query=userCount&url=http%3A%2F%2Fsponsor.ajay.app%2Fapi%2FgetTotalStats&color=darkblue" alt="Badge"></img></a>
<a href="https://sponsor.ajay.app/stats"><img src="https://img.shields.io/badge/dynamic/json?label=Time%20Saved%20From%20Skips&query=daysSaved&url=http%3A%2F%2Fsponsor.ajay.app%2Fapi%2FgetDaysSavedFormatted&color=darkgreen&suffix=%20days" alt="Badge"></img></a> <a href="https://sponsor.ajay.app/stats"><img src="https://img.shields.io/badge/dynamic/json?label=Time%20Saved%20From%20Skips&query=daysSaved&url=http%3A%2F%2Fsponsor.ajay.app%2Fapi%2FgetDaysSavedFormatted&color=darkgreen&suffix=%20days" alt="Badge"></img></a>
</p> </p>
@@ -32,7 +36,7 @@
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. SponsorBlock is an extension that will skip over sponsored segments of YouTube videos. SponsorBlock is a crowdsourced browser extension that lets anyone submit the start and end times of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment.
Also support Invidio.us. Also supports Invidio.us.
**Translate:** [![Crowdin](https://badges.crowdin.net/sponsorblock/localized.svg)](https://crowdin.com/project/sponsorblock) **Translate:** [![Crowdin](https://badges.crowdin.net/sponsorblock/localized.svg)](https://crowdin.com/project/sponsorblock)
@@ -46,7 +50,7 @@ The backend server code is available here: https://github.com/ajayyy/SponsorBloc
It is a simple SQLite database that will hold all the timing data. It is a simple SQLite database that will hold all the timing data.
To make sure that this project doesn't die, I have made the database publicly downloadable at https://sponsor.ajay.app/database.db. If you are planning on using the database in another project, please read the [API Docs](https://github.com/ajayyy/SponsorBlock/wiki/API-Docs) page for more information. To make sure that this project doesn't die, I have made the database publicly downloadable at https://sponsor.ajay.app/database.db ([License](https://github.com/ajayyy/SponsorBlock/wiki/Database-and-API-License)). If you are planning on using the database in another project, please read the [API Docs](https://github.com/ajayyy/SponsorBlock/wiki/API-Docs) page for more information.
The dataset and API are now being used in some [ports](https://github.com/ajayyy/SponsorBlock/wiki/Unofficial-Ports) as well as a [neural network](https://github.com/andrewzlee/NeuralBlock). The dataset and API are now being used in some [ports](https://github.com/ajayyy/SponsorBlock/wiki/Unofficial-Ports) as well as a [neural network](https://github.com/andrewzlee/NeuralBlock).

View File

@@ -1,7 +1,7 @@
{ {
"name": "__MSG_fullName__", "name": "__MSG_fullName__",
"short_name": "__MSG_Name__", "short_name": "SponsorBlock",
"version": "2.0", "version": "2.0.4",
"default_locale": "en", "default_locale": "en",
"description": "__MSG_Description__", "description": "__MSG_Description__",
"content_scripts": [{ "content_scripts": [{
@@ -50,7 +50,7 @@
"*://*/*" "*://*/*"
], ],
"browser_action": { "browser_action": {
"default_title": "__MSG_Name__", "default_title": "SponsorBlock",
"default_popup": "popup.html" "default_popup": "popup.html"
}, },
"background": { "background": {

View File

@@ -1,8 +1,4 @@
{ {
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": { "fullName": {
"message": "SponsorBlock за YouTube - пропускай спонсорства", "message": "SponsorBlock за YouTube - пропускай спонсорства",
"description": "Name of the extension." "description": "Name of the extension."
@@ -124,5 +120,29 @@
}, },
"voteOnTime": { "voteOnTime": {
"message": "Гласуване за спонсорства" "message": "Гласуване за спонсорства"
},
"savedPeopleFrom": {
"message": "Вие сте помогнали на хора да пропуснат "
},
"viewLeaderboard": {
"message": "Вижте leaderboard-а"
},
"here": {
"message": "тук"
},
"discordAdvert": {
"message": "Елате в официалния Discord сървър за да давате предложения!"
},
"hideThis": {
"message": "Скрий това"
},
"Options": {
"message": "Настройки"
},
"showButtons": {
"message": "Показване на бутоните в YouTube Player-а"
},
"hideButtons": {
"message": "Скриване на бутоните в YouTube Player-а"
} }
} }

View File

@@ -1,8 +1,4 @@
{ {
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": { "fullName": {
"message": "SponsorBlock für YouTube - Überspringe Sponsor Anzeigen", "message": "SponsorBlock für YouTube - Überspringe Sponsor Anzeigen",
"description": "Name of the extension." "description": "Name of the extension."
@@ -12,10 +8,10 @@
"description": "Description of the extension." "description": "Description of the extension."
}, },
"400": { "400": {
"message": "Ungültige Anforderung" "message": "Der Server meldet, dass diese Anfrage ungültig war"
}, },
"429": { "429": {
"message": "Du hast zu viele Segmente in diesem Video eingereicht. Bist du dir sicher?" "message": "Du hast zu viele Segmente in diesem Video eingereicht. Sind es wirklich so viele?"
}, },
"409": { "409": {
"message": "Dieser Inhalt wurde bereits eingereicht." "message": "Dieser Inhalt wurde bereits eingereicht."
@@ -33,11 +29,17 @@
"message": "gesponsorter Inhalt" "message": "gesponsorter Inhalt"
}, },
"Segments": { "Segments": {
"message": "gesponsorte Inhalte" "message": "gesponserten Inhalten"
},
"upvoteButtonInfo": {
"message": "Diesen Beitrag aufwerten"
}, },
"reportButtonTitle": { "reportButtonTitle": {
"message": "Melden" "message": "Melden"
}, },
"reportButtonInfo": {
"message": "Beitrag als unzulässig melden."
},
"Dismiss": { "Dismiss": {
"message": "Abbrechen" "message": "Abbrechen"
}, },
@@ -98,6 +100,9 @@
"voted": { "voted": {
"message": "Abgestimmt!" "message": "Abgestimmt!"
}, },
"serverDown": {
"message": "Der Server ist scheinbar offline. Bitte unverzüglich dem Entwickler melden."
},
"connectionError": { "connectionError": {
"message": "Ein Verbindungsfehler ist aufgetreten. Fehlermeldung: " "message": "Ein Verbindungsfehler ist aufgetreten. Fehlermeldung: "
}, },
@@ -114,7 +119,7 @@
"message": "Öffne SponsorBlock-Popup" "message": "Öffne SponsorBlock-Popup"
}, },
"SubmitTimes": { "SubmitTimes": {
"message": "Sende Auswahl" "message": "Diese Zeiten einreichen"
}, },
"submitCheck": { "submitCheck": {
"message": "Bist du sicher, dass die Auswahl abgeschickt werden soll?" "message": "Bist du sicher, dass die Auswahl abgeschickt werden soll?"
@@ -213,7 +218,7 @@
"message": "Benachrichtigung wieder zeigen" "message": "Benachrichtigung wieder zeigen"
}, },
"longDescription": { "longDescription": {
"message": "SponsorBlock ist eine Erweiterung, die gesponsorte Segmente in YouTube-Videos überspringt. SponsorBlock ist ein Benutzernetzwerk, bei dem jeder Anfang und Ende eines Werbeblocks einreichen kann. Sobald die Information von einem Nutzer eingereicht wurde, überspringen die Erweiterungen der anderen dieses Segment automatisch.", "message": "SponsorBlock ist eine Erweiterung, die gesponserte Segmente von YouTube Videos überspringt. SponsorBlock ist eine durch Crowdsourcing betriebene Browsererweiterung, die es jedem erlaubt, die Beginn- und Endzeitpunkte von gesponserten Segmenten in YouTube Videos einzureichen. Nachdem diese Information eingereicht wurde, wird das Segment für alle anderen Nutzer mit dieser Erweiterung direkt übersprungen.\n\nDu kannst auch den Vorspann, Nachspann, Erinnerungen zu abonnieren und andere Kategorien überspringen.",
"description": "Full description of the extension on the store pages." "description": "Full description of the extension on the store pages."
}, },
"website": { "website": {
@@ -273,7 +278,7 @@
"message": "Auto-Überspringen deaktivieren" "message": "Auto-Überspringen deaktivieren"
}, },
"enableAutoSkip": { "enableAutoSkip": {
"message": "Auto-Überspringen aktivieren" "message": "Automatisches Überspringen aktivieren"
}, },
"autoSkipDescription": { "autoSkipDescription": {
"message": "Auto-Überspringen überspringt gesponsorte Inhalte für dich. Wenn deaktiviert, fragt die Benachrichtigung, ob übersprungen werden soll." "message": "Auto-Überspringen überspringt gesponsorte Inhalte für dich. Wenn deaktiviert, fragt die Benachrichtigung, ob übersprungen werden soll."
@@ -284,6 +289,12 @@
"audioNotificationDescription": { "audioNotificationDescription": {
"message": "Audio-Benachrichtigung beim Überspringen wird einen Ton abspielen, wenn ein Sponsor übersprungen wird. Wenn deaktiviert (oder wenn Automatisches-Überspringen deaktiviert ist), wird kein Ton abgespielt." "message": "Audio-Benachrichtigung beim Überspringen wird einen Ton abspielen, wenn ein Sponsor übersprungen wird. Wenn deaktiviert (oder wenn Automatisches-Überspringen deaktiviert ist), wird kein Ton abgespielt."
}, },
"showTimeWithSkips": {
"message": "Zeit mit entfernten Überspringungen anzeigen"
},
"showTimeWithSkipsDescription": {
"message": "Diese Zeit wird in Klammern neben der aktuellen Zeit in der Suchleiste angezeigt. Diese Zeit die gesamte Dauer des Videos ohne jeglicher Segmente. Dies inkludiert auch Segmente, die als \"In Suchleiste anzeigen\" markiert sind."
},
"youHaveSkipped": { "youHaveSkipped": {
"message": "Du übersprangst " "message": "Du übersprangst "
}, },
@@ -461,9 +472,6 @@
"theKey": { "theKey": {
"message": "Die Taste" "message": "Die Taste"
}, },
"keyAlreadyUsedByYouTube": {
"message": "wird bereits von Youtube verwendet. Bitte wählen Sie eine andere Taste."
},
"keyAlreadyUsed": { "keyAlreadyUsed": {
"message": "an eine andere Aktion gebunden. Bitte wählen Sie eine andere Taste." "message": "an eine andere Aktion gebunden. Bitte wählen Sie eine andere Taste."
}, },
@@ -478,13 +486,13 @@
"message": "Bezahlte Promotion, bezahlte Empfehlungen und direkte Werbung. Nicht für Selbstpromotion oder kostenlose Shoutouts an Ursachen/Webseiten/Produkte, die sie mögen." "message": "Bezahlte Promotion, bezahlte Empfehlungen und direkte Werbung. Nicht für Selbstpromotion oder kostenlose Shoutouts an Ursachen/Webseiten/Produkte, die sie mögen."
}, },
"category_intro": { "category_intro": {
"message": "Intro Animation" "message": "Unterbrechung/Vorspann"
}, },
"category_intro_description": { "category_intro_description": {
"message": "Intro Animationen, die in der Serie wiederholt werden oder keinen direkten Wert haben. Dies sollte nicht für Musikvideos verwendet werden." "message": "Ein Intervall ohne relevanten Inhalt. Beispiele dafür wären eine Pause, ein statisches Bild oder sich wiederholende Animationen. Dies sollte nicht für Übergänge benutzt werden, die Informationen erhalten oder für Musikvideos."
}, },
"category_intro_short": { "category_intro_short": {
"message": "Intro" "message": "Unterbrechung"
}, },
"category_outro": { "category_outro": {
"message": "Endkarten/Credits" "message": "Endkarten/Credits"
@@ -501,6 +509,9 @@
"category_interaction_short": { "category_interaction_short": {
"message": "Interaktions-Erinnerung" "message": "Interaktions-Erinnerung"
}, },
"category_selfpromo": {
"message": "Unbezahlt/Eigenwerbung"
},
"category_selfpromo_description": { "category_selfpromo_description": {
"message": "Ähnlich wie bei \"Sponsor\" mit Ausnahme von unbezahlten oder Selbstpromotion. Dies beinhaltet Abschnitte über Waren, Spenden oder Informationen darüber, mit wem sie zusammengearbeitet haben." "message": "Ähnlich wie bei \"Sponsor\" mit Ausnahme von unbezahlten oder Selbstpromotion. Dies beinhaltet Abschnitte über Waren, Spenden oder Informationen darüber, mit wem sie zusammengearbeitet haben."
}, },
@@ -523,7 +534,7 @@
"message": "Deaktivieren" "message": "Deaktivieren"
}, },
"manualSkip": { "manualSkip": {
"message": "Manueller Überspringen" "message": "Manuelles Überspringen"
}, },
"showOverlay": { "showOverlay": {
"message": "Vor-/Rücklaufleiste anzeigen" "message": "Vor-/Rücklaufleiste anzeigen"
@@ -596,6 +607,9 @@
"nonMusicCategoryOnMusic": { "nonMusicCategoryOnMusic": {
"message": "Dieses Video ist als Musik kategorisiert. Sind Sie sicher, dass Sie Segmente mit Nicht-Musikkategorien einreichen möchten? Wenn dieses Video nicht wirklich Musik ist, sollten Sie dieses Segment nicht einreichen. Bitte lesen Sie die Richtlinien, wenn Sie verwirrt sind." "message": "Dieses Video ist als Musik kategorisiert. Sind Sie sicher, dass Sie Segmente mit Nicht-Musikkategorien einreichen möchten? Wenn dieses Video nicht wirklich Musik ist, sollten Sie dieses Segment nicht einreichen. Bitte lesen Sie die Richtlinien, wenn Sie verwirrt sind."
}, },
"multipleSegments": {
"message": "Mehrere Segmente"
},
"guidelines": { "guidelines": {
"message": "Richtlinien" "message": "Richtlinien"
}, },

View File

@@ -1,8 +1,4 @@
{ {
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": { "fullName": {
"message": "SponsorBlock for YouTube - Skip Sponsorships", "message": "SponsorBlock for YouTube - Skip Sponsorships",
"description": "Name of the extension." "description": "Name of the extension."
@@ -222,7 +218,7 @@
"message": "Show Notice Again" "message": "Show Notice Again"
}, },
"longDescription": { "longDescription": {
"message": "SponsorBlock is an extension that will skip over sponsored segments of YouTube videos. SponsorBlock is a crowdsourced browser extension that lets anyone submit the start and end times of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment.", "message": "SponsorBlock is an extension that will skip over sponsored segments of YouTube videos. SponsorBlock is a crowdsourced browser extension that lets anyone submit the start and end times of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment. \n\n You can also skip intros, outros, reminders to subscribe and other categories.",
"description": "Full description of the extension on the store pages." "description": "Full description of the extension on the store pages."
}, },
"website": { "website": {
@@ -293,6 +289,12 @@
"audioNotificationDescription": { "audioNotificationDescription": {
"message": "Audio notification on skip will play a sound whenever a sponsor is skipped. If disabled (or auto skip is disabled), no sound will be played." "message": "Audio notification on skip will play a sound whenever a sponsor is skipped. If disabled (or auto skip is disabled), no sound will be played."
}, },
"showTimeWithSkips": {
"message": "Show Time With Skips Removed"
},
"showTimeWithSkipsDescription": {
"message": "This time appears in brackets next to the current time on below the seekbar. This shows the total video duration minus any segments. This includes segments marked as only \"Show In Seekbar\"."
},
"youHaveSkipped": { "youHaveSkipped": {
"message": "You have skipped " "message": "You have skipped "
}, },
@@ -470,9 +472,6 @@
"theKey": { "theKey": {
"message": "The key" "message": "The key"
}, },
"keyAlreadyUsedByYouTube": {
"message": "is already used by youtube. Please select another key."
},
"keyAlreadyUsed": { "keyAlreadyUsed": {
"message": "is bound to another action. Please select another key." "message": "is bound to another action. Please select another key."
}, },
@@ -487,13 +486,13 @@
"message": "Paid promotion, paid referrals and direct advertisements. Not for self-promotion or free shoutouts to causes/creators/websites/products they like." "message": "Paid promotion, paid referrals and direct advertisements. Not for self-promotion or free shoutouts to causes/creators/websites/products they like."
}, },
"category_intro": { "category_intro": {
"message": "Intro Animation" "message": "Intermission/Intro Animation"
}, },
"category_intro_description": { "category_intro_description": {
"message": "Intro animations that are recurring in the series or provide no direct value. This should not be used on music videos." "message": "An interval without actual content. Could be a pause, static frame, repeating animation. This should not be used for transitions containing information or be used on music videos."
}, },
"category_intro_short": { "category_intro_short": {
"message": "Intro" "message": "Intermission"
}, },
"category_outro": { "category_outro": {
"message": "Endcards/Credits" "message": "Endcards/Credits"
@@ -572,6 +571,12 @@
"moreCategories": { "moreCategories": {
"message": "More Categories" "message": "More Categories"
}, },
"chooseACategory": {
"message": "Choose a Category"
},
"youMustSelectACategory": {
"message": "You must select a category for all segments you are submitting!"
},
"bracketEnd": { "bracketEnd": {
"message": "(End)" "message": "(End)"
}, },

View File

@@ -1,8 +1,4 @@
{ {
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": { "fullName": {
"message": "SponsorBlock para YouTube - Omitir Sponsors", "message": "SponsorBlock para YouTube - Omitir Sponsors",
"description": "Name of the extension." "description": "Name of the extension."
@@ -221,10 +217,6 @@
"showNotice": { "showNotice": {
"message": "Mostrar aviso de nuevo" "message": "Mostrar aviso de nuevo"
}, },
"longDescription": {
"message": "SponsorBlock es una extensión que se omitira segmentos de sponsor de vídeos de YouTube. SponsorBlock es una extensión de navegador que permite a cualquiera enviar los tiempos de comienzo y fin de segmentos de sponsor de vídeos de YouTube. Una vez que una persona envíe esta información, todos los demás con esta extensión pueden omitir directamente el segmento de sponsor.",
"description": "Full description of the extension on the store pages."
},
"website": { "website": {
"message": "Sitio Web", "message": "Sitio Web",
"description": "Used on Firefox Store Page" "description": "Used on Firefox Store Page"
@@ -440,18 +432,12 @@
"theKey": { "theKey": {
"message": "El botón" "message": "El botón"
}, },
"keyAlreadyUsedByYouTube": {
"message": "ya está en uso por youtube. Por favor, seleccione otro botón."
},
"keyAlreadyUsed": { "keyAlreadyUsed": {
"message": "está enlazado a otra acción. Por favor, seleccione otro botón." "message": "está enlazado a otra acción. Por favor, seleccione otro botón."
}, },
"category_sponsor": { "category_sponsor": {
"message": "Sponsor" "message": "Sponsor"
}, },
"category_intro": {
"message": "Animación de introducción"
},
"category_outro": { "category_outro": {
"message": "Tarjetas/Créditos" "message": "Tarjetas/Créditos"
}, },

View File

@@ -1,8 +1,4 @@
{ {
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": { "fullName": {
"message": "SponsorBlock YouTubelle - Ohita sponsoroinnit", "message": "SponsorBlock YouTubelle - Ohita sponsoroinnit",
"description": "Name of the extension." "description": "Name of the extension."
@@ -314,9 +310,6 @@
"theKey": { "theKey": {
"message": "Näppäin" "message": "Näppäin"
}, },
"keyAlreadyUsedByYouTube": {
"message": "on jo YouTuben käytössä. Valitse toinen näppäin."
},
"keyAlreadyUsed": { "keyAlreadyUsed": {
"message": "on jo liitetty toiseen toimintoon. Valitse toinen näppäin." "message": "on jo liitetty toiseen toimintoon. Valitse toinen näppäin."
}, },
@@ -327,9 +320,6 @@
"category_sponsor": { "category_sponsor": {
"message": "Sponsori" "message": "Sponsori"
}, },
"category_intro": {
"message": "Intro-animaatio"
},
"category_outro": { "category_outro": {
"message": "Loppukortit/-tekstit" "message": "Loppukortit/-tekstit"
}, },

View File

@@ -1,8 +1,4 @@
{ {
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": { "fullName": {
"message": "SponsorBlock pour YouTube - Supprime les messages commerciaux et publicités intégrées", "message": "SponsorBlock pour YouTube - Supprime les messages commerciaux et publicités intégrées",
"description": "Name of the extension." "description": "Name of the extension."
@@ -81,10 +77,10 @@
"message": "Êtes-vous certain(e) de vouloir supprimer vos soumissions ?\n\n" "message": "Êtes-vous certain(e) de vouloir supprimer vos soumissions ?\n\n"
}, },
"Unknown": { "Unknown": {
"message": "Une erreur s'est produite lors de la soumission, veuillez ré-essayer plus tard." "message": "Une erreur s'est produite lors de la soumission, veuillez réessayer plus tard."
}, },
"sponsorFound": { "sponsorFound": {
"message": "Les messages commerciaux pour cette vidéo sont déjà dans notre base de donnée !" "message": "Les messages commerciaux pour cette vidéo sont déjà dans notre base de données !"
}, },
"sponsor404": { "sponsor404": {
"message": "Pas de messages commerciaux trouvés" "message": "Pas de messages commerciaux trouvés"
@@ -168,10 +164,10 @@
"message": "Soumettre les temps" "message": "Soumettre les temps"
}, },
"publicStats": { "publicStats": {
"message": "Affiché sur le classement public pour montrer vos contributions. Voir sur" "message": "Votre pseudo est inscrit dans le classement public pour afficher vos contributions. Le consulter"
}, },
"setUsername": { "setUsername": {
"message": "Choisir pseudo" "message": "Choisir un pseudonyme"
}, },
"discordAdvert": { "discordAdvert": {
"message": "Rejoignez le serveur Discord officiel pour toutes suggestions ou remarques!" "message": "Rejoignez le serveur Discord officiel pour toutes suggestions ou remarques!"
@@ -221,10 +217,6 @@
"showNotice": { "showNotice": {
"message": "Afficher la notification" "message": "Afficher la notification"
}, },
"longDescription": {
"message": "SponsorBlock est une extension qui permet de passer les messages commerciaux des vidéos YouTube. SponsorBlock est une extension pour navigateur basée sur le crowdsourcing permettant à n'importe qui de soumettre le début et la fin des segments commerciaux sur les vidéos YouTube. Dès qu'une personne a soumis ces informations, les autres utilisateurs de l'extension en bénéficieront et verront les messages commerciaux automatiquement sautés.",
"description": "Full description of the extension on the store pages."
},
"website": { "website": {
"message": "Site web", "message": "Site web",
"description": "Used on Firefox Store Page" "description": "Used on Firefox Store Page"
@@ -297,7 +289,7 @@
"message": "Vous avez passé " "message": "Vous avez passé "
}, },
"youHaveSaved": { "youHaveSaved": {
"message": "Vous avez économisé " "message": "Vous vous êtes économisé "
}, },
"minLower": { "minLower": {
"message": "minute" "message": "minute"
@@ -342,13 +334,13 @@
"message": "Passage automatique" "message": "Passage automatique"
}, },
"showSkipNotice": { "showSkipNotice": {
"message": "Afficher l'avis après le passage d'un sponsor" "message": "Notifier après qu'un sponsor ait été sauté"
}, },
"keybindCurrentlySet": { "keybindCurrentlySet": {
"message": ". Il est actuellement réglé sur :" "message": ". Il est actuellement réglé sur :"
}, },
"supportInvidious": { "supportInvidious": {
"message": "Soutenir Invidious" "message": "Supporter Invidious"
}, },
"supportInvidiousDescription": { "supportInvidiousDescription": {
"message": "Invidious (invidio.us) est un client tiers pour YouTube. Vous devez accepter des permissions supplémentaires pour activer son support. Cette fonctionnalité ne fonctionne pas en mode incognito sur Chrome et les autres variantes de Chromium." "message": "Invidious (invidio.us) est un client tiers pour YouTube. Vous devez accepter des permissions supplémentaires pour activer son support. Cette fonctionnalité ne fonctionne pas en mode incognito sur Chrome et les autres variantes de Chromium."
@@ -470,9 +462,6 @@
"theKey": { "theKey": {
"message": "La clé" "message": "La clé"
}, },
"keyAlreadyUsedByYouTube": {
"message": "est déjà utilisé par YouTube. Veuillez sélectionner une autre clé."
},
"keyAlreadyUsed": { "keyAlreadyUsed": {
"message": "est lié à une autre action. Veuillez sélectionner une autre clé." "message": "est lié à une autre action. Veuillez sélectionner une autre clé."
}, },
@@ -483,21 +472,45 @@
"category_sponsor": { "category_sponsor": {
"message": "Message commercial" "message": "Message commercial"
}, },
"category_intro": { "category_sponsor_description": {
"message": "Générique d'introduction" "message": "Promotion rémunérée, parrainage rémunéré et publicité directe. Pas pour l'autopromotion ou les présentations gratuites de causes, de créateurs, de sites web ou de produits qu'ils aiment."
}, },
"category_outro": { "category_outro": {
"message": "Générique de fin" "message": "Générique de fin"
}, },
"category_outro_description": {
"message": "Générique de fin ou quand les fiches de fin de vidéo apparaissent. Ne pas utiliser pour les conclusions orales. Ne doit pas inclure de contenu utile. Ne pas utiliser sur les vidéos de musique."
},
"category_interaction": { "category_interaction": {
"message": "Rappel d'interaction (abonnement)" "message": "Rappel d'interaction (abonnement)"
}, },
"category_interaction_description": {
"message": "Lorsqu'il y a un bref rappel pour liker, s'abonner ou les follow parmi le contenu. Si le message est long ou porte sur quelque chose de spécifique, cela devrait plutôt être classé comme une autopromotion."
},
"category_interaction_short": {
"message": "Rappel d'interaction"
},
"category_selfpromo": {
"message": "Non rémunéré/autopromotion"
},
"category_selfpromo_description": {
"message": "Semblable au \"sponsor\", excepté pour la promotion non rémunérée ou l'auto-promotion. Cela inclut les marchandises, les dons et les informations sur leurs collaborateurs."
},
"category_music_offtopic": { "category_music_offtopic": {
"message": "Musique : Segment non-musicale" "message": "Musique : Segment non-musicale"
}, },
"category_music_offtopic_description": {
"message": "A utiliser uniquement dans les vidéos musicales. Cela inclut les introductions ou les fins dans les vidéos."
},
"category_music_offtopic_short": {
"message": "Hors musique"
},
"category_livestream_messages": { "category_livestream_messages": {
"message": "Stream : lecture de dons et messages" "message": "Stream : lecture de dons et messages"
}, },
"category_livestream_messages_short": {
"message": "Lecture de messages"
},
"disable": { "disable": {
"message": "Désactiver" "message": "Désactiver"
}, },
@@ -507,6 +520,23 @@
"showOverlay": { "showOverlay": {
"message": "Afficher dans la barre de progression" "message": "Afficher dans la barre de progression"
}, },
"colorFormatIncorrect": {
"message": "Votre couleur est mal formatée. Il devrait s'agir d'un code hexadécimal à 3 ou 6 chiffres avec un signe numérique au début."
},
"previewColor": {
"message": "Couleur en mode aperçu",
"description": "Referring to submissions that have not been sent to the server yet."
},
"seekBarColor": {
"message": "Couleur dans la barre de progression"
},
"category": {
"message": "Catégorie"
},
"skipOption": {
"message": "Option de saut",
"description": "Used on the options page to describe the ways to skip the segment (auto skip, manual, etc.)"
},
"enableTestingServer": { "enableTestingServer": {
"message": "Activer le serveur de test bêta" "message": "Activer le serveur de test bêta"
}, },
@@ -560,5 +590,24 @@
}, },
"multipleSegments": { "multipleSegments": {
"message": "Plusieurs segments" "message": "Plusieurs segments"
},
"guidelines": {
"message": "Instructions"
},
"readTheGuidelines": {
"message": "Lisez les instructions !!",
"description": "Show the first time they submit or if they are \"high risk\""
},
"categoryUpdate1": {
"message": "Les catégories sont là !"
},
"categoryUpdate2": {
"message": "Ouvrir les options pour sauter les intros, outros, marchandises, etc."
},
"unsubmittedWarning": {
"message": "Notification de segments non soumis"
},
"unsubmittedWarningDescription": {
"message": "Envoyer une notification lorsque vous quittez une vidéo avec des segments qui ne sont pas téléversés"
} }
} }

View File

@@ -1,8 +1,4 @@
{ {
"Name": {
"message": "સ્પોન્સરબ્લોક",
"description": "Name of the extension."
},
"fullName": { "fullName": {
"message": "યુટ્યુબ માટે સ્પોન્સરબ્લોક - સ્પોન્સરશિપ છોડી દો", "message": "યુટ્યુબ માટે સ્પોન્સરબ્લોક - સ્પોન્સરશિપ છોડી દો",
"description": "Name of the extension." "description": "Name of the extension."

View File

@@ -205,10 +205,6 @@
"showNotice": { "showNotice": {
"message": "Mostra di Nuovo l'Avviso" "message": "Mostra di Nuovo l'Avviso"
}, },
"longDescription": {
"message": "SponsorBlock è un'estensione che salta gli spezzoni con contenuti sponsorizzati nei video di YouTube. SponsorBlock è un'estensione crowdsourced per i browser che permette a chiunque di inviare i minutaggi degli spezzoni sponsorizzati nei video di YouTube. Quando una persona avrà inviato questa informazione, tutti gli utenti che utilizzano questa estensione potranno saltare lo spezzone sponsorizzato.",
"description": "Full description of the extension on the store pages."
},
"website": { "website": {
"message": "Sito Web", "message": "Sito Web",
"description": "Used on Firefox Store Page" "description": "Used on Firefox Store Page"

View File

@@ -1,8 +1,4 @@
{ {
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": { "fullName": {
"message": "SponsorBlock voor YouTube - Sla sponsorberichten over", "message": "SponsorBlock voor YouTube - Sla sponsorberichten over",
"description": "Name of the extension." "description": "Name of the extension."
@@ -11,15 +7,39 @@
"message": "Sla sponsoring over op YouTube video's. Rapporteer sponsors van video's die je bekijkt om tijd van anderen te besparen.", "message": "Sla sponsoring over op YouTube video's. Rapporteer sponsors van video's die je bekijkt om tijd van anderen te besparen.",
"description": "Description of the extension." "description": "Description of the extension."
}, },
"400": {
"message": "Server zegt dat het verzoek ongeldig is"
},
"429": {
"message": "Je hebt te veel sponsortijden voor deze video doorgegeven, weet je zeker dat het er zo veel zijn?"
},
"409": {
"message": "Dit is al een keer ingediend"
},
"channelWhitelisted": {
"message": "Kanaal gewhitelist!"
},
"Sponsor": { "Sponsor": {
"message": "sponsor" "message": "sponsor"
}, },
"Sponsors": { "Sponsors": {
"message": "sponsoren" "message": "sponsoren"
}, },
"Segment": {
"message": "Sponsor segment"
},
"Segments": {
"message": "Sponsor segmenten"
},
"upvoteButtonInfo": {
"message": "Stem op deze indiening"
},
"reportButtonTitle": { "reportButtonTitle": {
"message": "Melden" "message": "Melden"
}, },
"reportButtonInfo": {
"message": "Rapporteer deze indiening als onjuist."
},
"Dismiss": { "Dismiss": {
"message": "Negeren" "message": "Negeren"
}, },
@@ -35,9 +55,21 @@
"Hide": { "Hide": {
"message": "Nooit weergeven" "message": "Nooit weergeven"
}, },
"hitGoBack": {
"message": "Druk op unskip om naar waar je vandaan komt te gaan."
},
"unskip": {
"message": "Unskip"
},
"reskip": {
"message": "Reskip"
},
"paused": { "paused": {
"message": "Gepauzeerd" "message": "Gepauzeerd"
}, },
"manualPaused": {
"message": "Timer gestopt"
},
"clearThis": { "clearThis": {
"message": "Weet je zeker dat je dit formulier wilt wissen?\n\n" "message": "Weet je zeker dat je dit formulier wilt wissen?\n\n"
}, },

View File

@@ -1,8 +1,4 @@
{ {
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": { "fullName": {
"message": "SponsorBlock na YouTube - Omiń reklamy sponsorów", "message": "SponsorBlock na YouTube - Omiń reklamy sponsorów",
"description": "Name of the extension." "description": "Name of the extension."
@@ -209,10 +205,6 @@
"showNotice": { "showNotice": {
"message": "Pokaż informacje ponownie" "message": "Pokaż informacje ponownie"
}, },
"longDescription": {
"message": "SponsorBlock jest rozszerzeniem które przewinie segmenty sponsorów w filmach na YouTube. SponsorBlock jest opartym na crowdsourcing rozszerzeniem które pozwala każdemu zgłaszać początek i koniec segmentu reklamowego w filmach na YouTube. Kiedy ktoś zgłosi taki fragment zostanie on pominięty przez innych użytkowników rozszerzenia.",
"description": "Full description of the extension on the store pages."
},
"website": { "website": {
"message": "Strona", "message": "Strona",
"description": "Used on Firefox Store Page" "description": "Used on Firefox Store Page"

View File

@@ -1,8 +1,4 @@
{ {
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": { "fullName": {
"message": "SponsorBlock para YouTube - Pule patrocínios", "message": "SponsorBlock para YouTube - Pule patrocínios",
"description": "Name of the extension." "description": "Name of the extension."
@@ -38,6 +34,9 @@
"reportButtonTitle": { "reportButtonTitle": {
"message": "Reportar" "message": "Reportar"
}, },
"reportButtonInfo": {
"message": "Reportar esse segmento como inválido."
},
"Dismiss": { "Dismiss": {
"message": "Ignorar" "message": "Ignorar"
}, },
@@ -54,7 +53,7 @@
"message": "Nunca mostrar" "message": "Nunca mostrar"
}, },
"hitGoBack": { "hitGoBack": {
"message": "Aperta reverter pulo para voltar onde estava" "message": "Aperta \"reverter pulo\" para voltar onde estava."
}, },
"unskip": { "unskip": {
"message": "Reverter pulo" "message": "Reverter pulo"
@@ -72,7 +71,7 @@
"message": "Tem certeza que quer limpar isso?\n\n" "message": "Tem certeza que quer limpar isso?\n\n"
}, },
"Unknown": { "Unknown": {
"message": "Teve um erro ao enviar seus segmentos, tente novamente depois." "message": "Houve um erro ao enviar seus segmentos, tente novamente mais tarde."
}, },
"sponsorFound": { "sponsorFound": {
"message": "Os patrocinadores desse vídeo estão no banco de dados!" "message": "Os patrocinadores desse vídeo estão no banco de dados!"
@@ -87,7 +86,7 @@
"message": "Patrocínio termina agora" "message": "Patrocínio termina agora"
}, },
"noVideoID": { "noVideoID": {
"message": "Isso provavelmente não é uma tab do YouTube, ou você clicou muito cedo. \n Se sabe que é uma tab do YouTube,\n feche esse popup e abra de novo." "message": "Nenhum vídeo do YouTube foi encontrado nesta aba. Se você sabe que esta é uma aba do YouTube, feche este pop-up e abra-o novamente. Se isso não funcionar, tente recarregar a aba."
}, },
"success": { "success": {
"message": "Sucesso!" "message": "Sucesso!"
@@ -95,14 +94,17 @@
"voted": { "voted": {
"message": "Votado!" "message": "Votado!"
}, },
"serverDown": {
"message": "Parece que o servidor caiu. Contate o desenvolvedor o quanto antes."
},
"connectionError": { "connectionError": {
"message": "Um erro de conexão aconteceu: Código: " "message": "Ocorreu um erro de conexão. Código de erro: "
}, },
"wantToSubmit": { "wantToSubmit": {
"message": "Quer enviar os segmentos para o vídeo de ID" "message": "Quer enviar os segmentos para o vídeo de ID"
}, },
"leftTimes": { "leftTimes": {
"message": "Parece que você se esqueceu de enviar alguns segmentos. Volta pra página para os enviar (não foram deletados)." "message": "Parece que você se esqueceu de enviar alguns segmentos. Volte para aquela página para enviá-los (eles não foram deletados)."
}, },
"clearTimes": { "clearTimes": {
"message": "Apagar intervalos dos patrocínios" "message": "Apagar intervalos dos patrocínios"
@@ -111,25 +113,25 @@
"message": "Abrir o Popup SponsorBlock" "message": "Abrir o Popup SponsorBlock"
}, },
"SubmitTimes": { "SubmitTimes": {
"message": "Submeter intervalos dos patrocínios" "message": "Enviar intervalos de patrocínios"
}, },
"submitCheck": { "submitCheck": {
"message": "Tem a certeza que pretende submeter?" "message": "Você tem certeza que deseja enviar isto?"
}, },
"whitelistChannel": { "whitelistChannel": {
"message": "Meter canal na Whitelist" "message": "Colocar canal na lista branca"
}, },
"removeFromWhitelist": { "removeFromWhitelist": {
"message": "Remover canal da Whitelist" "message": "Remover canal da lista branca"
}, },
"voteOnTime": { "voteOnTime": {
"message": "Vote num intervalo de patrocínio" "message": "Vote num intervalo de patrocínio"
}, },
"recordTimes": { "recordTimes": {
"message": "Registe um intervalo de patrocínio" "message": "Grave os intervalos de um patrocínio"
}, },
"soFarUHSubmited": { "soFarUHSubmited": {
"message": "Até agora submeteu" "message": "Até agora, você já enviou"
}, },
"savedPeopleFrom": { "savedPeopleFrom": {
"message": "Poupaste a outros de " "message": "Poupaste a outros de "
@@ -141,10 +143,10 @@
"message": "aqui" "message": "aqui"
}, },
"recordTimesDescription": { "recordTimesDescription": {
"message": "Clique no botão abaixo quando o patrocínio começar e quando terminar para registrar e submetê-lo à base de dados." "message": "Clique no botão abaixo quando o patrocínio começa e termina para gravá-lo na base de dados."
}, },
"popupHint": { "popupHint": {
"message": "Dica: Aperte a tecla ; enquanto reproduzir o vídeo para registar o começo/fim de um patrocínio e \" para enviar. (Essa configuração pode ser mudada em opções.)" "message": "Dica: Aperte a tecla ponto e vírgula (;) com a janela focada em um vídeo para reportar o começo/fim de um patrocínio e aspas (\") para enviar. (Esta configuração pode ser mudada nas opções.)"
}, },
"lastTimes": { "lastTimes": {
"message": "Últimos Intervalos de Patrocínios Seleciados" "message": "Últimos Intervalos de Patrocínios Seleciados"
@@ -159,10 +161,10 @@
"message": "Isso é usado na página pública de estatísticas que mostra o quanto você já contríbuíu. Veja-a" "message": "Isso é usado na página pública de estatísticas que mostra o quanto você já contríbuíu. Veja-a"
}, },
"setUsername": { "setUsername": {
"message": "Criar nomde de utilizador" "message": "Definir nome de usuário"
}, },
"discordAdvert": { "discordAdvert": {
"message": "Junte-se ao discord oficial para sugerir dicas e sugestões!" "message": "Junte-se ao servidor do discord oficial para dar dicas e sugestões!"
}, },
"hideThis": { "hideThis": {
"message": "Esconder isto" "message": "Esconder isto"
@@ -209,10 +211,6 @@
"showNotice": { "showNotice": {
"message": "Mostrar notificação outra vez" "message": "Mostrar notificação outra vez"
}, },
"longDescription": {
"message": "SponsorBlock é uma extensão que salta segmentos patrocinados em vídeos do YouTube. SponsorBlock é uma extenção crowdfunded que permite a qualquer um submeter o início e o fim de segmentos patrocinados. Assim que uma pessoa submete essa informação todos com a extenção poderam saltar automaticamete o patrocínio.",
"description": "Full description of the extension on the store pages."
},
"website": { "website": {
"message": "Site", "message": "Site",
"description": "Used on Firefox Store Page" "description": "Used on Firefox Store Page"
@@ -263,6 +261,9 @@
"skip": { "skip": {
"message": "Pular" "message": "Pular"
}, },
"skipped": {
"message": "Pulado"
},
"disableAutoSkip": { "disableAutoSkip": {
"message": "Desativar Salto Automático" "message": "Desativar Salto Automático"
}, },
@@ -455,9 +456,6 @@
"theKey": { "theKey": {
"message": "A tecla" "message": "A tecla"
}, },
"keyAlreadyUsedByYouTube": {
"message": "já está sendo usado pelo youtube. Por favor, selecione outra tecla."
},
"keyAlreadyUsed": { "keyAlreadyUsed": {
"message": "está vinculado a outra ação. Por favor, selecione outra tecla." "message": "está vinculado a outra ação. Por favor, selecione outra tecla."
}, },
@@ -468,21 +466,24 @@
"category_sponsor": { "category_sponsor": {
"message": "Patrocinador" "message": "Patrocinador"
}, },
"category_intro": {
"message": "Animação de Introdução"
},
"category_outro": { "category_outro": {
"message": "Finalização/Créditos" "message": "Finalização/Créditos"
}, },
"category_interaction": { "category_interaction": {
"message": "Lembrete de interação (inscrever-se)" "message": "Lembrete de interação (inscrever-se)"
}, },
"category_interaction_short": {
"message": "Lembrete de interação"
},
"category_music_offtopic": { "category_music_offtopic": {
"message": "Música: Seção sem música" "message": "Música: Seção sem música"
}, },
"category_livestream_messages": { "category_livestream_messages": {
"message": "Livestream: Leituras de Doação/Mensagem" "message": "Livestream: Leituras de Doação/Mensagem"
}, },
"category_livestream_messages_short": {
"message": "Leitura de mensagens"
},
"disable": { "disable": {
"message": "Desativar" "message": "Desativar"
}, },
@@ -492,6 +493,20 @@
"showOverlay": { "showOverlay": {
"message": "Mostrar barra de progresso" "message": "Mostrar barra de progresso"
}, },
"previewColor": {
"message": "Cor de pré-visualização",
"description": "Referring to submissions that have not been sent to the server yet."
},
"seekBarColor": {
"message": "Cor da barra"
},
"category": {
"message": "Categoria"
},
"skipOption": {
"message": "Opção de pulo",
"description": "Used on the options page to describe the ways to skip the segment (auto skip, manual, etc.)"
},
"enableTestingServer": { "enableTestingServer": {
"message": "Habilitar Servidor em teste Beta" "message": "Habilitar Servidor em teste Beta"
}, },
@@ -534,10 +549,25 @@
"forceChannelCheckPopup": { "forceChannelCheckPopup": {
"message": "Considere habilitar a verificação de canal forçada antes de pular os patrocinadores" "message": "Considere habilitar a verificação de canal forçada antes de pular os patrocinadores"
}, },
"downvoteDescription": {
"message": "Incorreto/tempo errado"
},
"incorrectCategory": { "incorrectCategory": {
"message": "Categoria errada" "message": "Categoria errada"
}, },
"nonMusicCategoryOnMusic": { "nonMusicCategoryOnMusic": {
"message": "Este vídeo é classificado como música. Você tem certeza que deseja enviar segmentos com categorias que não são músicas? A menos que esse vídeo não seja de fato música, você não deve enviar esse segmento. Por favor leia as orientações se estiver em dúvidas." "message": "Este vídeo é classificado como música. Você tem certeza que deseja enviar segmentos com categorias que não são músicas? A menos que esse vídeo não seja de fato música, você não deve enviar esse segmento. Por favor leia as orientações se estiver em dúvidas."
},
"multipleSegments": {
"message": "Multiplos segmentos"
},
"categoryUpdate1": {
"message": "As categorias estão aqui!"
},
"unsubmittedWarning": {
"message": "Notificação de segmentos não enviados"
},
"unsubmittedWarningDescription": {
"message": "Enviar uma notificação quando você sair de um vídeo com segmentos que não foram enviados"
} }
} }

View File

@@ -205,10 +205,6 @@
"showNotice": { "showNotice": {
"message": "Mostrar notificação outra vez" "message": "Mostrar notificação outra vez"
}, },
"longDescription": {
"message": "SponsorBlock é uma extensão que salta segmentos patrocinados em vídeos do YouTube. SponsorBlock é uma extenção crowdfunded que permite a qualquer um submeter o início e o fim de segmentos patrocinados. Assim que uma pessoa submete essa informação todos com a extenção poderam saltar automaticamete o patrocínio.",
"description": "Full description of the extension on the store pages."
},
"website": { "website": {
"message": "Site", "message": "Site",
"description": "Used on Firefox Store Page" "description": "Used on Firefox Store Page"

View File

@@ -1,8 +1,4 @@
{ {
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": { "fullName": {
"message": "SponsorBlock pentru YouTube - Sari peste sponsorizări", "message": "SponsorBlock pentru YouTube - Sari peste sponsorizări",
"description": "Name of the extension." "description": "Name of the extension."
@@ -221,10 +217,6 @@
"showNotice": { "showNotice": {
"message": "Arată Notificarea Din Nou" "message": "Arată Notificarea Din Nou"
}, },
"longDescription": {
"message": "SponsorBlock este o extensie care va sări peste segmentele sponsorizate din videoclipurile de pe YouTube. SponsorBlock este o extensie crowdsourced care lasă pe oricine să trimită începutul și finalul segmentelor sponsorizate din videoclipurile de pe YouTube. Odată ce o persoană trimite aceste informații, toată lumea cu această extensie va sări peste acel segment sponsorizat.",
"description": "Full description of the extension on the store pages."
},
"website": { "website": {
"message": "Website", "message": "Website",
"description": "Used on Firefox Store Page" "description": "Used on Firefox Store Page"
@@ -470,9 +462,6 @@
"theKey": { "theKey": {
"message": "Tasta" "message": "Tasta"
}, },
"keyAlreadyUsedByYouTube": {
"message": "este deja utilizat de YouTube. Vă rugăm selectați o altă tastă."
},
"keyAlreadyUsed": { "keyAlreadyUsed": {
"message": "este deja setată la o altă acțiune. Vă rugăm să selectați o altă tastă." "message": "este deja setată la o altă acțiune. Vă rugăm să selectați o altă tastă."
}, },
@@ -486,15 +475,6 @@
"category_sponsor_description": { "category_sponsor_description": {
"message": "Promovare plătită, refferali plătiți și reclame directe. Nu pentru autopromovări sau promovări gratis ale cauzelor/creatorilor/website-urilor/produselor." "message": "Promovare plătită, refferali plătiți și reclame directe. Nu pentru autopromovări sau promovări gratis ale cauzelor/creatorilor/website-urilor/produselor."
}, },
"category_intro": {
"message": "Animație de Început"
},
"category_intro_description": {
"message": "Animațiile de introducere care se repetă în serie sau care nu oferă nici o valoare directă. Această opțiune nu ar trebui folosită în videoclipurile muzicale."
},
"category_intro_short": {
"message": "Intro"
},
"category_outro": { "category_outro": {
"message": "Ecran De Final/Credite" "message": "Ecran De Final/Credite"
}, },

View File

@@ -1,8 +1,4 @@
{ {
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": { "fullName": {
"message": "SponsorBlock для YouTube - Пропускайте спонсорские вставки", "message": "SponsorBlock для YouTube - Пропускайте спонсорские вставки",
"description": "Name of the extension." "description": "Name of the extension."
@@ -65,6 +61,9 @@
"paused": { "paused": {
"message": "Пауза" "message": "Пауза"
}, },
"manualPaused": {
"message": "Таймер остановлен"
},
"confirmMSG": { "confirmMSG": {
"message": "\n\nЧтобы изменить или удалить отдельные значения, нажмите кнопку «Информация» или откройте всплывающее окно расширения, щелкнув значок расширения в правом верхнем углу." "message": "\n\nЧтобы изменить или удалить отдельные значения, нажмите кнопку «Информация» или откройте всплывающее окно расширения, щелкнув значок расширения в правом верхнем углу."
}, },
@@ -107,6 +106,9 @@
"clearTimes": { "clearTimes": {
"message": "Удалить отмеченные сегменты" "message": "Удалить отмеченные сегменты"
}, },
"openPopup": {
"message": "Открыть всплывающее окно SponsorBlock"
},
"SubmitTimes": { "SubmitTimes": {
"message": "Отправить отмеченные сегменты" "message": "Отправить отмеченные сегменты"
}, },
@@ -206,10 +208,6 @@
"showNotice": { "showNotice": {
"message": "Показывать уведомление снова" "message": "Показывать уведомление снова"
}, },
"longDescription": {
"message": "SponsorBlock — это расширение, которое пропускает спонсорские вставки в видео на YouTube. SponsorBlock — это краудсорсинговое расширение, которое позволяет каждому отправить время начала и конца спонсорских сегментов в видео на YouTube. После того, как кто-нибудь отправляет эту информацию, все остальные пользователи расширения будут автоматически пропускать спонсорские сегменты.",
"description": "Full description of the extension on the store pages."
},
"website": { "website": {
"message": "Сайт", "message": "Сайт",
"description": "Used on Firefox Store Page" "description": "Used on Firefox Store Page"
@@ -413,6 +411,24 @@
"whatExportOptions": { "whatExportOptions": {
"message": "Это вся конфигурация в формате JSON. Этот файл содержит Ваш идентификатор пользователя, поэтому не забудьте общаться с этим разумно." "message": "Это вся конфигурация в формате JSON. Этот файл содержит Ваш идентификатор пользователя, поэтому не забудьте общаться с этим разумно."
}, },
"submit": {
"message": "Отправить"
},
"cancel": {
"message": "Отменить"
},
"delete": {
"message": "Удалить"
},
"preview": {
"message": "Превью"
},
"edit": {
"message": "Редактировать"
},
"copyDebugInformation": {
"message": "Скопировать отладочную информацию в буфер обмена"
},
"bracketNow": { "bracketNow": {
"message": "(Сейчас)" "message": "(Сейчас)"
}, },

View File

@@ -1,8 +1,4 @@
{ {
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"Sponsor": { "Sponsor": {
"message": "sponzor" "message": "sponzor"
}, },

View File

@@ -4,7 +4,7 @@
"description": "Name of the extension." "description": "Name of the extension."
}, },
"Description": { "Description": {
"message": "Hoppa över sponsormeddelanden på YouTube-videor. Rapportera sponsring på videor du ser på för att spara tid för andra.", "message": "Hoppa över sponsormeddelanden på YouTube-videor. Rapportera sponsring på videor du ser på för att spara tid åt andra.",
"description": "Description of the extension." "description": "Description of the extension."
}, },
"400": { "400": {
@@ -14,11 +14,14 @@
"message": "Du har rapporterat för många sponsormeddelanden för den här videon, är du säker att det finns så många?" "message": "Du har rapporterat för många sponsormeddelanden för den här videon, är du säker att det finns så många?"
}, },
"409": { "409": {
"message": "Den här har redan blivit rapporterad." "message": "Den här har redan blivit rapporterad"
}, },
"channelWhitelisted": { "channelWhitelisted": {
"message": "Kanal vitlistad!" "message": "Kanal vitlistad!"
}, },
"Sponsor": {
"message": "sponsor"
},
"Sponsors": { "Sponsors": {
"message": "sponsorer" "message": "sponsorer"
}, },
@@ -31,6 +34,9 @@
"reportButtonTitle": { "reportButtonTitle": {
"message": "Rapportera" "message": "Rapportera"
}, },
"reportButtonInfo": {
"message": "Rapportera det här segmentet som inkorrekt."
},
"Dismiss": { "Dismiss": {
"message": "Avfärda" "message": "Avfärda"
}, },
@@ -44,7 +50,7 @@
"message": "Sekunder" "message": "Sekunder"
}, },
"Hide": { "Hide": {
"message": "\"Visa aldrig\"-knappen. " "message": "Visa Aldrig"
}, },
"hitGoBack": { "hitGoBack": {
"message": "Tryck på Tillbaka för att ångra åtgärden." "message": "Tryck på Tillbaka för att ångra åtgärden."
@@ -53,11 +59,14 @@
"message": "Tillbaka" "message": "Tillbaka"
}, },
"reskip": { "reskip": {
"message": "Frammåt" "message": "Framåt"
}, },
"paused": { "paused": {
"message": "Pausad" "message": "Pausad"
}, },
"manualPaused": {
"message": "Timern stoppad"
},
"confirmMSG": { "confirmMSG": {
"message": "Klicka på infoknappen eller öppna popup-rutan genom att klicka på tilläggets ikon i hörnet uppe till höger för att redigera eller ta bort inviduella värden." "message": "Klicka på infoknappen eller öppna popup-rutan genom att klicka på tilläggets ikon i hörnet uppe till höger för att redigera eller ta bort inviduella värden."
}, },
@@ -88,6 +97,9 @@
"voted": { "voted": {
"message": "Röstat!" "message": "Röstat!"
}, },
"serverDown": {
"message": "Det verkar som att servern är nere. Kontakta utvecklaren omedelbart."
},
"connectionError": { "connectionError": {
"message": "Anslutningsfel. Felkod: " "message": "Anslutningsfel. Felkod: "
}, },
@@ -130,6 +142,9 @@
"viewLeaderboard": { "viewLeaderboard": {
"message": "Se leaderboarden" "message": "Se leaderboarden"
}, },
"here": {
"message": "här"
},
"recordTimesDescription": { "recordTimesDescription": {
"message": "Klicka på knappen nedan när sponsormeddelandet börjar och slutar för att spela in och rapportera till databasen." "message": "Klicka på knappen nedan när sponsormeddelandet börjar och slutar för att spela in och rapportera till databasen."
}, },
@@ -199,10 +214,6 @@
"showNotice": { "showNotice": {
"message": "Visa Notisen Igen" "message": "Visa Notisen Igen"
}, },
"longDescription": {
"message": "SponsorBlock är ett webbläsartillägg som hoppar över sponsormeddelanden på YouTube-videor. SponsorBlock är ett crowdsourcat webbläsartillägg som låter vem som hellst att rapportera start och sluttider för sponsorsegment på YouTube-videor. När informationen väl har rapporterats kommer alla andra med detta tillägg att hoppa över sponsorsegmentet.",
"description": "Full description of the extension on the store pages."
},
"website": { "website": {
"message": "Hemsida", "message": "Hemsida",
"description": "Used on Firefox Store Page" "description": "Used on Firefox Store Page"
@@ -253,6 +264,9 @@
"skip": { "skip": {
"message": "Hoppa över" "message": "Hoppa över"
}, },
"skipped": {
"message": "Skippat"
},
"disableAutoSkip": { "disableAutoSkip": {
"message": "Avaktivera Hoppa Över Automatiskt" "message": "Avaktivera Hoppa Över Automatiskt"
}, },
@@ -325,6 +339,9 @@
"supportInvidious": { "supportInvidious": {
"message": "Stöd Invidious" "message": "Stöd Invidious"
}, },
"supportInvidiousDescription": {
"message": "Invidious (invidio.us) är en tredjeparts YouTube-klient. För att aktivera stöd måste du acceptera de extra behörigheterna. Detta kommer INTE att fungera i incognito i Chrome och andra Cromium-varianter."
},
"optionsInfo": { "optionsInfo": {
"message": "Aktivera Invidious stöd, avaktivera hoppa över automatiskt, dölj knappar och mer." "message": "Aktivera Invidious stöd, avaktivera hoppa över automatiskt, dölj knappar och mer."
}, },
@@ -442,9 +459,6 @@
"theKey": { "theKey": {
"message": "Nyckeln" "message": "Nyckeln"
}, },
"keyAlreadyUsedByYouTube": {
"message": "används redan av YouTube. Välj en annan nyckel."
},
"keyAlreadyUsed": { "keyAlreadyUsed": {
"message": "är kopplad till en annan funktion. Välj en annan knapp." "message": "är kopplad till en annan funktion. Välj en annan knapp."
}, },
@@ -455,6 +469,12 @@
"category_sponsor": { "category_sponsor": {
"message": "Sponsormeddelande" "message": "Sponsormeddelande"
}, },
"category_music_offtopic_description": {
"message": "Endast för användning i musikvideor. Detta inkluderar intros och outros i musikvideor."
},
"category_music_offtopic_short": {
"message": "Icke-musik"
},
"disable": { "disable": {
"message": "Avaktivera" "message": "Avaktivera"
}, },
@@ -464,6 +484,9 @@
"showOverlay": { "showOverlay": {
"message": "Visa Lager Ovanpå Spelare" "message": "Visa Lager Ovanpå Spelare"
}, },
"category": {
"message": "Kategori"
},
"enableTestingServer": { "enableTestingServer": {
"message": "Aktivera Server För Betatestning" "message": "Aktivera Server För Betatestning"
}, },
@@ -482,6 +505,9 @@
"bracketEnd": { "bracketEnd": {
"message": "(Slut)" "message": "(Slut)"
}, },
"hiddenDueToDuration": {
"message": "dold: för kort"
},
"channelDataNotFound": { "channelDataNotFound": {
"message": "Kanal-ID är inte inladdat än." "message": "Kanal-ID är inte inladdat än."
}, },
@@ -490,5 +516,24 @@
}, },
"itCouldBeAdblockerIssue": { "itCouldBeAdblockerIssue": {
"message": "Om detta fortsätter att inträffa, kan orsaken vara din annonsblockerare. Vänligen kontrollera https://github.com/ajayyy/SponsorBlock/wiki/Fix-Ad-Blocker-Blocking-SponsorBlock's-Requests" "message": "Om detta fortsätter att inträffa, kan orsaken vara din annonsblockerare. Vänligen kontrollera https://github.com/ajayyy/SponsorBlock/wiki/Fix-Ad-Blocker-Blocking-SponsorBlock's-Requests"
},
"downvoteDescription": {
"message": "Fel timing"
},
"incorrectCategory": {
"message": "Fel kategori"
},
"nonMusicCategoryOnMusic": {
"message": "Den här videon är kategoriserad som musik. Är du säker på att du vill skicka in segment med icke-musikkategorier? Om denna video faktiskt är musik, bör du inte skicka in detta segment. Vänligen läs riktlinjerna om du är förvirrad."
},
"multipleSegments": {
"message": "Flera segment"
},
"guidelines": {
"message": "Riktlinjer"
},
"readTheGuidelines": {
"message": "Läs riktlinjerna!!",
"description": "Show the first time they submit or if they are \"high risk\""
} }
} }

View File

@@ -1,8 +1,4 @@
{ {
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": { "fullName": {
"message": "Youtube için SponsorBlock - Sponsorlukları Atla", "message": "Youtube için SponsorBlock - Sponsorlukları Atla",
"description": "Name of the extension." "description": "Name of the extension."
@@ -221,10 +217,6 @@
"showNotice": { "showNotice": {
"message": "Uyarıyı Tekrar Göster" "message": "Uyarıyı Tekrar Göster"
}, },
"longDescription": {
"message": "SponsorBlock, YouTube'da sponsorlu bölümleri atlamanıza yardımcı olan bir eklentidir. SponsorBlock, herkesin YouTube videolarında bulunan sponsorlu bölümlerin başını ve sonunu göndermesine izin veren kitlekaynaklı bir tarayıcı eklentisidir. Bu bilgiyi biri yolladığında, bu sponsorlu bölüm herkeste atlanır.",
"description": "Full description of the extension on the store pages."
},
"website": { "website": {
"message": "Website", "message": "Website",
"description": "Used on Firefox Store Page" "description": "Used on Firefox Store Page"
@@ -470,9 +462,6 @@
"theKey": { "theKey": {
"message": "Anahtar" "message": "Anahtar"
}, },
"keyAlreadyUsedByYouTube": {
"message": "YouTube tarafından zaten kullanımda. Lütfen başka bir anahtar seçin."
},
"keyAlreadyUsed": { "keyAlreadyUsed": {
"message": "başka bir eyleme bağlı. Lütfen başka bir anahtar seçin." "message": "başka bir eyleme bağlı. Lütfen başka bir anahtar seçin."
}, },
@@ -483,9 +472,6 @@
"category_sponsor": { "category_sponsor": {
"message": "Sponsor" "message": "Sponsor"
}, },
"category_intro": {
"message": "Giriş Animasyonu"
},
"category_outro": { "category_outro": {
"message": "Bitiş Ekranı/Jenerik" "message": "Bitiş Ekranı/Jenerik"
}, },
@@ -510,6 +496,20 @@
"showOverlay": { "showOverlay": {
"message": "Arama Çubuğunda Göster" "message": "Arama Çubuğunda Göster"
}, },
"previewColor": {
"message": "Önizleme Rengi",
"description": "Referring to submissions that have not been sent to the server yet."
},
"seekBarColor": {
"message": "Oynatma Çubuğu Rengi"
},
"category": {
"message": "Kategori"
},
"skipOption": {
"message": "Atlama Seçeneği",
"description": "Used on the options page to describe the ways to skip the segment (auto skip, manual, etc.)"
},
"enableTestingServer": { "enableTestingServer": {
"message": "Beta Deneme Sunucusunu Devreye Sok" "message": "Beta Deneme Sunucusunu Devreye Sok"
}, },
@@ -563,5 +563,15 @@
}, },
"multipleSegments": { "multipleSegments": {
"message": "Birden Çok Bölüm" "message": "Birden Çok Bölüm"
},
"guidelines": {
"message": "Kılavuz"
},
"readTheGuidelines": {
"message": "Kılavuzu Oku!!",
"description": "Show the first time they submit or if they are \"high risk\""
},
"categoryUpdate1": {
"message": "Kategoriler burada!"
} }
} }

View File

@@ -1,8 +1,4 @@
{ {
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": { "fullName": {
"message": "SponsorBlock для YouTube - Пропускайте спонсорські вставки", "message": "SponsorBlock для YouTube - Пропускайте спонсорські вставки",
"description": "Name of the extension." "description": "Name of the extension."
@@ -209,10 +205,6 @@
"showNotice": { "showNotice": {
"message": "Показувати сповіщення знову" "message": "Показувати сповіщення знову"
}, },
"longDescription": {
"message": "SponsorBlock - це розширення, яке пропускає спонсорські вставки в відео на YouTube. SponsorBlock - це краудсорсінгове розширення, яке дозволяє кожному надіслати час початку і кінця спонсорських сегментів в відео на YouTube. Після того, як хто-небудь надсилає цю інформацію, всі інші користувачі розширення будуть автоматично пропускати спонсорські сегменти.",
"description": "Full description of the extension on the store pages."
},
"website": { "website": {
"message": "Сайт", "message": "Сайт",
"description": "Used on Firefox Store Page" "description": "Used on Firefox Store Page"

View File

@@ -1,8 +1,4 @@
{ {
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": { "fullName": {
"message": "SponsorBlock for YouTube - 跳过赞助商广告", "message": "SponsorBlock for YouTube - 跳过赞助商广告",
"description": "Name of the extension." "description": "Name of the extension."
@@ -221,10 +217,6 @@
"showNotice": { "showNotice": {
"message": "重新显示通知" "message": "重新显示通知"
}, },
"longDescription": {
"message": "SponsorBlock 是一个用于跳过 YouTube 视频的赞助商广告片段的扩展。SponsorBlock 是一个众包的浏览器扩展,可以让任何人提交 Youtube 视频的赞助商广告片段的开始和结束时间。一旦有人提交了信息,其他所有使用此扩展的人都能直接跳过赞助商广告片段。",
"description": "Full description of the extension on the store pages."
},
"website": { "website": {
"message": "网站", "message": "网站",
"description": "Used on Firefox Store Page" "description": "Used on Firefox Store Page"
@@ -470,9 +462,6 @@
"theKey": { "theKey": {
"message": "按键" "message": "按键"
}, },
"keyAlreadyUsedByYouTube": {
"message": "已被 Youtube 使用。请选择其他按键。"
},
"keyAlreadyUsed": { "keyAlreadyUsed": {
"message": "已绑定其他操作。请选择其他按键。" "message": "已绑定其他操作。请选择其他按键。"
}, },
@@ -483,24 +472,30 @@
"category_sponsor": { "category_sponsor": {
"message": "赞助商广告" "message": "赞助商广告"
}, },
"category_intro": {
"message": "开头动画"
},
"category_outro": { "category_outro": {
"message": "结束画面/结尾职员表" "message": "结束画面/结尾职员表"
}, },
"category_interaction": { "category_interaction": {
"message": "互动提醒(订阅)" "message": "互动提醒(订阅)"
}, },
"category_interaction_short": {
"message": "互动提醒"
},
"category_selfpromo": { "category_selfpromo": {
"message": "未收钱的/自我推销" "message": "未收钱的/自我推销"
}, },
"category_music_offtopic": { "category_music_offtopic": {
"message": "音乐:非音乐部分" "message": "音乐:非音乐部分"
}, },
"category_music_offtopic_short": {
"message": "无音乐"
},
"category_livestream_messages": { "category_livestream_messages": {
"message": "直播:捐赠/消息阅读" "message": "直播:捐赠/消息阅读"
}, },
"category_livestream_messages_short": {
"message": "阅读消息"
},
"disable": { "disable": {
"message": "禁用" "message": "禁用"
}, },
@@ -510,6 +505,20 @@
"showOverlay": { "showOverlay": {
"message": "在搜索栏中显示" "message": "在搜索栏中显示"
}, },
"previewColor": {
"message": "预览颜色",
"description": "Referring to submissions that have not been sent to the server yet."
},
"seekBarColor": {
"message": "拖动条颜色"
},
"category": {
"message": "类别"
},
"skipOption": {
"message": "跳过选项",
"description": "Used on the options page to describe the ways to skip the segment (auto skip, manual, etc.)"
},
"enableTestingServer": { "enableTestingServer": {
"message": "启用 Beta 测试服务器" "message": "启用 Beta 测试服务器"
}, },
@@ -563,5 +572,18 @@
}, },
"multipleSegments": { "multipleSegments": {
"message": "多个片段" "message": "多个片段"
},
"guidelines": {
"message": "指南"
},
"readTheGuidelines": {
"message": "阅读指南!!",
"description": "Show the first time they submit or if they are \"high risk\""
},
"categoryUpdate1": {
"message": "类别在这里!"
},
"categoryUpdate2": {
"message": "打开选项,跳过开头,结尾,商业等。"
} }
} }

View File

@@ -140,6 +140,7 @@
color: rgb(235, 235, 235); color: rgb(235, 235, 235);
border: none; border: none;
display: inline-block; display: inline-block;
font-size: 13.3333px !important;
cursor: pointer; cursor: pointer;
@@ -179,6 +180,7 @@
.sponsorSkipNoticeCloseButton { .sponsorSkipNoticeCloseButton {
height: 10px; height: 10px;
width: 10px; width: 10px;
box-sizing: unset;
padding: 2px 5px; padding: 2px 5px;

View File

@@ -12,13 +12,13 @@
<body class="sponsorBlockPageBody"> <body class="sponsorBlockPageBody">
<div id="title"> <div id="title" class="titleBar">
<img src="../icons/LogoSponsorBlocker256px.png" height="80" class="profilepic"/> <img src="../icons/LogoSponsorBlocker256px.png" height="80" class="profilepic"/>
SponsorBlock SponsorBlock
</div> </div>
<div class="center"> <div class="center">
<p class="createdBy">__MSG_createdBy__ <a href="https://ajay.app">Ajay Ramachandran</a> <img src="../icons/newprofilepic.jpg" height="30" class="profilepiccircle"/></p> <p class="createdBy titleBar">__MSG_createdBy__ <a href="https://ajay.app">Ajay Ramachandran</a> <img src="../icons/newprofilepic.jpg" height="30" class="profilepiccircle"/></p>
<h1>__MSG_Options__</h1> <h1>__MSG_Options__</h1>
@@ -149,6 +149,40 @@
</label> </label>
</div> </div>
<br/>
<br/>
<div option-type="toggle" sync-option="unsubmittedWarning">
<label class="switch-container" label-name="__MSG_unsubmittedWarning__">
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>
</label>
<br/>
<br/>
<div class="small-description">__MSG_unsubmittedWarningDescription__</div>
</div>
<br/>
<br/>
<div option-type="toggle" sync-option="forceChannelCheck">
<label class="switch-container" label-name="__MSG_forceChannelCheck__">
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>
</label>
<br/>
<br/>
<div class="small-description">__MSG_whatForceChannelCheck__</div>
</div>
<br/> <br/>
<br/> <br/>
@@ -234,6 +268,23 @@
<div class="small-description">__MSG_audioNotificationDescription__</div> <div class="small-description">__MSG_audioNotificationDescription__</div>
</div> </div>
<br/>
<br/>
<div option-type="toggle" sync-option="showTimeWithSkips">
<label class="switch-container" label-name="__MSG_showTimeWithSkips__">
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>
</label>
<br/>
<br/>
<div class="small-description">__MSG_showTimeWithSkipsDescription__</div>
</div>
<br/> <br/>
<br/> <br/>

View File

@@ -10,7 +10,7 @@
<div id="app" class="popupBody sponsorBlockPageBody"> <div id="app" class="popupBody sponsorBlockPageBody">
<h1 class="popupElement logoText"> <h1 class="popupElement logoText">
<img src="icons/IconSponsorBlocker256px.png" height="32px" id="sponsorBlockPopupLogo"/> <img src="icons/IconSponsorBlocker256px.png" height="32px" id="sponsorBlockPopupLogo"/>
__MSG_Name__ SponsorBlock
</h1> </h1>
<!-- Loading text --> <!-- Loading text -->

View File

@@ -40,21 +40,6 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
}); });
}); });
return true;
case "addSponsorTime":
addSponsorTime(request.time, request.videoID, callback);
//this allows the callback to be called later
return true;
case "getSponsorTimes":
getSponsorTimes(request.videoID, function(sponsorTimes) {
callback({
sponsorTimes
});
});
//this allows the callback to be called later
return true; return true;
case "submitVote": case "submitVote":
submitVote(request.type, request.UUID, request.category).then(callback); submitVote(request.type, request.UUID, request.category).then(callback);
@@ -127,38 +112,6 @@ function unregisterFirefoxContentScript(id: string) {
delete contentScriptRegistrations[id]; delete contentScriptRegistrations[id];
} }
//gets the sponsor times from memory
function getSponsorTimes(videoID, callback) {
let sponsorTimes = [];
let sponsorTimesStorage = Config.config.sponsorTimes.get(videoID);
if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
sponsorTimes = sponsorTimesStorage;
}
callback(sponsorTimes);
}
function addSponsorTime(time, videoID, callback) {
getSponsorTimes(videoID, function(sponsorTimes) {
//add to sponsorTimes
if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) {
//it is an end time
sponsorTimes[sponsorTimes.length - 1][1] = time;
} else {
//it is a start time
let sponsorTimesIndex = sponsorTimes.length;
sponsorTimes[sponsorTimesIndex] = [];
sponsorTimes[sponsorTimesIndex][0] = time;
}
//save this info
Config.config.sponsorTimes.set(videoID, sponsorTimes);
callback();
});
}
async function submitVote(type: number, UUID: string, category: string) { async function submitVote(type: number, UUID: string, category: string) {
let userID = Config.config.userID; let userID = Config.config.userID;

View File

@@ -134,13 +134,6 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
this.audio.volume = this.contentContainer().v.volume * 0.1; this.audio.volume = this.contentContainer().v.volume * 0.1;
this.audio.play(); this.audio.play();
} }
if (Config.config.categoryUpdateShowCount < 3 && Config.config.categorySelections.length <= 1) {
this.setNoticeInfoMessageWithOnClick(() => chrome.runtime.sendMessage({"message": "openConfig"})
, chrome.i18n.getMessage("categoryUpdate1"), chrome.i18n.getMessage("categoryUpdate2"));
Config.config.categoryUpdateShowCount = Config.config.categoryUpdateShowCount + 1
}
} }
render() { render() {

View File

@@ -230,7 +230,12 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
} }
getCategoryOptions() { getCategoryOptions() {
let elements = []; let elements = [(
<option value={"chooseACategory"}
key={"chooseACategory"}>
{chrome.i18n.getMessage("chooseACategory")}
</option>
)];
for (const category of Config.config.categorySelections) { for (const category of Config.config.categorySelections) {
elements.push( elements.push(
@@ -322,7 +327,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
sponsorTimesSubmitting[this.props.index].category = this.categoryOptionRef.current.value; sponsorTimesSubmitting[this.props.index].category = this.categoryOptionRef.current.value;
Config.config.sponsorTimes.set(this.props.contentContainer().sponsorVideoID, utils.getSegmentsFromSponsorTimes(sponsorTimesSubmitting)); Config.config.segmentTimes.set(this.props.contentContainer().sponsorVideoID, sponsorTimesSubmitting);
this.props.contentContainer().updatePreviewBar(); this.props.contentContainer().updatePreviewBar();
} }
@@ -354,7 +359,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
sponsorTimes.splice(index, 1); sponsorTimes.splice(index, 1);
//save this //save this
Config.config.sponsorTimes.set(this.props.contentContainer().sponsorVideoID, sponsorTimes); Config.config.segmentTimes.set(this.props.contentContainer().sponsorVideoID, sponsorTimes);
this.props.contentContainer().updatePreviewBar(); this.props.contentContainer().updatePreviewBar();

View File

@@ -167,9 +167,16 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
ref.current.saveEditTimes(); ref.current.saveEditTimes();
} }
let sponsorTimesSubmitting = this.props.contentContainer().sponsorTimesSubmitting;
for (const sponsorTime of sponsorTimesSubmitting) {
if (sponsorTime.category === "chooseACategory") {
alert(chrome.i18n.getMessage("youMustSelectACategory"));
return;
}
}
// Check if any non music categories are being used on a music video // Check if any non music categories are being used on a music video
if (this.contentContainer().videoInfo?.microformat?.playerMicroformatRenderer?.category === "Music") { if (this.contentContainer().videoInfo?.microformat?.playerMicroformatRenderer?.category === "Music") {
let sponsorTimesSubmitting = this.props.contentContainer().sponsorTimesSubmitting;
for (const sponsorTime of sponsorTimesSubmitting) { for (const sponsorTime of sponsorTimesSubmitting) {
if (!sponsorTime.category.startsWith("music_")) { if (!sponsorTime.category.startsWith("music_")) {
if (!confirm(chrome.i18n.getMessage("nonMusicCategoryOnMusic"))) return; if (!confirm(chrome.i18n.getMessage("nonMusicCategoryOnMusic"))) return;

View File

@@ -1,12 +1,14 @@
import * as CompileConfig from "../config.json"; import * as CompileConfig from "../config.json";
import { CategorySelection, CategorySkipOption, PreviewBarOption } from "./types"; import { CategorySelection, CategorySkipOption, PreviewBarOption, SponsorTime } from "./types";
import Utils from "./utils"; import Utils from "./utils";
const utils = new Utils(); const utils = new Utils();
interface SBConfig { interface SBConfig {
userID: string, userID: string,
sponsorTimes: SBMap<string, any>, // sponsorTimes: SBMap<string, SponsorTime[]>,
segmentTimes: SBMap<string, SponsorTime[]>,
defaultCategory: string,
whitelistedChannels: string[], whitelistedChannels: string[],
forceChannelCheck: boolean, forceChannelCheck: boolean,
startSponsorKeybind: string, startSponsorKeybind: string,
@@ -15,6 +17,7 @@ interface SBConfig {
skipCount: number, skipCount: number,
sponsorTimesContributed: number, sponsorTimesContributed: number,
submissionCountSinceCategories: number, // New count used to show the "Read The Guidelines!!" message submissionCountSinceCategories: number, // New count used to show the "Read The Guidelines!!" message
showTimeWithSkips: boolean,
unsubmittedWarning: boolean, unsubmittedWarning: boolean,
disableSkipping: boolean, disableSkipping: boolean,
trackViewCount: boolean, trackViewCount: boolean,
@@ -33,13 +36,12 @@ interface SBConfig {
checkForUnlistedVideos: boolean, checkForUnlistedVideos: boolean,
testingServer: boolean, testingServer: boolean,
categoryUpdateShowCount: number,
// What categories should be skipped // What categories should be skipped
categorySelections: CategorySelection[], categorySelections: CategorySelection[],
// Preview bar // Preview bar
barTypes: { barTypes: {
"preview-chooseACategory": PreviewBarOption,
"sponsor": PreviewBarOption, "sponsor": PreviewBarOption,
"preview-sponsor": PreviewBarOption, "preview-sponsor": PreviewBarOption,
"intro": PreviewBarOption, "intro": PreviewBarOption,
@@ -51,7 +53,7 @@ interface SBConfig {
"selfpromo": PreviewBarOption, "selfpromo": PreviewBarOption,
"preview-selfpromo": PreviewBarOption, "preview-selfpromo": PreviewBarOption,
"music_offtopic": PreviewBarOption, "music_offtopic": PreviewBarOption,
"preview-music_offtopic": PreviewBarOption "preview-music_offtopic": PreviewBarOption,
} }
} }
@@ -84,24 +86,39 @@ class SBMap<T, U> extends Map {
} }
} }
set(key, value) { get(key): U {
const result = super.set(key, value); return super.get(key);
}
rawSet(key, value) {
return super.set(key, value);
}
update() {
// Store updated SBMap locally // Store updated SBMap locally
chrome.storage.sync.set({ chrome.storage.sync.set({
[this.id]: encodeStoredItem(this) [this.id]: encodeStoredItem(this)
}); });
}
set(key: T, value: U) {
const result = super.set(key, value);
this.update();
return result; return result;
} }
delete(key) { delete(key) {
const result = super.delete(key); const result = super.delete(key);
// Store updated SBMap locally // Make sure there are no empty elements
chrome.storage.sync.set({ for (const entry of this.entries()) {
[this.id]: encodeStoredItem(this) if (entry[1].length === 0) {
}); super.delete(entry[0]);
}
}
this.update();
return result; return result;
} }
@@ -109,10 +126,7 @@ class SBMap<T, U> extends Map {
clear() { clear() {
const result = super.clear(); const result = super.clear();
chrome.storage.sync.set({ this.update();
[this.id]: encodeStoredItem(this)
});
return result; return result;
} }
} }
@@ -124,7 +138,8 @@ var Config: SBObject = {
configListeners: [], configListeners: [],
defaults: { defaults: {
userID: null, userID: null,
sponsorTimes: new SBMap("sponsorTimes"), segmentTimes: new SBMap("segmentTimes"),
defaultCategory: "chooseACategory",
whitelistedChannels: [], whitelistedChannels: [],
forceChannelCheck: false, forceChannelCheck: false,
startSponsorKeybind: ";", startSponsorKeybind: ";",
@@ -133,6 +148,7 @@ var Config: SBObject = {
skipCount: 0, skipCount: 0,
sponsorTimesContributed: 0, sponsorTimesContributed: 0,
submissionCountSinceCategories: 0, submissionCountSinceCategories: 0,
showTimeWithSkips: true,
unsubmittedWarning: true, unsubmittedWarning: true,
disableSkipping: false, disableSkipping: false,
trackViewCount: true, trackViewCount: true,
@@ -151,8 +167,6 @@ var Config: SBObject = {
checkForUnlistedVideos: false, checkForUnlistedVideos: false,
testingServer: false, testingServer: false,
categoryUpdateShowCount: 0,
categorySelections: [{ categorySelections: [{
name: "sponsor", name: "sponsor",
option: CategorySkipOption.AutoSkip option: CategorySkipOption.AutoSkip
@@ -160,6 +174,10 @@ var Config: SBObject = {
// Preview bar // Preview bar
barTypes: { barTypes: {
"preview-chooseACategory": {
color: "#ffffff",
opacity: "0.7"
},
"sponsor": { "sponsor": {
color: "#00d400", color: "#00d400",
opacity: "0.7" opacity: "0.7"
@@ -238,24 +256,13 @@ function encodeStoredItem<T>(data: T): T | Array<any> {
* *
* @param {*} data * @param {*} data
*/ */
function decodeStoredItem<T>(id: string, data: T): T | SBMap<string, any> { function decodeStoredItem<T>(id: string, data: T): T | SBMap<string, SponsorTime[]> {
if (!Config.defaults[id]) return data; if (!Config.defaults[id]) return data;
if (Config.defaults[id] instanceof SBMap) { if (Config.defaults[id] instanceof SBMap) {
try { try {
let jsonData: any = data; if (!Array.isArray(data)) return data;
return new SBMap(id, data);
// Check if data is stored in the old format for SBMap (a JSON string)
if (typeof data === "string") {
try {
jsonData = JSON.parse(data);
} catch(e) {
// Continue normally (out of this if statement)
}
}
if (!Array.isArray(jsonData)) return data;
return new SBMap(id, jsonData);
} catch(e) { } catch(e) {
console.error("Failed to parse SBMap: " + id); console.error("Failed to parse SBMap: " + id);
} }
@@ -313,9 +320,9 @@ function fetchConfig() {
}); });
} }
async function migrateOldFormats() { function migrateOldFormats(config: SBConfig) {
if (Config.config["disableAutoSkip"]) { if (config["disableAutoSkip"]) {
for (const selection of Config.config.categorySelections) { for (const selection of config.categorySelections) {
if (selection.name === "sponsor") { if (selection.name === "sponsor") {
selection.option = CategorySkipOption.ManualSkip; selection.option = CategorySkipOption.ManualSkip;
@@ -325,62 +332,108 @@ async function migrateOldFormats() {
} }
// Auto vote removal // Auto vote removal
if (Config.config["autoUpvote"]) { if (config["autoUpvote"]) {
chrome.storage.sync.remove("autoUpvote"); chrome.storage.sync.remove("autoUpvote");
} }
// mobileUpdateShowCount removal // mobileUpdateShowCount removal
if (Config.config["mobileUpdateShowCount"] !== undefined) { if (config["mobileUpdateShowCount"] !== undefined) {
chrome.storage.sync.remove("mobileUpdateShowCount"); chrome.storage.sync.remove("mobileUpdateShowCount");
} }
// categoryUpdateShowCount removal
if (config["categoryUpdateShowCount"] !== undefined) {
chrome.storage.sync.remove("categoryUpdateShowCount");
}
// Channel URLS // Channel URLS
if (Config.config.whitelistedChannels.length > 0 && if (config.whitelistedChannels.length > 0 &&
(Config.config.whitelistedChannels[0] == null || Config.config.whitelistedChannels[0].includes("/"))) { (config.whitelistedChannels[0] == null || config.whitelistedChannels[0].includes("/"))) {
let newChannelList: string[] = []; const channelURLFixer = async() => {
for (const item of Config.config.whitelistedChannels) { let newChannelList: string[] = [];
if (item != null) { for (const item of config.whitelistedChannels) {
if (item.includes("/channel/")) { if (item != null) {
newChannelList.push(item.split("/")[2]); if (item.includes("/channel/")) {
} else if (item.includes("/user/") && utils.isContentScript()) { newChannelList.push(item.split("/")[2]);
// Replace channel URL with channelID } else if (item.includes("/user/") && utils.isContentScript()) {
let response = await utils.asyncRequestToCustomServer("GET", "https://sponsor.ajay.app/invidious/api/v1/channels/" + item.split("/")[2] + "?fields=authorId");
if (response.ok) { // Replace channel URL with channelID
newChannelList.push((JSON.parse(response.responseText)).authorId); let response = await utils.asyncRequestToCustomServer("GET", "https://sponsor.ajay.app/invidious/api/v1/channels/" + item.split("/")[2] + "?fields=authorId");
} else {
// Add it at the beginning so it gets converted later if (response.ok) {
newChannelList.push((JSON.parse(response.responseText)).authorId);
} else {
// Add it at the beginning so it gets converted later
newChannelList.unshift(item);
}
} else if (item.includes("/user/")) {
// Add it at the beginning so it gets converted later (The API can only be called in the content script due to CORS issues)
newChannelList.unshift(item); newChannelList.unshift(item);
} else {
newChannelList.push(item);
} }
} else if (item.includes("/user/")) {
// Add it at the beginning so it gets converted later (The API can only be called in the content script due to CORS issues)
newChannelList.unshift(item);
} else {
newChannelList.push(item);
} }
} }
config.whitelistedChannels = newChannelList;
} }
Config.config.whitelistedChannels = newChannelList; channelURLFixer();
} }
// Check if off-topic category needs to be removed // Check if off-topic category needs to be removed
for (let i = 0; i < Config.config.categorySelections.length; i++) { for (let i = 0; i < config.categorySelections.length; i++) {
if (Config.config.categorySelections[i].name === "offtopic") { if (config.categorySelections[i].name === "offtopic") {
Config.config.categorySelections.splice(i, 1); config.categorySelections.splice(i, 1);
// Call set listener // Call set listener
Config.config.categorySelections = Config.config.categorySelections; config.categorySelections = config.categorySelections;
break; break;
} }
} }
// Migrate old "sponsorTimes"
if (config["sponsorTimes"]) {
let jsonData: any = config["sponsorTimes"];
// Check if data is stored in the old format for SBMap (a JSON string)
if (typeof jsonData === "string") {
try {
jsonData = JSON.parse(jsonData);
} catch(e) {
// Continue normally (out of this if statement)
}
}
// Otherwise junk data
if (Array.isArray(jsonData)) {
let oldMap = new Map(jsonData);
oldMap.forEach((sponsorTimes: number[][], key) => {
let segmentTimes: SponsorTime[] = [];
for (const segment of sponsorTimes) {
segmentTimes.push({
segment: segment,
category: "sponsor",
UUID: null
});
}
config.segmentTimes.rawSet(key, segmentTimes);
});
config.segmentTimes.update();
}
chrome.storage.sync.remove("sponsorTimes");
}
} }
async function setupConfig() { async function setupConfig() {
await fetchConfig(); await fetchConfig();
addDefaults(); addDefaults();
convertJSON(); convertJSON();
Config.config = configProxy(); const config = configProxy();
migrateOldFormats(); migrateOldFormats(config);
Config.config = config;
} }
// Reset config // Reset config
@@ -399,6 +452,12 @@ function addDefaults() {
for (const key in Config.defaults) { for (const key in Config.defaults) {
if(!Config.localConfig.hasOwnProperty(key)) { if(!Config.localConfig.hasOwnProperty(key)) {
Config.localConfig[key] = Config.defaults[key]; Config.localConfig[key] = Config.defaults[key];
} else if (key === "barTypes") {
for (const key2 in Config.defaults[key]) {
if(!Config.localConfig[key].hasOwnProperty(key2)) {
Config.localConfig[key][key2] = Config.defaults[key][key2];
}
}
} }
} }
}; };
@@ -406,4 +465,4 @@ function addDefaults() {
// Sync config // Sync config
setupConfig(); setupConfig();
export default Config; export default Config;

View File

@@ -323,13 +323,13 @@ async function videoIDChange(id) {
//warn them if they had unsubmitted times //warn them if they had unsubmitted times
if (previousVideoID != null) { if (previousVideoID != null) {
//get the sponsor times from storage //get the sponsor times from storage
let sponsorTimes = Config.config.sponsorTimes.get(previousVideoID); let sponsorTimes = Config.config.segmentTimes.get(previousVideoID);
if (sponsorTimes != undefined && sponsorTimes.length > 0) { if (sponsorTimes != undefined && sponsorTimes.length > 0) {
//warn them that they have unsubmitted sponsor times //warn them that they have unsubmitted sponsor times
chrome.runtime.sendMessage({ chrome.runtime.sendMessage({
message: "alertPrevious", message: "alertPrevious",
previousVideoID: previousVideoID previousVideoID: previousVideoID
}) });
} }
//set the previous video id to the currentID //set the previous video id to the currentID
@@ -347,10 +347,10 @@ async function videoIDChange(id) {
//make sure everything is properly added //make sure everything is properly added
updateVisibilityOfPlayerControlsButton().then(() => { updateVisibilityOfPlayerControlsButton().then(() => {
//see if the onvideo control image needs to be changed //see if the onvideo control image needs to be changed
let segments = Config.config.sponsorTimes.get(sponsorVideoID); let segments = Config.config.segmentTimes.get(sponsorVideoID);
if (segments != null && segments.length > 0 && segments[segments.length - 1].length >= 2) { if (segments != null && segments.length > 0 && segments[segments.length - 1].segment.length >= 2) {
changeStartSponsorButton(true, true); changeStartSponsorButton(true, true);
} else if (segments != null && segments.length > 0 && segments[segments.length - 1].length < 2) { } else if (segments != null && segments.length > 0 && segments[segments.length - 1].segment.length < 2) {
changeStartSponsorButton(false, true); changeStartSponsorButton(false, true);
} else { } else {
changeStartSponsorButton(true, false); changeStartSponsorButton(true, false);
@@ -418,7 +418,7 @@ function createPreviewBar(): void {
const el = document.querySelectorAll(selector); const el = document.querySelectorAll(selector);
if (el && el.length && el[0]) { if (el && el.length && el[0]) {
previewBar = new PreviewBar(el[0], onMobileYouTube); previewBar = new PreviewBar(el[0], onMobileYouTube, onInvidious);
updatePreviewBar(); updatePreviewBar();
@@ -801,7 +801,7 @@ function updatePreviewBar() {
if (localSponsorTimes == null) localSponsorTimes = []; if (localSponsorTimes == null) localSponsorTimes = [];
let allSponsorTimes = localSponsorTimes.concat(sponsorTimesSubmitting); let allSponsorTimes = localSponsorTimes.concat(sponsorTimesSubmitting);
//create an array of the sponsor types //create an array of the sponsor types
let types = []; let types = [];
for (let i = 0; i < localSponsorTimes.length; i++) { for (let i = 0; i < localSponsorTimes.length; i++) {
@@ -818,6 +818,10 @@ function updatePreviewBar() {
previewBar.set(utils.getSegmentsFromSponsorTimes(allSponsorTimes), types, video.duration) previewBar.set(utils.getSegmentsFromSponsorTimes(allSponsorTimes), types, video.duration)
if (Config.config.showTimeWithSkips) {
showTimeWithoutSkips(allSponsorTimes);
}
//update last video id //update last video id
lastPreviewBarUpdate = sponsorVideoID; lastPreviewBarUpdate = sponsorVideoID;
} }
@@ -1007,8 +1011,6 @@ function unskipSponsorTime(segment: SponsorTime) {
if (sponsorTimes != null) { if (sponsorTimes != null) {
//add a tiny bit of time to make sure it is not skipped again //add a tiny bit of time to make sure it is not skipped again
video.currentTime = segment.segment[0] + 0.001; video.currentTime = segment.segment[0] + 0.001;
checkIfInsideSegment();
} }
} }
@@ -1016,16 +1018,6 @@ function reskipSponsorTime(segment: SponsorTime) {
video.currentTime = segment.segment[1]; video.currentTime = segment.segment[1];
} }
/**
* Checks if currently inside a segment and will trigger
* a skip schedule if true.
*
* This is used for when a manual skip is finished or a reskip is complete
*/
function checkIfInsideSegment() {
// for
}
function createButton(baseID, title, callback, imageName, isDraggable=false): boolean { function createButton(baseID, title, callback, imageName, isDraggable=false): boolean {
if (document.getElementById(baseID + "Button") != null) return false; if (document.getElementById(baseID + "Button") != null) return false;
@@ -1034,18 +1026,10 @@ function createButton(baseID, title, callback, imageName, isDraggable=false): bo
newButton.draggable = isDraggable; newButton.draggable = isDraggable;
newButton.id = baseID + "Button"; newButton.id = baseID + "Button";
newButton.classList.add("playerButton"); newButton.classList.add("playerButton");
if (!onMobileYouTube) { newButton.classList.add("ytp-button");
newButton.classList.add("ytp-button");
} else {
newButton.classList.add("icon-button");
newButton.style.padding = "0";
}
newButton.setAttribute("title", chrome.i18n.getMessage(title)); newButton.setAttribute("title", chrome.i18n.getMessage(title));
newButton.addEventListener("click", (event: Event) => { newButton.addEventListener("click", (event: Event) => {
callback(); callback();
// Prevents the contols from closing when clicked
if (onMobileYouTube) event.stopPropagation();
}); });
// Image HTML // Image HTML
@@ -1087,6 +1071,8 @@ function getControls(): HTMLElement | boolean {
//adds all the player controls buttons //adds all the player controls buttons
async function createButtons(): Promise<boolean> { async function createButtons(): Promise<boolean> {
if (onMobileYouTube) return;
let result = await utils.wait(getControls).catch(); let result = await utils.wait(getControls).catch();
//set global controls variable //set global controls variable
@@ -1164,36 +1150,28 @@ function startSponsorClicked() {
sponsorTimesSubmitting.push({ sponsorTimesSubmitting.push({
segment: [getRealCurrentTime()], segment: [getRealCurrentTime()],
UUID: null, UUID: null,
// Default to sponsor category: Config.config.defaultCategory
category: "sponsor"
}); });
} }
// Create raw segment list
let segments: number[][] = [];
for (const sponsorTime of sponsorTimesSubmitting) {
segments.push(sponsorTime.segment);
}
//save this info //save this info
Config.config.sponsorTimes.set(sponsorVideoID, segments); Config.config.segmentTimes.set(sponsorVideoID, sponsorTimesSubmitting);
updateSponsorTimesSubmitting(false) updateSponsorTimesSubmitting(false)
} }
function updateSponsorTimesSubmitting(getFromConfig: boolean = true) { function updateSponsorTimesSubmitting(getFromConfig: boolean = true) {
let segments = Config.config.sponsorTimes.get(sponsorVideoID); let segmentTimes = Config.config.segmentTimes.get(sponsorVideoID);
//see if this data should be saved in the sponsorTimesSubmitting variable //see if this data should be saved in the sponsorTimesSubmitting variable
if (getFromConfig && segments != undefined) { if (getFromConfig && segmentTimes != undefined) {
sponsorTimesSubmitting = []; sponsorTimesSubmitting = [];
for (const segment of segments) { for (const segmentTime of segmentTimes) {
sponsorTimesSubmitting.push({ sponsorTimesSubmitting.push({
segment: segment, segment: segmentTime.segment,
UUID: null, UUID: null,
// Default to sponsor category: segmentTime.category
category: "sponsor"
}); });
} }
} }
@@ -1220,9 +1198,9 @@ async function changeStartSponsorButton(showStartSponsor, uploadButtonVisible) {
(<HTMLImageElement> document.getElementById("startSponsorImage")).src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png"); (<HTMLImageElement> document.getElementById("startSponsorImage")).src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png");
document.getElementById("startSponsorButton").setAttribute("title", chrome.i18n.getMessage("sponsorStart")); document.getElementById("startSponsorButton").setAttribute("title", chrome.i18n.getMessage("sponsorStart"));
if (document.getElementById("startSponsorImage").style.display != "none" && uploadButtonVisible && !Config.config.hideUploadButtonPlayerControls) { if (document.getElementById("startSponsorImage").style.display != "none" && uploadButtonVisible && !Config.config.hideUploadButtonPlayerControls && !onInvidious) {
document.getElementById("submitButton").style.display = "unset"; document.getElementById("submitButton").style.display = "unset";
} else if (!uploadButtonVisible) { } else if (!uploadButtonVisible || onInvidious) {
//disable submit button //disable submit button
document.getElementById("submitButton").style.display = "none"; document.getElementById("submitButton").style.display = "none";
} }
@@ -1317,7 +1295,7 @@ function clearSponsorTimes() {
let currentVideoID = sponsorVideoID; let currentVideoID = sponsorVideoID;
let sponsorTimes = Config.config.sponsorTimes.get(currentVideoID); let sponsorTimes = Config.config.segmentTimes.get(currentVideoID);
if (sponsorTimes != undefined && sponsorTimes.length > 0) { if (sponsorTimes != undefined && sponsorTimes.length > 0) {
let confirmMessage = chrome.i18n.getMessage("clearThis") + getSegmentsMessage(sponsorTimes) let confirmMessage = chrome.i18n.getMessage("clearThis") + getSegmentsMessage(sponsorTimes)
@@ -1325,7 +1303,7 @@ function clearSponsorTimes() {
if(!confirm(confirmMessage)) return; if(!confirm(confirmMessage)) return;
//clear the sponsor times //clear the sponsor times
Config.config.sponsorTimes.delete(currentVideoID); Config.config.segmentTimes.delete(currentVideoID);
//clear sponsor times submitting //clear sponsor times submitting
sponsorTimesSubmitting = []; sponsorTimesSubmitting = [];
@@ -1447,14 +1425,14 @@ async function sendSubmitMessage(){
} }
//update sponsorTimes //update sponsorTimes
Config.config.sponsorTimes.set(sponsorVideoID, utils.getSegmentsFromSponsorTimes(sponsorTimesSubmitting)); Config.config.segmentTimes.set(sponsorVideoID, sponsorTimesSubmitting);
// Check to see if any of the submissions are below the minimum duration set // Check to see if any of the submissions are below the minimum duration set
if (Config.config.minDuration > 0) { if (Config.config.minDuration > 0) {
for (let i = 0; i < sponsorTimesSubmitting.length; i++) { for (let i = 0; i < sponsorTimesSubmitting.length; i++) {
if (sponsorTimesSubmitting[i].segment[1] - sponsorTimesSubmitting[i].segment[0] < Config.config.minDuration) { if (sponsorTimesSubmitting[i].segment[1] - sponsorTimesSubmitting[i].segment[0] < Config.config.minDuration) {
let confirmShort = chrome.i18n.getMessage("shortCheck") + "\n\n" + let confirmShort = chrome.i18n.getMessage("shortCheck") + "\n\n" +
getSegmentsMessage(utils.getSegmentsFromSponsorTimes(sponsorTimesSubmitting)); getSegmentsMessage(sponsorTimesSubmitting);
if(!confirm(confirmShort)) return; if(!confirm(confirmShort)) return;
} }
@@ -1484,7 +1462,7 @@ async function sendSubmitMessage(){
submitButton.addEventListener("animationend", animationEndListener); submitButton.addEventListener("animationend", animationEndListener);
//clear the sponsor times //clear the sponsor times
Config.config.sponsorTimes.delete(sponsorVideoID); Config.config.segmentTimes.delete(sponsorVideoID);
//add submissions to current sponsors list //add submissions to current sponsors list
if (sponsorTimes === null) sponsorTimes = []; if (sponsorTimes === null) sponsorTimes = [];
@@ -1512,12 +1490,12 @@ async function sendSubmitMessage(){
} }
//get the message that visually displays the video times //get the message that visually displays the video times
function getSegmentsMessage(segments: number[][]): string { function getSegmentsMessage(sponsorTimes: SponsorTime[]): string {
let sponsorTimesMessage = ""; let sponsorTimesMessage = "";
for (let i = 0; i < segments.length; i++) { for (let i = 0; i < sponsorTimes.length; i++) {
for (let s = 0; s < segments[i].length; s++) { for (let s = 0; s < sponsorTimes[i].segment.length; s++) {
let timeMessage = utils.getFormattedTime(segments[i][s]); let timeMessage = utils.getFormattedTime(sponsorTimes[i].segment[s]);
//if this is an end time //if this is an end time
if (s == 1) { if (s == 1) {
timeMessage = " to " + timeMessage; timeMessage = " to " + timeMessage;
@@ -1593,3 +1571,38 @@ function updateAdFlag() {
updateVisibilityOfPlayerControlsButton(); updateVisibilityOfPlayerControlsButton();
} }
} }
function showTimeWithoutSkips(allSponsorTimes): void {
if (onMobileYouTube || onInvidious) return;
let skipDuration = 0;
// Calculate skipDuration based from the segments in the preview bar
for (let i = 0; i < allSponsorTimes.length; i++) {
// If an end time exists
if (allSponsorTimes[i].segment[1]) {
skipDuration += allSponsorTimes[i].segment[1] - allSponsorTimes[i].segment[0];
}
}
// YouTube player time display
let display = document.getElementsByClassName("ytp-time-display notranslate")[0];
if (!display) return;
let formatedTime = utils.getFormattedTime(video.duration - skipDuration);
const durationID = "sponsorBlockDurationAfterSkips";
let duration = document.getElementById(durationID);
// Create span if needed
if(duration === null) {
duration = document.createElement('span');
duration.id = durationID;
duration.classList.add("ytp-time-duration");
display.appendChild(duration);
}
duration.innerText = (skipDuration <= 0 || isNaN(skipDuration)) ? "" : " ("+formatedTime+")";
}

View File

@@ -6,21 +6,25 @@
'use strict'; 'use strict';
import Config from "../config"; import Config from "../config";
import Utils from "../utils";
let utils = new Utils();
class PreviewBar { class PreviewBar {
container: HTMLUListElement; container: HTMLUListElement;
parent: any; parent: any;
onMobileYouTube: boolean; onMobileYouTube: boolean;
onInvidious: boolean;
timestamps: number[][]; timestamps: number[][];
types: string; types: string;
constructor(parent, onMobileYouTube) { constructor(parent, onMobileYouTube, onInvidious) {
this.container = document.createElement('ul'); this.container = document.createElement('ul');
this.container.id = 'previewbar'; this.container.id = 'previewbar';
this.parent = parent; this.parent = parent;
this.onMobileYouTube = onMobileYouTube; this.onMobileYouTube = onMobileYouTube;
this.onInvidious = onInvidious;
this.updatePosition(parent); this.updatePosition(parent);
@@ -28,6 +32,8 @@ class PreviewBar {
} }
setupHoverText() { setupHoverText() {
if (this.onMobileYouTube || this.onInvidious) return;
let seekBar = document.querySelector(".ytp-progress-bar-container"); let seekBar = document.querySelector(".ytp-progress-bar-container");
// Create label placeholder // Create label placeholder
@@ -79,8 +85,8 @@ class PreviewBar {
tooltipTextWrapper.classList.remove("sbTooltipOneTitleThumbnailOffset"); tooltipTextWrapper.classList.remove("sbTooltipOneTitleThumbnailOffset");
} else if (category !== null) { } else if (category !== null) {
categoryTooltip.classList.remove("sbHidden"); categoryTooltip.classList.remove("sbHidden");
categoryTooltip.textContent = chrome.i18n.getMessage("category_" + category) categoryTooltip.textContent = utils.shortCategoryName(category)
|| (chrome.i18n.getMessage("preview") + " " + chrome.i18n.getMessage("category_" + category.split("preview-")[1])); || (chrome.i18n.getMessage("preview") + " " + utils.shortCategoryName(category.split("preview-")[1]));
// There is a title now // There is a title now
tooltip.classList.remove("ytp-tooltip-text-no-title"); tooltip.classList.remove("ytp-tooltip-text-no-title");

View File

@@ -237,7 +237,7 @@ function invidiousInstanceAddInit(element: HTMLElement, option: string) {
let setButton = element.querySelector(".text-change-set"); let setButton = element.querySelector(".text-change-set");
setButton.addEventListener("click", async function(e) { setButton.addEventListener("click", async function(e) {
if (textBox.value == "" || textBox.value.includes("/") || textBox.value.includes("http") || textBox.value.includes(":")) { if (textBox.value == "" || textBox.value.includes("/") || textBox.value.includes("http")) {
alert(chrome.i18n.getMessage("addInvidiousInstanceError")); alert(chrome.i18n.getMessage("addInvidiousInstanceError"));
} else { } else {
// Add this // Add this
@@ -298,19 +298,23 @@ function invidiousInit(checkbox: HTMLInputElement, option: string) {
* @param checkbox * @param checkbox
* @param option * @param option
*/ */
function invidiousOnClick(checkbox: HTMLInputElement, option: string) { async function invidiousOnClick(checkbox: HTMLInputElement, option: string) {
if (checkbox.checked) { return new Promise((resolve) => {
utils.setupExtraSitePermissions(function (granted) { if (checkbox.checked) {
if (!granted) { utils.setupExtraSitePermissions(function (granted) {
Config.config[option] = false; if (!granted) {
checkbox.checked = false; Config.config[option] = false;
} else { checkbox.checked = false;
checkbox.checked = true; } else {
} checkbox.checked = true;
}); }
} else {
utils.removeExtraSiteRegistration(); resolve();
} });
} else {
utils.removeExtraSiteRegistration();
}
});
} }
/** /**
@@ -358,15 +362,6 @@ function keybindKeyPressed(element: HTMLElement, e: KeyboardEvent) {
let button: HTMLElement = element.querySelector(".trigger-button"); let button: HTMLElement = element.querySelector(".trigger-button");
let option = element.getAttribute("sync-option"); let option = element.getAttribute("sync-option");
// Don't allow keys which are already listened for by youtube
let restrictedKeys = "1234567890,.jklftcibmJKLFTCIBMNP/<> -+";
if (restrictedKeys.indexOf(key) !== -1 ) {
closeKeybindOption(element, button);
alert(chrome.i18n.getMessage("theKey") + " " + key + " " + chrome.i18n.getMessage("keyAlreadyUsedByYouTube"));
return;
}
// Make sure keybind isn't used by the other listener // Make sure keybind isn't used by the other listener
// TODO: If other keybindings are going to be added, we need a better way to find the other keys used. // TODO: If other keybindings are going to be added, we need a better way to find the other keys used.
let otherKeybind = (option === "startSponsorKeybind") ? Config.config['submitKeybind'] : Config.config['startSponsorKeybind']; let otherKeybind = (option === "startSponsorKeybind") ? Config.config['submitKeybind'] : Config.config['startSponsorKeybind'];
@@ -435,8 +430,8 @@ function activatePrivateTextChange(element: HTMLElement) {
case "*": case "*":
let jsonData = JSON.parse(JSON.stringify(Config.localConfig)); let jsonData = JSON.parse(JSON.stringify(Config.localConfig));
// Fix sponsorTimes data as it is destroyed from the JSON stringify // Fix segmentTimes data as it is destroyed from the JSON stringify
jsonData.sponsorTimes = Config.encodeStoredItem(Config.localConfig.sponsorTimes); jsonData.segmentTimes = Config.encodeStoredItem(Config.localConfig.segmentTimes);
result = JSON.stringify(jsonData); result = JSON.stringify(jsonData);
break; break;
@@ -445,7 +440,7 @@ function activatePrivateTextChange(element: HTMLElement) {
textBox.value = result; textBox.value = result;
let setButton = element.querySelector(".text-change-set"); let setButton = element.querySelector(".text-change-set");
setButton.addEventListener("click", () => { setButton.addEventListener("click", async () => {
let confirmMessage = element.getAttribute("confirm-message"); let confirmMessage = element.getAttribute("confirm-message");
if (confirmMessage === null || confirm(chrome.i18n.getMessage(confirmMessage))) { if (confirmMessage === null || confirm(chrome.i18n.getMessage(confirmMessage))) {
@@ -460,15 +455,14 @@ function activatePrivateTextChange(element: HTMLElement) {
} }
Config.convertJSON(); Config.convertJSON();
// Reload options on page
init();
if (newConfig.supportInvidious) { if (newConfig.supportInvidious) {
let checkbox = <HTMLInputElement> document.querySelector("#support-invidious > label > label > input"); let checkbox = <HTMLInputElement> document.querySelector("#support-invidious > label > label > input");
checkbox.checked = true; checkbox.checked = true;
invidiousOnClick(checkbox, "supportInvidious"); await invidiousOnClick(checkbox, "supportInvidious");
} }
window.location.reload();
} catch (e) { } catch (e) {
alert(chrome.i18n.getMessage("incorrectlyFormattedOptions")); alert(chrome.i18n.getMessage("incorrectlyFormattedOptions"));
@@ -519,8 +513,8 @@ function copyDebugOutputToClipboard() {
config: JSON.parse(JSON.stringify(Config.localConfig)) // Deep clone config object config: JSON.parse(JSON.stringify(Config.localConfig)) // Deep clone config object
}; };
// Fix sponsorTimes data as it is destroyed from the JSON stringify // Fix segmentTimes data as it is destroyed from the JSON stringify
output.config.sponsorTimes = Config.encodeStoredItem(Config.localConfig.sponsorTimes); output.config.segmentTimes = Config.encodeStoredItem(Config.localConfig.segmentTimes);
// Sanitise sensitive user config values // Sanitise sensitive user config values
delete output.config.userID; delete output.config.userID;

View File

@@ -119,7 +119,7 @@ async function runThePopup(messageListener?: MessageListener) {
let startTimeChosen = false; let startTimeChosen = false;
//the start and end time pairs (2d) //the start and end time pairs (2d)
let sponsorTimes = []; let sponsorTimes: SponsorTime[] = [];
//current video ID of this tab //current video ID of this tab
let currentVideoID = null; let currentVideoID = null;
@@ -252,9 +252,9 @@ async function runThePopup(messageListener?: MessageListener) {
} }
//load video times for this video //load video times for this video
let sponsorTimesStorage = Config.config.sponsorTimes.get(currentVideoID); let sponsorTimesStorage = Config.config.segmentTimes.get(currentVideoID);
if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) { if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
if (sponsorTimesStorage[sponsorTimesStorage.length - 1] != undefined && sponsorTimesStorage[sponsorTimesStorage.length - 1].length < 2) { if (sponsorTimesStorage[sponsorTimesStorage.length - 1] != undefined && sponsorTimesStorage[sponsorTimesStorage.length - 1].segment.length < 2) {
startTimeChosen = true; startTimeChosen = true;
PageElements.sponsorStart.innerHTML = chrome.i18n.getMessage("sponsorEnd"); PageElements.sponsorStart.innerHTML = chrome.i18n.getMessage("sponsorEnd");
} }
@@ -336,13 +336,17 @@ async function runThePopup(messageListener?: MessageListener) {
let sponsorTimesIndex = sponsorTimes.length - (startTimeChosen ? 1 : 0); let sponsorTimesIndex = sponsorTimes.length - (startTimeChosen ? 1 : 0);
if (sponsorTimes[sponsorTimesIndex] == undefined) { if (sponsorTimes[sponsorTimesIndex] == undefined) {
sponsorTimes[sponsorTimesIndex] = []; sponsorTimes[sponsorTimesIndex] = {
segment: [],
category: Config.config.defaultCategory,
UUID: null
};
} }
sponsorTimes[sponsorTimesIndex][startTimeChosen ? 1 : 0] = response.time; sponsorTimes[sponsorTimesIndex].segment[startTimeChosen ? 1 : 0] = response.time;
let localStartTimeChosen = startTimeChosen; let localStartTimeChosen = startTimeChosen;
Config.config.sponsorTimes.set(currentVideoID, sponsorTimes); Config.config.segmentTimes.set(currentVideoID, sponsorTimes);
//send a message to the client script //send a message to the client script
if (localStartTimeChosen) { if (localStartTimeChosen) {
@@ -528,7 +532,7 @@ async function runThePopup(messageListener?: MessageListener) {
} }
function previewSponsorTime(index) { function previewSponsorTime(index) {
let skipTime = sponsorTimes[index][0]; let skipTime = sponsorTimes[index].segment[0];
if (document.getElementById("startTimeMinutes" + index) != null) { if (document.getElementById("startTimeMinutes" + index) != null) {
//edit is currently open, use that time //edit is currently open, use that time
@@ -575,28 +579,28 @@ async function runThePopup(messageListener?: MessageListener) {
startTimeMinutes.id = "startTimeMinutes" + index; startTimeMinutes.id = "startTimeMinutes" + index;
startTimeMinutes.className = "sponsorTime popupElement"; startTimeMinutes.className = "sponsorTime popupElement";
startTimeMinutes.type = "text"; startTimeMinutes.type = "text";
startTimeMinutes.value = String(getTimeInMinutes(sponsorTimes[index][0])); startTimeMinutes.value = String(getTimeInMinutes(sponsorTimes[index].segment[0]));
startTimeMinutes.style.width = "45px"; startTimeMinutes.style.width = "45px";
let startTimeSeconds = document.createElement("input"); let startTimeSeconds = document.createElement("input");
startTimeSeconds.id = "startTimeSeconds" + index; startTimeSeconds.id = "startTimeSeconds" + index;
startTimeSeconds.className = "sponsorTime popupElement"; startTimeSeconds.className = "sponsorTime popupElement";
startTimeSeconds.type = "text"; startTimeSeconds.type = "text";
startTimeSeconds.value = getTimeInFormattedSeconds(sponsorTimes[index][0]); startTimeSeconds.value = getTimeInFormattedSeconds(sponsorTimes[index].segment[0]);
startTimeSeconds.style.width = "60px"; startTimeSeconds.style.width = "60px";
let endTimeMinutes = document.createElement("input"); let endTimeMinutes = document.createElement("input");
endTimeMinutes.id = "endTimeMinutes" + index; endTimeMinutes.id = "endTimeMinutes" + index;
endTimeMinutes.className = "sponsorTime popupElement"; endTimeMinutes.className = "sponsorTime popupElement";
endTimeMinutes.type = "text"; endTimeMinutes.type = "text";
endTimeMinutes.value = String(getTimeInMinutes(sponsorTimes[index][1])); endTimeMinutes.value = String(getTimeInMinutes(sponsorTimes[index].segment[1]));
endTimeMinutes.style.width = "45px"; endTimeMinutes.style.width = "45px";
let endTimeSeconds = document.createElement("input"); let endTimeSeconds = document.createElement("input");
endTimeSeconds.id = "endTimeSeconds" + index; endTimeSeconds.id = "endTimeSeconds" + index;
endTimeSeconds.className = "sponsorTime popupElement"; endTimeSeconds.className = "sponsorTime popupElement";
endTimeSeconds.type = "text"; endTimeSeconds.type = "text";
endTimeSeconds.value = getTimeInFormattedSeconds(sponsorTimes[index][1]); endTimeSeconds.value = getTimeInFormattedSeconds(sponsorTimes[index].segment[1]);
endTimeSeconds.style.width = "60px"; endTimeSeconds.style.width = "60px";
//the button to set the current time //the button to set the current time
@@ -668,11 +672,11 @@ async function runThePopup(messageListener?: MessageListener) {
} }
function saveSponsorTimeEdit(index, closeEditMode = true) { function saveSponsorTimeEdit(index, closeEditMode = true) {
sponsorTimes[index][0] = getSponsorTimeEditTimes("startTime", index); sponsorTimes[index].segment[0] = getSponsorTimeEditTimes("startTime", index);
sponsorTimes[index][1] = getSponsorTimeEditTimes("endTime", index); sponsorTimes[index].segment[1] = getSponsorTimeEditTimes("endTime", index);
//save this //save this
Config.config.sponsorTimes.set(currentVideoID, sponsorTimes); Config.config.segmentTimes.set(currentVideoID, sponsorTimes);
messageHandler.query({ messageHandler.query({
active: true, active: true,
@@ -692,7 +696,7 @@ async function runThePopup(messageListener?: MessageListener) {
//deletes the sponsor time submitted at an index //deletes the sponsor time submitted at an index
function deleteSponsorTime(index) { function deleteSponsorTime(index) {
//if it is not a complete sponsor time //if it is not a complete sponsor time
if (sponsorTimes[index].length < 2) { if (sponsorTimes[index].segment.length < 2) {
messageHandler.query({ messageHandler.query({
active: true, active: true,
currentWindow: true currentWindow: true
@@ -710,7 +714,7 @@ async function runThePopup(messageListener?: MessageListener) {
sponsorTimes.splice(index, 1); sponsorTimes.splice(index, 1);
//save this //save this
Config.config.sponsorTimes.set(currentVideoID, sponsorTimes); Config.config.segmentTimes.set(currentVideoID, sponsorTimes);
//if they are all removed //if they are all removed
if (sponsorTimes.length == 0) { if (sponsorTimes.length == 0) {
@@ -780,7 +784,7 @@ async function runThePopup(messageListener?: MessageListener) {
//hides and shows the submit times button when needed //hides and shows the submit times button when needed
function showSubmitTimesIfNecessary() { function showSubmitTimesIfNecessary() {
//check if an end time has been specified for the latest sponsor time //check if an end time has been specified for the latest sponsor time
if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length > 1) { if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].segment.length > 1) {
//show submit times button //show submit times button
document.getElementById("submitTimesContainer").style.display = "unset"; document.getElementById("submitTimesContainer").style.display = "unset";
} else { } else {

View File

@@ -331,25 +331,30 @@ class Utils {
return seconds % 60; return seconds % 60;
} }
getFormattedTime(seconds: number, precise?: boolean) { getFormattedTime(seconds: number, precise?: boolean): string {
let minutes = Math.floor(seconds / 60); let hours = Math.floor(seconds / 60 / 60);
let secondsNum: number = seconds - minutes * 60; let minutes = Math.floor(seconds / 60) % 60;
let secondsNum = seconds % 60;
if (!precise) { if (!precise) {
secondsNum = Math.floor(secondsNum); secondsNum = Math.floor(secondsNum);
} }
let secondsDisplay: string = String(secondsNum.toFixed(3)); let secondsDisplay: string = String(precise ? secondsNum.toFixed(3) : secondsNum);
if (secondsNum < 10) { if (secondsNum < 10) {
//add a zero //add a zero
secondsDisplay = "0" + secondsDisplay; secondsDisplay = "0" + secondsDisplay;
} }
let formatted = minutes + ":" + secondsDisplay; let formatted = (hours ? hours + ":" : "") + minutes + ":" + secondsDisplay;
return formatted; return formatted;
} }
shortCategoryName(categoryName: string): string {
return chrome.i18n.getMessage("category_" + categoryName + "_short") || chrome.i18n.getMessage("category_" + categoryName);
}
getRawSeconds(minutes: number, seconds: number): number { getRawSeconds(minutes: number, seconds: number): number {
return minutes * 60 + seconds; return minutes * 60 + seconds;
} }