diff --git a/README.md b/README.md index 1ca64824..3c13765c 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ The awesome [Invidious API](https://github.com/omarroth/invidious/wiki/API) was Originally forked from [YTSponsorSkip](https://github.com/NDevTK/YTSponsorSkip), but zero code remains. -Some icons made by Gregor Cresnar from www.flaticon.com and are licensed by CC 3.0 BY - -Some icons made by Freepik from www.flaticon.com are licensed by CC 3.0 BY +Icons made by: +* Gregor Cresnar from www.flaticon.com and are licensed by CC 3.0 BY +* Freepik from www.flaticon.com and are licensed by CC 3.0 BY +* Alexander Kahlkopf from iconmonstr.com and are licensed by iconmonstr License diff --git a/manifest/manifest.json b/manifest/manifest.json index db127294..2cfd9bce 100644 --- a/manifest/manifest.json +++ b/manifest/manifest.json @@ -28,6 +28,9 @@ "icons/PlayerStopIconSponsorBlocker256px.png", "icons/PlayerUploadIconSponsorBlocker256px.png", "icons/PlayerUploadFailedIconSponsorBlocker256px.png", + "icons/settings.svg", + "icons/pencil.svg", + "icons/check.svg", "icons/upvote.png", "icons/downvote.png", "icons/thumbs_down.svg", diff --git a/package-lock.json b/package-lock.json index 2d7b6068..16885c02 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4129,9 +4129,9 @@ } }, "bl": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", "dev": true, "requires": { "readable-stream": "^2.3.5", diff --git a/public/_locales/cs/messages.json b/public/_locales/cs/messages.json index 7e9f4b41..d7dfdfda 100644 --- a/public/_locales/cs/messages.json +++ b/public/_locales/cs/messages.json @@ -1,6 +1,6 @@ { "fullName": { - "message": "SponsorBlock pro YouTube - Přeskoč Sponzorství", + "message": "SponsorBlock pro YouTube - Přeskoč sponzorství", "description": "Name of the extension." }, "Description": { @@ -23,7 +23,7 @@ "message": "segment" }, "Segments": { - "message": "segmenty" + "message": "segmentů" }, "upvoteButtonInfo": { "message": "Hlasovat pro tento příspěvek" @@ -275,7 +275,7 @@ "message": "Přeskočit {0}?" }, "skipped": { - "message": "Přeskočeno" + "message": "- přeskočeno" }, "disableAutoSkip": { "message": "Zakázat automatické přeskočení" diff --git a/public/_locales/el/messages.json b/public/_locales/el/messages.json index 92e650ba..13b9ac79 100644 --- a/public/_locales/el/messages.json +++ b/public/_locales/el/messages.json @@ -1,4 +1,8 @@ { + "fullName": { + "message": "SponsorBlock for YouTube - Skip Sponsorships", + "description": "Name of the extension." + }, "Segment": { "message": "τμήμα" }, @@ -67,9 +71,6 @@ "skip": { "message": "Παράκαμψη" }, - "skip_category": { - "message": "Παράκαμψη {0}?" - }, "skipped": { "message": "Παραλείφθηκε" }, diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json index 62ec128c..a13a3165 100644 --- a/public/_locales/en/messages.json +++ b/public/_locales/en/messages.json @@ -86,7 +86,7 @@ "message": "Segment Ends Now" }, "noVideoID": { - "message": "No YouTube video found at this tab. If you know this is a YouTube tab, close this popup and open it again. If that does not work, try reloading the tab." + "message": "No YouTube video found.\nIf this is incorrect, refresh the tab." }, "success": { "message": "Success!" @@ -122,31 +122,35 @@ "message": "Are you sure you want to submit this?" }, "whitelistChannel": { - "message": "Whitelist Channel" + "message": "Add to whitelist" }, "removeFromWhitelist": { - "message": "Remove Channel From Whitelist" + "message": "Remove from whitelist" }, "voteOnTime": { "message": "Vote On A Segment" }, - "soFarUHSubmited": { - "message": "So far, you've submitted" + "Submissions": { + "message": "Submissions" }, "savedPeopleFrom": { - "message": "You have saved people from " + "message": "You've saved people from " }, "viewLeaderboard": { - "message": "View the leaderboard" + "message": "Leaderboard" }, "here": { "message": "here" }, "recordTimesDescription": { - "message": "Click the button below when the segment starts and ends to record and submit it to the database." + "message": "Submit" + }, + "submissionEditHint": { + "message": "Section editing will appear after you click submit", + "description": "Appears in the popup to inform them that editing has been moved to the video player." }, "popupHint": { - "message": "Hint: Press the semicolon key while focused on a video to report the start/end of a segment and quote to submit. (This can be changed in the options)" + "message": "Hint: You can setup keybinds for submitting in the options" }, "clearTimesButton": { "message": "Clear Times" @@ -157,6 +161,9 @@ "publicStats": { "message": "This is used on the public stats page to show off how much you've contributed. See it" }, + "Username": { + "message": "Username" + }, "setUsername": { "message": "Set Username" }, @@ -253,10 +260,10 @@ "message": "Connection Timeout. Check your internet connection. If your internet is working, the server is probably overloaded or down." }, "disableSkipping": { - "message": "Disable SponsorBlock" + "message": "Skipping is enabled" }, "enableSkipping": { - "message": "Enable SponsorBlock" + "message": "Skipping is disabled" }, "yourWork": { "message": "Your Work", @@ -296,7 +303,7 @@ "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": { - "message": "You have skipped " + "message": "You've skipped " }, "youHaveSaved": { "message": "You have saved yourself " @@ -314,10 +321,10 @@ "message": "hours" }, "youHaveSavedTime": { - "message": "You have saved people" + "message": "You've saved people" }, "youHaveSavedTimeEnd": { - "message": " of their lives." + "message": " of their lives" }, "statusReminder": { "message": "Check status.sponsor.ajay.app for server status." @@ -634,5 +641,8 @@ }, "unsubmittedWarningDescription": { "message": "Send a notification when you leave a video with segments that are not uploaded" + }, + "help": { + "message": "Help" } } diff --git a/public/_locales/es/messages.json b/public/_locales/es/messages.json index 984c8dce..df21f1f4 100644 --- a/public/_locales/es/messages.json +++ b/public/_locales/es/messages.json @@ -209,7 +209,7 @@ "message": "En el lugar de solicitar segmentos del servidor usando el videoID, se envían los primeros 4 caracteres del hash del videoID. Este servidor devolverá los datos de todos los vídeos con hashes similares." }, "enableRefetchWhenNotFound": { - "message": "Actualizar segmentos en nuevos vídeos" + "message": "Actualizar Segmentos En Nuevos Vídeos" }, "whatRefetchWhenNotFound": { "message": "Si el video es nuevo, y no hay segmentos encontrados, seguirá recuperándose cada pocos minutos mientras veas." @@ -272,7 +272,7 @@ "message": "Omitir" }, "skip_category": { - "message": "¿Saltarse {0}?" + "message": "¿Saltar {0}?" }, "skipped": { "message": "Omitido" diff --git a/public/_locales/fi/messages.json b/public/_locales/fi/messages.json index d3862de3..c7f8f19c 100644 --- a/public/_locales/fi/messages.json +++ b/public/_locales/fi/messages.json @@ -252,9 +252,6 @@ "skip": { "message": "Ohita" }, - "skip_category": { - "message": "Ohita {0}?" - }, "skipped": { "message": "Ohitettu" }, @@ -268,7 +265,7 @@ "message": "Äänellinen Ilmoitus Ohitettaessa" }, "audioNotificationDescription": { - "message": "Ääni-ilmoitus ohituksessa toistaa äänen, kun segmentti ohitetaan. Jos pois päältä (tai automaattinen ohitus on pois käytöstä), ääntä ei soiteta." + "message": "Ääni-ilmoitus ohittaessa toistaa äänen kun segmentti ohitetaan. Jos asetus on pois päältä (tai automaattinen ohitus on pois käytöstä), ääntä ei soiteta." }, "youHaveSkipped": { "message": "Olet ohittanut " @@ -295,7 +292,7 @@ "message": " heidän elämästään." }, "statusReminder": { - "message": "Tarkista status.sponsor.ajay.app palvelimen tila." + "message": "Tarkista palvelimen tila osoitteessa status.sponsor.ajay.app." }, "changeUserID": { "message": "Tuo/vie sinun UserID:si" @@ -346,7 +343,7 @@ "message": "Vähimmäiskesto (sekuntia):" }, "minDurationDescription": { - "message": "Segmentit, jotka ovat asetettua arvoa lyhyempiä, ei tulla ohittamaan tai näytetä soittimessa." + "message": "Segmenttejä jotka ovat asetettua arvoa lyhyempiä ei ohiteta tai näytetä soittimessa." }, "showUploadButton": { "message": "Näytä lähetä-painike" @@ -358,7 +355,7 @@ "message": "SponsorBlock Palvelimen Osoite" }, "customServerAddressDescription": { - "message": "Osoite jota SponsorBlock käyttää lähettääkseen kutsuja palvelimelle.\nEllei sinulla ole omaa palvelin instanssia, tätä ei pitäisi muuttaa." + "message": "Osoite jota SponsorBlock käyttää lähettääkseen kutsuja palvelimelle.\nEllei sinulla ole omaa palvelininstanssia, tätä ei pitäisi muuttaa." }, "save": { "message": "Tallenna" @@ -373,7 +370,7 @@ "message": "Oletko varma, että haluat nollata tämän?" }, "unlistedCheck": { - "message": "Ohita Listaamattomat/Yksityiset Videot" + "message": "Ohita listaamattomat/yksityiset videot" }, "mobileUpdateInfo": { "message": "m.youtube.com-osoitetta tuetaan nyt" @@ -428,7 +425,7 @@ "message": "Sponsori" }, "category_intro": { - "message": "Väli/Intro Animaatio" + "message": "Väli- tai introanimaatio" }, "category_intro_description": { "message": "Aikaväli ilman varsinaista sisältöä. Voi olla tauko, staattinen kehys, toistuva animaatio. Tätä ei pitäisi käyttää siirtymisiin, jotka sisältävät tietoa." diff --git a/public/_locales/fr/messages.json b/public/_locales/fr/messages.json index 5fb2dd14..871c1bb8 100644 --- a/public/_locales/fr/messages.json +++ b/public/_locales/fr/messages.json @@ -1,6 +1,6 @@ { "fullName": { - "message": "SponsorBlock pour YouTube - Supprime les messages commerciaux et publicités intégrées", + "message": "SponsorBlock pour YouTube - Supprime les publicités intégrées", "description": "Name of the extension." }, "Description": { @@ -100,6 +100,9 @@ "connectionError": { "message": "Erreur de connexion. Code d'erreur : " }, + "wantToSubmit": { + "message": "Voulez-vous soumettre vos segments pour la vidéo" + }, "leftTimes": { "message": "Vous semblez avoir laissé certains segments non soumis. Retournez à cette page pour les soumettre (ils ne sont pas supprimés)." }, @@ -193,9 +196,31 @@ "whatDeleteButton": { "message": "Il s'agit du bouton qui permet de supprimer tous les segments commerciaux depuis le lecteur YouTube." }, + "enableViewTracking": { + "message": "Activer le suivi du nombre de sauts de segments" + }, + "whatViewTracking": { + "message": "Cette fonctionnalité permet de suivre les segments que vous avez sautés pour faire savoir aux utilisateurs à quel point leur soumission a aidé les autres et est utilisée comme donnée avec les votes positifs pour s'assurer que des spams n'entre pas dans la base de données. L'extension envoie un message au serveur chaque fois que vous sautez un segment. Il est à espérer que la plupart des gens ne modifient pas ce paramètre pour que les données sur le nombre d'affichage soient exacts :)" + }, + "enableQueryByHashPrefix": { + "message": "Requête par préfixe du hash" + }, + "whatQueryByHashPrefix": { + "message": "Au lieu de demander des segments au serveur à l'aide de l'identifiant de la vidéo, les 4 premiers caractères du hash de l'identifiant de la vidéo sont envoyés. Ce serveur renverra les données pour toutes les vidéos ayant des hash similaires." + }, + "enableRefetchWhenNotFound": { + "message": "Récupérer les segments sur les nouvelles vidéos" + }, + "whatRefetchWhenNotFound": { + "message": "Si la vidéo est nouvelle et qu'aucun segment n'a été trouvé, ils seront réactualisés toutes les quelques minutes pendant le visionnage." + }, "showNotice": { "message": "Afficher la notification" }, + "longDescription": { + "message": "SponsorBlock vous permet de passer les sponsors, les intros, les outros, les rappels d'abonnement et autres parties ennuyeuses des vidéos YouTube. SponsorBlock est une extension de navigateur qui permet à n'importe qui de soumettre les temps de début et de fin des segments sponsorisés et d'autres segments de vidéos YouTube. Une fois qu'une personne a soumis ces informations, toutes les autres personnes possédant cette extension passeront directement les segments sponsorisés. Vous pouvez également sauter les sections non musicales des vidéos musicales.", + "description": "Full description of the extension on the store pages." + }, "website": { "message": "Site web", "description": "Used on Firefox Store Page" @@ -354,6 +379,9 @@ "minDuration": { "message": "Durée minimale (en secondes):" }, + "minDurationDescription": { + "message": "Les segments plus courts que la valeur fixée ne seront pas sautés ou affichés dans le lecteur." + }, "shortCheck": { "message": "Le segment suivant est plus court que votre option de durée minimale. Cela pourrait signifier qu'il est déjà soumis, et just ignoré par cette option. Êtes-vous sûr de vouloir soumettre ?" }, @@ -381,9 +409,15 @@ "areYouSureReset": { "message": "Voulez-vous vraiment remettre à zéro ?" }, + "confirmPrivacy": { + "message": "La vidéo a été détectée comme étant non répertoriée. Cliquez sur annuler si vous ne voulez pas vérifier les segments sautés." + }, "unlistedCheck": { "message": "Ignorer les vidéos non listées" }, + "whatUnlistedCheck": { + "message": "Ce réglage ralentira légèrement SponsorBlock. Pour sauter des segments, il faut envoyer l'ID de la vidéo au serveur. Si vous craignez que des identifiants de vidéo non répertoriés soient envoyés sur Internet, activez cette option." + }, "mobileUpdateInfo": { "message": "m.youtube.com est maintenant pris en charge" }, @@ -455,7 +489,7 @@ "message": "Entracte/Animation d'intro" }, "category_intro_description": { - "message": "Un intervalle sans réel contenu, comme une pause, une image statique ou une animation répétitive. Ne doit pas être utilisé pour les transitions avec des informations ou pour les vidéos musicales." + "message": "Un intervalle sans réel contenu, comme une pause, une image statique ou une animation répétitive. Ne doit pas être utilisé pour les transitions avec des informations." }, "category_intro_short": { "message": "Entracte" @@ -464,7 +498,7 @@ "message": "Générique de fin" }, "category_outro_description": { - "message": "Crédits ou quand les écrans de fin Youtube apparaissent. Pas pour les conclusions qui contiennent des informations." + "message": "Crédits ou quand les annotations Youtube de fin apparaissent. Pas pour les conclusions qui contiennent des informations." }, "category_interaction": { "message": "Rappel d'interaction (abonnement)" @@ -565,7 +599,7 @@ "message": "Forcer la vérification du canal avant de passer" }, "whatForceChannelCheck": { - "message": "Par défaut, passer les segments avant même de savoir à quelle chaîne appartient la vidéo. Par défaut, certains segments au début des vidéos des chaînes qui sont sur la liste blanche peuvent être passés. Activer cette option empêchera ça mais passer les segments aura un délai car obtenir l'id des chaînes peut prendre du temps. Ce délai peut ne pas être remarqué si votre connexion est rapide." + "message": "Par défaut, passer les segments avant même de savoir à quelle chaîne appartient la vidéo. Par défaut, les segments en début des vidéos des chaînes sur liste blanche peuvent être passés. Activer cette option empêchera cela mais passer les segments aura un délai, car obtenir l'id des chaînes peut prendre du temps. Ce délai sera imperceptible si votre connexion est rapide." }, "forceChannelCheckPopup": { "message": "Envisagez d'activer \"Forcez la vérification de la chaîne avant de passer\"" @@ -577,7 +611,7 @@ "message": "Mauvaise catégorie" }, "nonMusicCategoryOnMusic": { - "message": "Cette vidéo est catégorisée comme de la musique. Êtes-vous sûr qu'elle est sponsorisée ? S'il s'agit en fait d'un \"segment non-musical\", allez dans les options de l'extension et activez cette catégorie. Ensuite, vous pourrez soumettre ce segment en tant que \"segment non-musical\" au lieu de sponsor. Lisez les \"Guidelines\" en cas de confusion." + "message": "Cette vidéo est catégorisée comme de la musique. Êtes-vous sûr qu'elle est sponsorisée ? S'il s'agit en fait d'un \"segment non-musical\", allez dans les options de l'extension et activez cette catégorie. Ensuite, vous pourrez soumettre ce segment en tant que \"segment non-musical\" au lieu de sponsor. Lisez les instructions en cas de confusion." }, "multipleSegments": { "message": "Plusieurs segments" diff --git a/public/_locales/hu/messages.json b/public/_locales/hu/messages.json index 57e58129..08d936a6 100644 --- a/public/_locales/hu/messages.json +++ b/public/_locales/hu/messages.json @@ -1,31 +1,62 @@ { "fullName": { - "message": "SponorBlock YouTube-ra - Szponzorok kihagyása", + "message": "SponorBlock YouTube-ra - Szponzorok átugrására", "description": "Name of the extension." }, + "Description": { + "message": "Szponzorok, feliratkozás-kérelmek és több átugrása a YouTube videókon. Jelöljön meg szponzorokat videókon amiket néz, hogy mások idejét is megtakarítsa.", + "description": "Description of the extension." + }, + "400": { + "message": "Szerver: Ez a kérés érvénytelen" + }, + "429": { + "message": "Túl sok szponzoridőt jelölt be ezen a videón. Biztos benne, hogy van ennyi?" + }, + "409": { + "message": "Ez már korábban be lett küldve" + }, + "channelWhitelisted": { + "message": "A csatorna az engedélyezőlistára került!" + }, "Segment": { "message": "szegmens" }, "Segments": { - "message": "részletek" + "message": "szegmensek" }, "upvoteButtonInfo": { "message": "Részlet felszavazása" }, "reportButtonTitle": { - "message": "Bejelentés" + "message": "Jelentés" + }, + "reportButtonInfo": { + "message": "Szegmens jelentése helytelenként." + }, + "Dismiss": { + "message": "Elvetés" }, "Loading": { "message": "Betöltés..." }, + "Mins": { + "message": "Perc" + }, + "Secs": { + "message": "Másodperc" + }, "Hide": { - "message": "Sose mutassa" + "message": "Ne mutassa többé" + }, + "hitGoBack": { + "message": "Kattintson a visszaugrásra, hogy visszakerüljön oda, ahonnan ugrott." }, "unskip": { - "message": "Kihagyás visszavonása" + "message": "Visszaugrás" }, "reskip": { - "message": "Újra-kihagyás" + "message": "Újra-átugrás" }, "paused": { "message": "Szüneteltetve" @@ -33,29 +64,107 @@ "manualPaused": { "message": "Időzítő megállítva" }, + "confirmMSG": { + "message": "Ahhoz, hogy értékeket szerkesszen, vagy töröljön kattintson az info gombra, vagy nyissa meg a bővítmény felugró ablakát a bővítmény ikonjával a jobb felső sarokban." + }, + "clearThis": { + "message": "Biztosan törölni akarja?\n\n" + }, + "Unknown": { + "message": "Hiba történt a szponzoridők bejelentésekor. Kérjük, próbálja újra." + }, + "sponsorFound": { + "message": "Ennek a videónak már vannak szegmensei az adatbázisban!" + }, + "sponsor404": { + "message": "Nem találhatóak szegmensek" + }, "sponsorStart": { - "message": "Részlet kezdődik most" + "message": "Szegmens eleje" }, "sponsorEnd": { - "message": "Részlet végződik most" + "message": "Szegmens vége" + }, + "noVideoID": { + "message": "Nem található YouTube videó ezen a fülön. Ha ez biztosan egy YouTube fül, csukja be ezt az ablakot, és nyissa meg újra. Amennyiben nem működik, próbája újratölteni a fület." }, "success": { "message": "Siker!" }, "voted": { - "message": "Szavaztál!" + "message": "Szavazott!" + }, + "serverDown": { + "message": "Úgy tűnik a szerver nem működik. Kérjük, mihamarabb értesítse a fejlesztőket." + }, + "connectionError": { + "message": "Kapcsolódási probléma merült fel. Error kód: " + }, + "wantToSubmit": { + "message": "Szeretné beküldeni a szegmenst ehhez a videóhoz:" + }, + "leftTimes": { + "message": "Úgy tűnik pár megjelölt szegmenst beküldetlenül hagyott. Lépjen vissza az oldalra, hogy beküldhesse őket (nem kerültek törlésre)." + }, + "clearTimes": { + "message": "Szegmensek törlése" + }, + "openPopup": { + "message": "SponsorBlock felugró ablak megnyitása" }, "closePopup": { - "message": "Doboz bezárása" + "message": "Felugró ablak bezárása" + }, + "SubmitTimes": { + "message": "Szegmens beküldése" + }, + "submitCheck": { + "message": "Biztosan be akarja küldeni?" + }, + "whitelistChannel": { + "message": "Csatorna engedélyezőlistára helyezése" + }, + "removeFromWhitelist": { + "message": "Csatorna eltávolítása az engedélyezőlistáról" }, "voteOnTime": { - "message": "Szavazz egy részleten" + "message": "Szavazzon a szegmensről" + }, + "soFarUHSubmited": { + "message": "Eddig beküldött" + }, + "savedPeopleFrom": { + "message": "Megspórolt másoknak " + }, + "viewLeaderboard": { + "message": "Ranglista megtekintése" }, "here": { "message": "itt" }, + "recordTimesDescription": { + "message": "Kattintson az alábbi gombra a szegmens kezdeténél és végénél megjelöléshez, és adja hozzá az adatbázishoz." + }, + "popupHint": { + "message": "Tipp: Nyomja le a pontosvessző gombot, hogy megjelölje egy szegmens kezdetét/végét és beküldhesse. (Változtatható a beállításokban)" + }, + "clearTimesButton": { + "message": "Időpontok törlése" + }, + "submitTimesButton": { + "message": "Időpontok megadása" + }, + "publicStats": { + "message": "Ezt használja a nyilvános ranglistán, hogy megmutassa mennyit járult hozzá. Nézze meg" + }, + "setUsername": { + "message": "Felhasználónév megadása" + }, + "discordAdvert": { + "message": "Csatlakozzon a hivatalos discord szerverhez, hogy javaslatokat és visszajelzést adhasson!" + }, "hideThis": { - "message": "Rejtsd el ezt" + "message": "Elrejtés" }, "Options": { "message": "Beállítások" @@ -67,7 +176,7 @@ "message": "Gombok elrejtése a YouTube lejátszón" }, "hideButtonsDescription": { - "message": "Ez elrejti a kihagyásos részletek létrehozásához szükséges gombokat a YouTube lejátszón." + "message": "Ez elrejti az átugrandó szegmensek megjelöléséhez használt gombokat a YouTube lejátszón." }, "showInfoButton": { "message": "Info gomb mutatása a YouTube lejátszón" @@ -76,7 +185,7 @@ "message": "Info gomb elrejtése a YouTube lejátszón" }, "whatInfoButton": { - "message": "Ez a gomb az, ami feldob egy dobozt a YouTube oldalon." + "message": "Ez a gomb felhoz egy felugró dobozt a YouTube oldalon." }, "hideDeleteButton": { "message": "Törlés gomb elrejtése a YouTube lejátszón" @@ -84,6 +193,34 @@ "showDeleteButton": { "message": "Törlés gomb mutatása a YouTube lejátszón" }, + "whatDeleteButton": { + "message": "Ez egy gomb a lejátszón, ami törli az összes beküldetlen szegmensét a jelenlegi videón." + }, + "enableViewTracking": { + "message": "Átugrás-számláló követés bekapcsolása" + }, + "whatViewTracking": { + "message": "Ez a funkció követi, mely szegmenseket ugrotta át, hogy más felhasználók megtudhassák mennyit segítettek a bejelentéseik és a szavazatokkal együtt egy mértékegységként van használva, hogy ne kerülhessen spam az adatbázisba. A bővítmény küld egy üzenetet a szervernek, minden alkalommal, mikor átugrik egy szegmenst. Remélhetőleg nem sokan állítják át ezt a beállítást, hogy a számok pontosak maradhassanak. :)" + }, + "enableQueryByHashPrefix": { + "message": "Lekérdezés Hash előtaggal" + }, + "whatQueryByHashPrefix": { + "message": "A szerverről videoID helyett, a videoID hash első négy karaktere lesz elküldve szegmenslekéréskor. A szerver visszaküldi az összes hasonló hashel rendelkező videó adatait." + }, + "enableRefetchWhenNotFound": { + "message": "Szegmensek újrakeresése új videókon" + }, + "whatRefetchWhenNotFound": { + "message": "Ha a videó új, és még nem találhatóak szegmensek, a bővítmény pár percenkét újra keresi őket, miközben nézi." + }, + "showNotice": { + "message": "Értesítés megjelenítése ismét" + }, + "longDescription": { + "message": "A SponsorBlock-al átugorhatja a szponzorokat, introkat, outrokat, feliratkozás emlékeztetőket és a YouTube videók többi idegesítő részeit. A SponsorBlock egy közösség által vezérelt böngészőbővítmény, ami lehetővé tesz bárkit arra, hogy megjelölhesse egy szponzor vagy más szegmens kezdő és végpontjait. Ha megosztja ezt az információt, mindenki más ennek a bővítménynek a birtokában egyenesen átugorja majd ezt a szponzorszegmenst. Emellett például a zene videók nem-zene részei is átugorhatóak.", + "description": "Full description of the extension on the store pages." + }, "website": { "message": "Weboldal", "description": "Used on Firefox Store Page" @@ -92,6 +229,29 @@ "message": "Forráskód", "description": "Used on Firefox Store Page" }, + "noticeUpdate": { + "message": "Az értesítést frissítettük!", + "description": "The first line of the message displayed after the notice was upgraded." + }, + "noticeUpdate2": { + "message": "Ha még mindig nem tetszik, kattintson a ne mutassa többé gombra.", + "description": "The second line of the message displayed after the notice was upgraded." + }, + "setStartSponsorShortcut": { + "message": "Billentyű beállítása a szegmenskezdés gombhoz" + }, + "setSubmitKeybind": { + "message": "Billentyű beállítása a beküldés gombhoz" + }, + "keybindDescription": { + "message": "Válasszon billentyűt azzal, hogy lenyomja" + }, + "keybindDescriptionComplete": { + "message": "A funkció erre a billentyűre lett állítva: " + }, + "0": { + "message": "Kapcsolati időtúllépés. Ellenőrizze az internetkapcsolatot. Ha az internet működik, a kiszolgáló valószínűleg túlterhelt vagy leállt." + }, "disableSkipping": { "message": "SponsorBlock kikapcsolása" }, @@ -102,35 +262,44 @@ "message": "Te munkád", "description": "Used to describe the section that will show you the statistics from your submissions." }, + "502": { + "message": "Úgy tűnik, hogy a szerver túlterhelt. Néhány másodperc múlva próbálkozzon újra." + }, "errorCode": { "message": "Hibakód: " }, "skip": { - "message": "Kihagy" + "message": "Átugrás" }, "skip_category": { - "message": "Kihagyod {0}-t?" + "message": "Átugorja ezt: {0}?" }, "skipped": { - "message": "Kihagyva" + "message": "Átugorva" }, "disableAutoSkip": { - "message": "Auto kihagyás kikapcsolása" + "message": "Auto átugrás kikapcsolása" }, "enableAutoSkip": { - "message": "Auto kihagyás bekapcsolása" + "message": "Auto átugrás bekapcsolása" }, "audioNotification": { - "message": "Hangjelzés kihagyáskor" + "message": "Hangjelzés átugráskor" }, "audioNotificationDescription": { - "message": "Hangjelzés kihagyáskor egy hangot fog játszani amikor kihagyunk egy részletet. Ha ez ki van kapcsolva (vagy az auto kihagyás), nem lesz semmilyen hang lejátszva." + "message": "A hangjelzés átugráskor lejátszik egy hangot minden alkalommal amikor átugrik egy szegmenst. Ha kikapcsolja (vagy az auto átugrás ki van kapcsolva) nem lesz hangjelzés lejátszva." + }, + "showTimeWithSkips": { + "message": "Idő megtekintése az átugrandók nélkül" + }, + "showTimeWithSkipsDescription": { + "message": "Ez az idő zárójelben jelenik meg az aktuális idő mellett a keresősáv alatt. Megmutatja a videó teljes időtartamát, levonva a szegmenseket. Beletartoznak a csak \"Megjelenítés a keresősávban\" jelöléssel ellátott szegmensek is." }, "youHaveSkipped": { - "message": "Te kihagytál " + "message": "Ön átugrott " }, "youHaveSaved": { - "message": "Te mentettél magadnak " + "message": "Megtakarított magának " }, "minLower": { "message": "perc" @@ -145,49 +314,133 @@ "message": "óra" }, "youHaveSavedTime": { - "message": "Megmentettél embereknek" + "message": "Megspórolt másoknak" }, "youHaveSavedTimeEnd": { - "message": " az életüknek." + "message": " az életükből." }, "statusReminder": { - "message": "Nézd meg status.sponsor.ajay.app-t a szerver állapotához." + "message": "A szerver állapotához tekintse meg a status.sponsor.ajay.app oldalt." }, "changeUserID": { "message": "UserID importálása / exportálása" }, + "whatChangeUserID": { + "message": "Ezt titokban kell tartani. Olyan, mint egy jelszó, nem szabad senkivel megosztania. Ha valakinek megvan, megszemélyesítheti Önt." + }, "setUserID": { "message": "UserID beállítása" }, + "userIDChangeWarning": { + "message": "Figyelem: A UserID megváltoztatása végleges. Biztosan szeretné megtenni? Minden esetben készítsen biztonsági másolatot a régiről." + }, "createdBy": { "message": "Készítette" }, "autoSkip": { - "message": "Auto kihagyás" + "message": "Auto átugrás" }, "showSkipNotice": { - "message": "Jelezzen ha egy részlet ki van hagyva" + "message": "Jelezzen, ha egy szegmens át lett ugorva" }, "keybindCurrentlySet": { - "message": ". Jelenleg állítva van:" + "message": ". Jelenleg erre van állítva:" + }, + "supportInvidious": { + "message": "Invidious támogatása" + }, + "supportInvidiousDescription": { + "message": "Az Invidious (invidio.us) egy harmadik fél által készített YouTube kliens. A támogatás engedélyezéséhez el kell fogadnia további engedélyeket. NEM működik inkognitómódban a Chrome-on vagy más Chromium-változatokon." + }, + "optionsInfo": { + "message": "Invidious támogatás engedélyezése, autoátugrás kikapcsolása, gombok eltűntetése és több." + }, + "addInvidiousInstance": { + "message": "Invidious példány hozzáadása" + }, + "addInvidiousInstanceDescription": { + "message": "Egyedi Invidious példány hozzáadása. CSAK a domain-nel kell formázni. Például: invidious.ajay.app" }, "add": { "message": "Hozzáadás" }, + "addInvidiousInstanceError": { + "message": "Érvénytelen domain. CSAK a domain részt tartalmazhatja. Például: invidious.ajay.app" + }, + "resetInvidiousInstance": { + "message": "Invidious példányok listájának visszaállítása" + }, + "resetInvidiousInstanceAlert": { + "message": "Épp visszaállítja az Invidious példányok listát" + }, + "currentInstances": { + "message": "Jelenlegi példányok:" + }, + "minDuration": { + "message": "Minimális időtartam (másodpercekben):" + }, + "minDurationDescription": { + "message": "A beállított értéknél rövidebb szegmenseket nem ugorja át és nem jeleníti meg a lejátszó." + }, + "shortCheck": { + "message": "A következő szegmens rövidebb, mint az Ön által beállított minimális időtartam. Ez azt jelentheti, hogy már beküldhették, csak emiatt az opció miatt Önnek figyelmen kívül marad. Biztosan beküldi?" + }, + "showUploadButton": { + "message": "Feltöltés gomb megjelenítése" + }, + "whatUploadButton": { + "message": "Ez a gomb a YouTube lejátszón jelenik meg, miután kiválasztott egy időtartamot és készen áll a beküldésre." + }, "customServerAddress": { "message": "SponsorBlock szerver címe" }, + "customServerAddressDescription": { + "message": "A SponsorBlock által használt cím a szerverre történő hívások kezdeményezésére szolgál.\nHacsak nincs saját szerverpéldánya, ezt nem szabad megváltoztatni." + }, "save": { "message": "Mentés" }, "reset": { "message": "Visszaállítás" }, + "customAddressError": { + "message": "A cím helytelenül van formázva. Győződjön meg róla, hogy http:// vagy https:// van az elején, és nem fordított perjeleket használ." + }, + "areYouSureReset": { + "message": "Biztosan vissza szeretné állítani?" + }, + "confirmPrivacy": { + "message": "Videó észlelve nem listázottként. Kattintson a Mégse gombra, ha nem akar ellenőrizni átugorható szegmensek után." + }, + "unlistedCheck": { + "message": "Nem listázott/Privát videók ignorálása" + }, + "whatUnlistedCheck": { + "message": "Ez a beállítás kissé lelassíthatja a SponsorBlockot. A szegmensek átugrásához szükséges, hogy a videoID el legyen küldve a szerverre. Ha aggódik az interneten küldött nem listázott videóazonosítók küldése miatt, kapcsolja be ezt a funkciót." + }, + "mobileUpdateInfo": { + "message": "az m.youtube.com már támogatott" + }, "exportOptions": { "message": "Összes beállítás importálása / exportálása" }, + "whatExportOptions": { + "message": "Ez az össze beállítása JSON-ban. Ebbe bele tartozik a userID-ja, szóval csak ésszel ossza meg." + }, + "setOptions": { + "message": "Beállítások" + }, + "exportOptionsWarning": { + "message": "Figyelem: Az beállítások megváltoztatása végleges, és tönkreteheti a bővítményét. Biztosan meg szeretné tenni? Készítsen egy biztonsági mentést a régi beállításairól, biztos, ami biztos." + }, + "incorrectlyFormattedOptions": { + "message": "Ez a JSON helytelenül van formázva. A beállításai nem lettek megváltoztatva." + }, + "confirmNoticeTitle": { + "message": "Szegmens beküldése" + }, "submit": { - "message": "Elküld" + "message": "Beküld" }, "cancel": { "message": "Mégse" @@ -204,14 +457,69 @@ "edit": { "message": "Szerkesztés" }, + "copyDebugInformation": { + "message": "Hibakeresési információ másolása a vágólapra" + }, + "copyDebugInformationFailed": { + "message": "Hiba a vágólapra másoláskor" + }, + "copyDebugInformationOptions": { + "message": "Információt másol a vágólapra, amit megadhat egy fejlesztőnek, ha bejelent egy hibát, vagy egy fejlesztő kéri öntől. Az érzékeny információkat, például a felhasználói azonosítót, az engedélyezőlistán szereplő csatornákat és az egyéni szerver címét eltávolítottuk. Azonban tartalmaz olyan információkat, mint a böngésző, az operációs rendszer és a bővítmény verziószáma. " + }, + "copyDebugInformationComplete": { + "message": "A hibakeresési információ másolva lett a vágólapjára. Nyugodtan távolítson el belőle olyan információkat, amiket nem szívesen osztana meg. Mentse el szöveges fájlként, vagy másolja a hibajelentésbe." + }, "theKey": { - "message": "A kulcs" + "message": "A billentyű" + }, + "keyAlreadyUsed": { + "message": "már máshoz van állítva. Kérem, válasszon egy másik billentyűt." + }, + "to": { + "message": "-tól eddig:", + "description": "Used between segments. Example: 1:20 to 1:30" }, "category_sponsor": { "message": "Szponzor" }, + "category_sponsor_description": { + "message": "Fizetett promóció, vagy közvetlen reklám. Nem ön-promóció vagy ingyenes ajánlat (/shoutout) emberekről/termékekről/weboldalakról amik tetszenek nekik." + }, + "category_intro": { + "message": "Megszakítás/Intro animáció" + }, + "category_intro_description": { + "message": "Egy részlet tartalom nélkül. Lehet szünet, álló képkocka, vagy ismétlődő animáció. Nem használandó információt tartalmazó átmeneteknél." + }, + "category_intro_short": { + "message": "Megszakítás" + }, + "category_outro": { + "message": "Záróképernyő/ Stáblista" + }, + "category_outro_description": { + "message": "Stáblista, vagy amikor megjelennek a YouTube zárókártyák. Nem használandó információt tartalmazó következtetésekkor." + }, + "category_interaction": { + "message": "Emlékeztető (Feliratkozás)" + }, + "category_interaction_description": { + "message": "Egy rövid emlékeztető arról, hogy likeoljunk, iratkozzunk fel, vagy kövessük a tartalom közben. Ha hosszabb szakasz, vagy egy adott témáról van, inkább a az ön-promóció alá tartozik." + }, "category_interaction_short": { - "message": "Szünet" + "message": "Emlékeztető" + }, + "category_selfpromo": { + "message": "Nem fizetett/ön-promóció" + }, + "category_selfpromo_description": { + "message": "Hasonló a szponzorhoz, de nem fizetett vagy ön-promóció. Beletartozik a saját ruhaáru, adományok, vagy infó arról hogy kivel működtek együtt." + }, + "category_music_offtopic": { + "message": "Zene: nem-zene szegmens" + }, + "category_music_offtopic_description": { + "message": "Csak zenei videókon. Beletartoznak a zenei videók intro és outro részei is." }, "category_music_offtopic_short": { "message": "Nem-Zene" @@ -220,24 +528,39 @@ "message": "Élő adás: Adomány / üzenet olvasások" }, "category_livestream_messages_short": { - "message": "Üzenet olvasás" + "message": "Üzenet beolvasása" }, "disable": { "message": "Kikapcsol" }, "manualSkip": { - "message": "Manuális kihagyás" + "message": "Átugrás manuálisan" }, "showOverlay": { - "message": "Keresősáv megjelenítése" + "message": "Megjelenítés a keresősávban" + }, + "colorFormatIncorrect": { + "message": "A szín helytelenül van formázva. Egy 3 vagy 6 számjegyből álló hex kódnak kell lennie egy kettőskereszttel az elején." }, "previewColor": { "message": "Előnézeti szín", "description": "Referring to submissions that have not been sent to the server yet." }, + "seekBarColor": { + "message": "Keresősáv színe" + }, "category": { "message": "Kategória" }, + "enableTestingServer": { + "message": "Bétateszt szerver bekapcsolása" + }, + "whatEnableTestingServer": { + "message": "A hozzájárulásai/szavazatai NEM FOGNAK SZÁMÍTANI a fő szerveren. Csak tesztelésre használja." + }, + "testingServerWarning": { + "message": "Az összes hozzájárulás/szavazat NEM FOG SZÁMÍTANI a fő szerverhez, amíg a tesztszerverhez kapcsolódik. Győződjön meg róla, hogy ki van kapcsolva, ha valódi hozzájárulásokat szeretne megosztani." + }, "bracketNow": { "message": "(Most)" }, @@ -245,7 +568,10 @@ "message": "További kategóriák" }, "chooseACategory": { - "message": "Válassz egy kategóriát" + "message": "Válasszon kategóriát" + }, + "youMustSelectACategory": { + "message": "Minden szegmenshez kategóriát kell választania beküldés előtt!" }, "bracketEnd": { "message": "(Vége)" @@ -257,7 +583,22 @@ "message": "elrejtve: túl rövid" }, "channelDataNotFound": { - "message": "Csatorna azonosító nem töltődött be." + "message": "A csatorna azonosító még nem töltődött be." + }, + "adblockerIssue": { + "message": "Valami meggátolja a SponsorBlockot a videó adatainak megszerzésében. Valószínűleg az ad-blockere. Kérem ellenőrizze: https://github.com/ajayyy/SponsorBlock/wiki/Fix-Ad-Blocker-Blocking-SponsorBlock's-Requests" + }, + "itCouldBeAdblockerIssue": { + "message": "Ha ez folyamatosan előfordul, lehet hogy az ad-blockere okozza. Kérem nézzen utána: https://github.com/ajayyy/SponsorBlock/wiki/Fix-Ad-Blocker-Blocking-SponsorBlock's-Requests" + }, + "forceChannelCheck": { + "message": "Csatorna ellenőrzése átugrás előtt" + }, + "whatForceChannelCheck": { + "message": "Alapértelmezett állapotban, a bővítmény átugorhat szegmenseket, mielőtt tudná melyik csatornán van. Alapból ezért, néhány szegmens, ami a videók legelején van, engedélyezett csatornákon is átugródhat. Ennek a bekapcsolásával ez elkerülhető, de minden átugrás előtt lesz egy kis késleltetés, hiszen a channelID megszerzéséhez elkell egy kis idő. Ez a késleltetés akár észrevehetetlen is lehet, ha elég gyors a kapcsolata." + }, + "forceChannelCheckPopup": { + "message": "Gondolja át a \"Csatorna ellenőrzése átugrás előtt\" bekapcsolását" }, "downvoteDescription": { "message": "Helytelen/rossz időzítés" @@ -266,19 +607,28 @@ "message": "Hibás kategória" }, "nonMusicCategoryOnMusic": { - "message": "Ez a videó zeneként van kategorizálva. Biztos vagy benne, hogy ennek van szponzorja? Ha ez valójában egy \"nem-zene részlet\", nyisd meg a bővítmény beállításait és kapcsold be ezt a kategóriát. Ezt követően elküldheted ezt a részletet \"Nem-Zene\"-ként szponzor helyett. Olvasd el az irányelveket, ha nem érted." + "message": "Ez a videó zeneként van kategorizálva. Biztos benne, hogy ennek van szponzora? Ha ez valójában egy \"nem-zene szegmens\", nyissa meg a bővítmény beállításait és kapcsolja be azt a kategóriát. Ezt követően elküldheti ezt a szegmenst \"nem-zene\"-ként szponzor helyett. Amennyiben nem érti, kérjük olvassa el az irányelveket." }, "multipleSegments": { - "message": "Több részlet" + "message": "Több szegmens" }, "guidelines": { "message": "Irányelvek" }, "readTheGuidelines": { - "message": "Olvasd el az irányelveket!!", + "message": "Olvassa el az irányelveket!!", "description": "Show the first time they submit or if they are \"high risk\"" }, "categoryUpdate1": { "message": "Itt vannak a kategóriák!" + }, + "categoryUpdate2": { + "message": "Nyissa meg a beállításokat, hogy átugorhasson introkat, outrokat stb." + }, + "unsubmittedWarning": { + "message": "Beküldetlen szegmens értesítő" + }, + "unsubmittedWarningDescription": { + "message": "Küldjön egy értesítést, ha elhagy egy videót amelyen beküldetlen szegmensek vannak" } } diff --git a/public/_locales/it/messages.json b/public/_locales/it/messages.json index 00a039fb..75e37262 100644 --- a/public/_locales/it/messages.json +++ b/public/_locales/it/messages.json @@ -203,7 +203,7 @@ "message": "Questa funzionalità tiene traccia dei segmenti che hai saltato, per far sapere agli utenti quanto il loro contributo abbia aiutato gli altri e sia stato utilizzato come metrica insieme ai voti positivi, per garantire che lo spam non entri nel database. L'estensione invierà un messaggio al server ogni volta che salterai un segmento. Si spera che la maggior parte delle persone non modifichino questa impostazione, in modo da non intaccare l'accuratezza dei numeri di visualizzazione. :)" }, "enableQueryByHashPrefix": { - "message": "Query Del Prefisso di Hash" + "message": "Ricerca tramite prefisso hash" }, "whatQueryByHashPrefix": { "message": "Invece di richiedere i segmenti dal server usando il videoID, i primi 4 caratteri dell'hash del videoID sono inviati. Questo server reinvierà i dati per tutti i video con hash simili." diff --git a/public/_locales/pl/messages.json b/public/_locales/pl/messages.json index a11e0e0e..f3d874e6 100644 --- a/public/_locales/pl/messages.json +++ b/public/_locales/pl/messages.json @@ -203,13 +203,13 @@ "message": "Ta opcja monitoruje pomijane przez Ciebie segmenty, by dać znać użytkownikom, jak bardzo ich wkład pomógł innym, oraz w połączeniu z systemem głosowania zapobiegać dostawaniu się spamu do bazy danych. Rozszerzenie wysyła wiadomość do serwera za każdym razem, kiedy pomijasz segment. Miejmy nadzieję, że większość ludzi tego nie wyłączy i liczniki wyświetleń będą wiarygodne. :)" }, "enableQueryByHashPrefix": { - "message": "Zapytanie Według Hash Prefix" + "message": "Zapytanie z użyciem funkcji skrótu" }, "whatQueryByHashPrefix": { - "message": "Zamiast żądać segmentów z serwera używając videoID, pierwsze 4 znaki haszu videoID'u są wysyłane. Ten serwer zwróci wszystkie dane dla wszystkich filmików z podobnymi hashami." + "message": "Zamiast wysyłać do serwera zapytanie o segmenty zawierające ID filmu, wysyłane są 4 pierwsze znaki hashu tego ID. Serwer zwróci dane dla wszystkich filmów z podobnymi hashami." }, "enableRefetchWhenNotFound": { - "message": "Pobierz na nowo segmenty z nowych filmów" + "message": "Ponawiaj pobieranie segmentów na nowych filmach" }, "whatRefetchWhenNotFound": { "message": "Jeśli film jest nowy i nie znaleziono żadnych segmentów, dane będą pobierane na nowo, co kilka minut, w czasie kiedy oglądasz." diff --git a/public/_locales/sk/messages.json b/public/_locales/sk/messages.json index 65396fc8..e05c256a 100644 --- a/public/_locales/sk/messages.json +++ b/public/_locales/sk/messages.json @@ -1,4 +1,8 @@ { + "fullName": { + "message": "SponsorBlock for YouTube - Skip Sponsorships", + "description": "Name of the extension." + }, "channelWhitelisted": { "message": "Kanál bol pridaný do whitelistu!" }, diff --git a/public/_locales/ta/messages.json b/public/_locales/ta/messages.json index db4a728e..a45725bc 100644 --- a/public/_locales/ta/messages.json +++ b/public/_locales/ta/messages.json @@ -1,6 +1,6 @@ { "fullName": { - "message": "YouTube க்கான ஸ்பான்சர் பிளாக் - ஸ்பான்சர்ஷிப்களைத் தவிர்", + "message": "YouTube க்கான SponsorBlock - ஸ்பான்சர்ஷிப்களைத் தவிர்", "description": "Name of the extension." }, "Description": { diff --git a/public/_locales/te/messages.json b/public/_locales/te/messages.json index bacae8cf..0c01162e 100644 --- a/public/_locales/te/messages.json +++ b/public/_locales/te/messages.json @@ -1,6 +1,6 @@ { "fullName": { - "message": "YouTube కోసం స్పాన్సర్‌బ్లాక్ - స్పాన్సర్‌షిప్‌లను దాటవేయి", + "message": "YouTube కోసం SponsorBlock - స్పాన్సర్‌షిప్‌లను దాటవేయి", "description": "Name of the extension." }, "Description": { diff --git a/public/_locales/vi/messages.json b/public/_locales/vi/messages.json index e40edb5f..c43a7651 100644 --- a/public/_locales/vi/messages.json +++ b/public/_locales/vi/messages.json @@ -497,6 +497,9 @@ "category_selfpromo": { "message": "Quảng cáo không trả công/Tự quảng cáo" }, + "category_selfpromo_description": { + "message": "Tương tự như 'nhà tài trợ' ngoại trừ việc quảng cáo không được trả tiền hay tự quảng cáo. Điều này bao gồm các phần hàng hóa, đóng góp, hoặc thông tin về người mà họ hợp tác với." + }, "category_music_offtopic": { "message": "Nhạc: Phần không nhạc" }, diff --git a/public/icons/check.svg b/public/icons/check.svg new file mode 100644 index 00000000..7ceda54b --- /dev/null +++ b/public/icons/check.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/pencil.svg b/public/icons/pencil.svg new file mode 100644 index 00000000..a14954fb --- /dev/null +++ b/public/icons/pencil.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/settings.svg b/public/icons/settings.svg new file mode 100644 index 00000000..d2fdae8f --- /dev/null +++ b/public/icons/settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/thumb.svg b/public/icons/thumb.svg new file mode 100644 index 00000000..c66bcdbd --- /dev/null +++ b/public/icons/thumb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/libs/Source+Sans+Pro.css b/public/libs/Source+Sans+Pro.css index 3a00466c..55a505fc 100644 --- a/public/libs/Source+Sans+Pro.css +++ b/public/libs/Source+Sans+Pro.css @@ -3,7 +3,7 @@ font-family: 'Source Sans Pro'; font-style: normal; font-weight: 400; - src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNa7lqDY.woff2) format('woff2'); + src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNa7lqDY.woff2) format('woff2'); unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; } /* cyrillic */ @@ -11,7 +11,7 @@ font-family: 'Source Sans Pro'; font-style: normal; font-weight: 400; - src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qPK7lqDY.woff2) format('woff2'); + src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xK3dSBYKcSV-LCoeQqfX1RYOo3qPK7lqDY.woff2) format('woff2'); unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } /* greek-ext */ @@ -19,7 +19,7 @@ font-family: 'Source Sans Pro'; font-style: normal; font-weight: 400; - src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNK7lqDY.woff2) format('woff2'); + src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNK7lqDY.woff2) format('woff2'); unicode-range: U+1F00-1FFF; } /* greek */ @@ -27,7 +27,7 @@ font-family: 'Source Sans Pro'; font-style: normal; font-weight: 400; - src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qO67lqDY.woff2) format('woff2'); + src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xK3dSBYKcSV-LCoeQqfX1RYOo3qO67lqDY.woff2) format('woff2'); unicode-range: U+0370-03FF; } /* vietnamese */ @@ -35,15 +35,15 @@ font-family: 'Source Sans Pro'; font-style: normal; font-weight: 400; - src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qN67lqDY.woff2) format('woff2'); - unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB; + src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xK3dSBYKcSV-LCoeQqfX1RYOo3qN67lqDY.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; } /* latin-ext */ @font-face { font-family: 'Source Sans Pro'; font-style: normal; font-weight: 400; - src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNq7lqDY.woff2) format('woff2'); + src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNq7lqDY.woff2) format('woff2'); unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; } /* latin */ @@ -51,6 +51,62 @@ font-family: 'Source Sans Pro'; font-style: normal; font-weight: 400; - src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7l.woff2) format('woff2'); + src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7l.woff2) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } +/* cyrillic-ext */ +@font-face { + font-family: 'Source Sans Pro'; + font-style: normal; + font-weight: 700; + src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmhduz8A.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Source Sans Pro'; + font-style: normal; + font-weight: 700; + src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwkxduz8A.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: 'Source Sans Pro'; + font-style: normal; + font-weight: 700; + src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmxduz8A.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: 'Source Sans Pro'; + font-style: normal; + font-weight: 700; + src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlBduz8A.woff2) format('woff2'); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Source Sans Pro'; + font-style: normal; + font-weight: 700; + src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmBduz8A.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Source Sans Pro'; + font-style: normal; + font-weight: 700; + src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmRduz8A.woff2) format('woff2'); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Source Sans Pro'; + font-style: normal; + font-weight: 700; + src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlxdu.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} \ No newline at end of file diff --git a/public/popup.css b/public/popup.css index fab03e3d..5a9f7b01 100644 --- a/public/popup.css +++ b/public/popup.css @@ -1,242 +1,361 @@ -/* reset some properties to default (youtube messes with them */ -p.popupElement { - margin-block-start: 1em; - margin-block-end: 1em; - margin-inline-start: 0px; - margin-inline-end: 0px; +:root { + --sb-main-bg-color: #222626; + --sb-main-fg-color: white; + --sb-gray-fg-color: #444848; + --sb-on-white-bg: black; + --sb-green-bg: #077B27; } -h1.popupElement { - margin-block-start: 0.67em; - margin-block-end: 0.67em; - margin-inline-start: 0px; - margin-inline-end: 0px; - font-weight: bold; +.hidden { + display: none !important; } -h2.popupElement { - margin-block-start: 0.83em; - margin-block-end: 0.83em; - margin-inline-start: 0px; - margin-inline-end: 0px; - font-weight: bold; +#sponsorblockPopup { + color: var(--sb-main-fg-color); + font-family: 'Source Sans Pro', sans-serif; + font-size: 14px; + display: flex; + flex-flow: column nowrap; + align-items: center; + width: 330px; + margin: 22px; + text-align: center; } -h3.popupElement { - margin-block-start: 1em; - margin-block-end: 1em; - margin-inline-start: 0px; - margin-inline-end: 0px; - font-weight: bold; +#issueReporterTimeButtons > .votingButtons > .segmentTimeButton { + font-weight: bold; + color: var(--sb-main-fg-color); + background: none; + border: none; + padding: 10px 8px; + outline: none; + + cursor: pointer; } -sub.popupElement { - font-size: smaller; +.dot { + height: 10px; + width: 10px; + border-radius: 50%; + display: inline-block; } -/* end reset */ -#sponsorBlockPopupLogo { - vertical-align: text-bottom; +.sponsorTimesThanksForVotingText { + font-size: large; +} + +.voteButton { + height: 20px; + padding: 0 5px; + + cursor: pointer; +} + +#videoInfo>p, #videoInfo>div>p { + margin: 0; +} + +div.logoText { + display: flex; + flex-flow: row nowrap; + align-items: center; + color: var(--sb-main-fg-color); +} + +div.logoText>p, .sbHeader { + font-size: 32px; + margin: -4px 0 -2px; + font-weight: bold; +} + +.sbHeader.sbSubHeader { + font-size: 20px; +} + +.largeButton{ + background: white; + /*font-weight: bold;*/ + padding: 6px 24px; + font-size: 20px; + border-radius: 25px; + border: none; + text-decoration: none; + color: black; + min-height: 26px; + min-width: 152px; + display: block; + overflow: hidden; + text-overflow: ellipsis; + font-family: 'Source Sans Pro', sans-serif; +} + +.sponsorBlockPageBody .mediumButton { + background-color:#cc1717; + -moz-border-radius:28px; + -webkit-border-radius:28px; + border-radius:28px; + border: none; + display:inline-block; + cursor:pointer; + color:#ffffff; + font-size:16px; + padding:8px 37px; + text-decoration:none; + text-shadow:0px 0px 0px #662727; + font-family: 'Source Sans Pro', sans-serif; + + transition: 0.01s background-color; +} +.sponsorBlockPageBody .mediumButton:hover { + background-color:#ec1c1c; +} +.sponsorBlockPageBody .mediumButton:focus { +outline: none; +background-color:#ec1c1c; +} +.sponsorBlockPageBody .mediumButton:active { + position:relative; + top:1px; +} + +/* disable extension */ + +#disableExtension { + display: flex; + flex-flow: column nowrap; + align-items: center; +} + +/* switch button */ + +.toggleSwitchContainer { + display: flex; + cursor: pointer; +} + +.switchBg { + display: block; + height: 37px; + width: 78px; + border-radius: 18.5px; +} + +.switchBg.shadow { + background: none; + box-shadow: 0.75px 0.75px 10px 0px rgba(50, 50, 50, 0.5); + opacity: 1; +} + +.switchBg.white { + position: absolute; + background: white; + opacity: 1; +} + +.switchBg.green { + position: absolute; + background: #00a205; + opacity: 0; + transition: opacity .2s ease-out; +} + +.switchDot { + width: 25px; + height: 25px; + margin: 6px; + background: white; + position: absolute; + border-radius: 12.5px; + box-shadow: .75px .75px 3.8px 0px rgba(50, 50, 50, 0.45); + transition: transform .2s ease-out; +} + +.preload * { + transition: none !important; +} + +#toggleSwitch:checked~.switchDot { + transform: translateX(40px); +} + +#toggleSwitch:checked~.switchBg.green { + opacity: 1 !important; +} + +#toggleSwitch:checked~.switchBg.white { + opacity: 0 !important; + transition: opacity .2s step-end; +} + +.sidebyside { + display: flex; + flex-flow: row nowrap; + width: 88%; + margin: 0 6% 0 6%; +} + +.sidebyside>div { + width: 50%; + justify-content: center; +} + +#whitelistButton, #sponsorTimesSkipsDoneContainer, .toggleSwitchContainer { + margin-bottom: 2px !important; +} + +#whitelistForceCheck { + font-weight: bold; + text-decoration: underline; + font-size: large; + cursor: pointer; + padding: 10px 0; +} + +.sbHeader { + margin-bottom: 5px !important; } .logoText { - color: white; + margin-bottom: 6px !important; } -h1.popupElement { - margin-top: 0px; - margin-bottom: 10px; +#videoInfo, #mainControls, .sidebyside, #sponsorTimesSkipsDoneContainer, .largeButton { + margin-bottom: 12px !important; +} +#mainControls{ + flex-flow: column; + align-items: center; +} +#submitTimesContainer{ + flex-flow: column; + align-items: center; +} +/* additional buttons */ + +#additionalButtons { + display: flex; + flex-flow: column nowrap; + align-items: center; } -.popupBody { - font-size: 14px; - background-color: #333; - padding: 0px 5px; +#additionalButtons>button, button#setUsernameButton, #submitUsername { + background: none; + border: none; + color: white; + width: fit-content; + padding-left: 0; - font-family: 'Source Sans Pro', sans-serif; - - color: #dddddd; + cursor: pointer; } -.outerPopupBody { - background-color: #222626; - overflow-y: scroll; +#submitUsername { + padding-left: 5pt; } -.discreteLink.popupElement { - color: #dddddd; +#additionalButtons, #additionalButtons>button { + font-size: 15px; } -.recordingSubtitle.popupElement { - margin-bottom: 10px; +#usernameValue, #usernameInput, #sponsorTimesContributionsDisplay{ + font-size: 16px; } -.voteButton.popupElement { - height: 32px; - margin-right: 15px; - cursor: pointer; -} -.voteButton:hover.popupElement { - filter: brightness(80%); +.SBWhitelistIcon { + min-width: 16px; + min-height: 16px; + margin-top: auto; + margin-bottom: auto; + + height: 100%; } -#discordButtonContainer.popupElement { - font-size: 12px; +.SBWhitelistIcon>path { + fill: var(--sb-main-fg-color); } -.sponsorTime.popupElement { - font-size: 20px; +label>p, #disableExtension>p, #usernameValue, #usernameElement > div > p,#sponsorTimesContributionsContainer > div > p, #usernameElement > div > #setUsername > #setUsernameStatusContainer > p { + margin: 0; } -.smallLink.popupElement { - font-size: 10px; - text-decoration: underline; - cursor: pointer; +#usernameElement > div > p, #sponsorTimesContributionsContainer { + text-align: start; } -.mediumLink.popupElement { - font-size: 15px; - margin-left: 25px; - margin-right: 25px; - text-decoration: underline; - cursor: pointer; +.grayedOut>.SBWhitelistIcon>path { + fill: var(--sb-gray-fg-color); } -.tinyLink.popupElement { - font-size: 10px; - text-decoration: underline; - cursor: pointer; +.grayedOut>label { + color: var(--sb-gray-fg-color); } -.whitelistButton.popupElement { - background-color:#27a52d; - -moz-border-radius:28px; - -webkit-border-radius:28px; - border-radius:28px; - border: none; - display:inline-block; - cursor:pointer; - color:#ffffff; - font-size:16px; - padding:8px 37px; - text-decoration:none; - text-shadow:0px 0px 0px #27663c; - - transition: 0.01s background-color; -} -.whitelistButton:hover.popupElement { - background-color:#3acc3a; -} -.whitelistButton:focus.popupElement { - outline: none; - background-color:#3acc3a; -} -.whitelistButton:active.popupElement { - position:relative; - top:1px; +.SBWhitelistIcon.rotated { + transform: rotate(45deg); } -.greenButton.popupElement { - background-color:#cc1717; - -moz-border-radius:28px; - -webkit-border-radius:28px; - border-radius:28px; - border: none; - display:inline-block; - cursor:pointer; - color:#ffffff; - font-size:16px; - padding:8px 37px; - text-decoration:none; - text-shadow:0px 0px 0px #662727; - - transition: 0.01s background-color; -} -.greenButton:hover.popupElement { - background-color:#ec1c1c; -} -.greenButton:focus.popupElement { - outline: none; - background-color:#ec1c1c; -} -.greenButton:active.popupElement { - position:relative; - top:1px; +.SBWhitelistIconContainer, button#optionsButton>img, .logoText>img, #usernameValue { + margin-right: 8px; } -.dangerButton.popupElement { - background-color:#bc3315; - -moz-border-radius:3px; - -webkit-border-radius:3px; - border-radius:3px; - border: none; - display:inline-block; - cursor:pointer; - color:#ffffff; - font-size:13px; - padding:6px 24px; - text-decoration:none; - text-shadow:0px 1px 0px #854629; -} -.dangerButton:hover.popupElement { - background-color:#d0451b; -} -.dangerButton:focus.popupElement { - outline: none; - background-color:#d0451b; -} -.dangerButton:active.popupElement { - position:relative; - top:1px; +#whitelistButton>label, #additionalButtons>button, div#setUsernameContainer { + display: flex; + flex-flow: row nowrap; } -.warningButton.popupElement { - background-color:#bc8215; - -moz-border-radius:3px; - -webkit-border-radius:3px; - border-radius:3px; - border: none; - display:inline-block; - cursor:pointer; - color:#ffffff; - font-size:13px; - padding:6px 24px; - text-decoration:none; - text-shadow:0px 1px 0px #856829; -} -.warningButton:hover.popupElement { - background-color:#d0821b; -} -.warningButton:focus.popupElement { - outline: none; - background-color:#d0821b; -} -.warningButton:active.popupElement { - position:relative; - top:1px; +#whitelistButton>label, #additionalButtons>button, div#setUsernameContainer>button { + cursor: pointer; } -.smallButton.popupElement { - background-color:#f9902d; - -moz-border-radius:3px; - -webkit-border-radius:3px; - border-radius:3px; - border:1px solid #f9a72d; - display:inline-block; - cursor:pointer; - color:#ffffff; - font-size:14px; - padding:6px 10px; - text-decoration:none; +#usernameElement > div, #sponsorTimesContributionsContainer > div { + display: flex; + flex-flow: column nowrap; + align-items: flex-start; } -.smallButton:hover.popupElement { - background-color:#fa9806; + +.sidebyside > #usernameElement, .sidebyside > #sponsorTimesContributionsContainer { + display: flex; + align-items: center; } -.smallButton:focus.popupElement { - outline: none; - background-color:#fa9806; + +#usernameValue{ + overflow: hidden; + text-overflow: ellipsis; + max-width: 130px; +} + +#setUsername { + display:flex; +} + +#usernameInput { + background: none; + padding: 0; + border: white 1px solid; + color: var(--sb-main-fg-color); + width: calc(100% - 24px); + + text-overflow: ellipsis; +} + +#setUsername.SBExpanded { + width: 200%; +} + +/* footer */ + +#sbFooter > a { + color: var(--sb-main-fg-color); + text-decoration: none; +} + +#showNoticeAgain { + margin-top: 30px; + + color: var(--sb-main-fg-color); + background: none; + border: 1px solid white; + cursor: pointer; + padding: 5px; + + border-radius: 5px; } -.smallButton:active.popupElement { - position:relative; - top:1px; -} \ No newline at end of file diff --git a/public/popup.html b/public/popup.html index d977724e..80755e8b 100644 --- a/public/popup.html +++ b/public/popup.html @@ -1,203 +1,146 @@ - - - - - + + __MSG_openPopup__ + + + - -
-
-

- - SponsorBlock -

- - -

__MSG_noVideoID__

- - -
- + + + + + + +

__MSG_yourWork__

+
+
+
+

__MSG_Username__:

+
+

+ +
+ +
+
+ +
+ + + + + + + - - - + + + \ No newline at end of file diff --git a/src/background.ts b/src/background.ts index 8326d8e1..2bab479f 100644 --- a/src/background.ts +++ b/src/background.ts @@ -32,6 +32,9 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) { case "openConfig": chrome.runtime.openOptionsPage(); return; + case "openHelp": + window.open(chrome.runtime.getURL('help/index_en.html')); + return; case "sendRequest": sendRequestToCustomServer(request.type, request.url, request.data).then(async (response) => { callback({ diff --git a/src/content.ts b/src/content.ts index 07c2b477..d58fb524 100644 --- a/src/content.ts +++ b/src/content.ts @@ -1125,7 +1125,7 @@ async function createButtons(): Promise { let createdButton = false; // Add button if does not already exist in html - createdButton = createButton("startSponsor", "sponsorStart", startSponsorClicked, "PlayerStartIconSponsorBlocker256px.png") || createdButton; + createdButton = createButton("startSponsor", "sponsorStart", startSponsorClicked, "PlayerStartIconSponsorBlocker256px.png") || createdButton; createdButton = createButton("info", "openPopup", openInfoMenu, "PlayerInfoIconSponsorBlocker256px.png") || createdButton; createdButton = createButton("delete", "clearTimes", clearSponsorTimes, "PlayerDeleteIconSponsorBlocker256px.png") || createdButton; createdButton = createButton("submit", "SubmitTimes", submitSponsorTimes, "PlayerUploadIconSponsorBlocker256px.png") || createdButton; @@ -1275,9 +1275,17 @@ function openInfoMenu() { sendRequestToCustomServer('GET', chrome.extension.getURL("popup.html"), function(xmlhttp) { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { - const popup = document.createElement("div"); + let popup = document.createElement("div"); popup.id = "sponsorBlockPopupContainer"; - popup.innerHTML = xmlhttp.responseText + + let htmlData = xmlhttp.responseText; + // Hack to replace head data (title, favicon) + htmlData = htmlData.replace(/[\S\s]*<\/head>/gi, ""); + // Hack to replace body tag with div + htmlData = htmlData.replace(/ popup.querySelector("#sponsorBlockPopupLogo"); + let logo = popup.querySelector("#sponsorBlockPopupLogo"); + let settings = popup.querySelector("#sbPopupIconSettings"); + let edit = popup.querySelector("#sbPopupIconEdit"); + let check = popup.querySelector("#sbPopupIconCheck"); logo.src = chrome.extension.getURL("icons/LogoSponsorBlocker256px.png"); - - //remove the style sheet and font that are not necessary - popup.querySelector("#sponsorBlockPopupFont").remove(); - popup.querySelector("#sponsorBlockStyleSheet").remove(); + settings.src = chrome.extension.getURL("icons/settings.svg"); + edit.src = chrome.extension.getURL("icons/pencil.svg"); + check.src = chrome.extension.getURL("icons/check.svg"); + check.src = chrome.extension.getURL("icons/thumb.svg"); parentNode.insertBefore(popup, parentNode.firstChild); diff --git a/src/popup.ts b/src/popup.ts index 961a5bdd..81f92b00 100644 --- a/src/popup.ts +++ b/src/popup.ts @@ -33,7 +33,7 @@ class MessageHandler { } else { chrome.tabs.query(config, callback); } - + } } @@ -47,121 +47,109 @@ async function runThePopup(messageListener?: MessageListener): Promise { const PageElements: any = {}; - ["sponsorStart", - // Top toggles - "whitelistChannel", - "unwhitelistChannel", - "whitelistForceCheck", - "disableSkipping", - "enableSkipping", - // Options - "showNoticeAgain", - "optionsButton", - // More controls - "submitTimes", - "reportAnIssue", - // sponsorTimesContributions - "sponsorTimesContributionsContainer", - "sponsorTimesContributionsDisplay", - "sponsorTimesContributionsDisplayEndWord", - // sponsorTimesViewsDisplay - "sponsorTimesViewsContainer", - "sponsorTimesViewsDisplay", - "sponsorTimesViewsDisplayEndWord", - // sponsorTimesOthersTimeSaved - "sponsorTimesOthersTimeSavedContainer", - "sponsorTimesOthersTimeSavedDisplay", - "sponsorTimesOthersTimeSavedEndWord", - // sponsorTimesSkipsDone - "sponsorTimesSkipsDoneContainer", - "sponsorTimesSkipsDoneDisplay", - "sponsorTimesSkipsDoneEndWord", - // sponsorTimeSaved - "sponsorTimeSavedContainer", - "sponsorTimeSavedDisplay", - "sponsorTimeSavedEndWord", - // discordButtons - "discordButtonContainer", - "hideDiscordButton", - // Username - "setUsernameContainer", - "setUsernameButton", - "setUsernameStatusContainer", - "setUsernameStatus", - "setUsername", - "usernameInput", - "submitUsername", - // More - "submissionSection", - "mainControls", - "loadingIndicator", - "videoFound", - "sponsorMessageTimes", - "downloadedSponsorMessageTimes", + [ + "sponsorblockPopup", + "sponsorStart", + // Top toggles + "whitelistChannel", + "unwhitelistChannel", + "whitelistToggle", + "whitelistForceCheck", + "disableSkipping", + "enableSkipping", + "toggleSwitch", + // Options + "showNoticeAgain", + "optionsButton", + "helpButton", + // More controls + "submitTimes", + "sponsorTimesContributionsContainer", + "sponsorTimesContributionsDisplay", + "sponsorTimesViewsContainer", + "sponsorTimesViewsDisplay", + "sponsorTimesViewsDisplayEndWord", + "sponsorTimesOthersTimeSavedDisplay", + "sponsorTimesOthersTimeSavedEndWord", + "sponsorTimesSkipsDoneContainer", + "sponsorTimesSkipsDoneDisplay", + "sponsorTimesSkipsDoneEndWord", + "sponsorTimeSavedDisplay", + "sponsorTimeSavedEndWord", + // Username + "setUsernameContainer", + "setUsernameButton", + "setUsernameStatusContainer", + "setUsernameStatus", + "setUsername", + "usernameInput", + "usernameValue", + "submitUsername", + // More + "submissionSection", + "mainControls", + "loadingIndicator", + "videoFound", + "sponsorMessageTimes", + //"downloadedSponsorMessageTimes", + "whitelistButton", ].forEach(id => PageElements[id] = document.getElementById(id)); //setup click listeners PageElements.sponsorStart.addEventListener("click", sendSponsorStartMessage); - PageElements.whitelistChannel.addEventListener("click", whitelistChannel); + PageElements.whitelistToggle.addEventListener("change", function() { + if (this.checked) { + whitelistChannel(); + } else { + unwhitelistChannel(); + } + }); PageElements.whitelistForceCheck.addEventListener("click", openOptions); - PageElements.unwhitelistChannel.addEventListener("click", unwhitelistChannel); - PageElements.disableSkipping.addEventListener("click", () => toggleSkipping(true)); - PageElements.enableSkipping.addEventListener("click", () => toggleSkipping(false)); + PageElements.toggleSwitch.addEventListener("change", function() { + toggleSkipping(!this.checked); + }); PageElements.submitTimes.addEventListener("click", submitTimes); PageElements.showNoticeAgain.addEventListener("click", showNoticeAgain); PageElements.setUsernameButton.addEventListener("click", setUsernameButton); + PageElements.usernameValue.addEventListener("click", setUsernameButton); PageElements.submitUsername.addEventListener("click", submitUsername); PageElements.optionsButton.addEventListener("click", openOptions); - PageElements.reportAnIssue.addEventListener("click", reportAnIssue); - PageElements.hideDiscordButton.addEventListener("click", hideDiscordButton); - + PageElements.helpButton.addEventListener("click", openHelp); + //if true, the button now selects the end time let startTimeChosen = false; - + //the start and end time pairs (2d) let sponsorTimes: SponsorTime[] = []; - + //current video ID of this tab let currentVideoID = null; - - //see if discord link can be shown - const hideDiscordLink = Config.config.hideDiscordLink; - if (hideDiscordLink == undefined || !hideDiscordLink) { - let hideDiscordLaunches = Config.config.hideDiscordLaunches; - //only if less than 10 launches - if (hideDiscordLaunches == undefined || hideDiscordLaunches < 10) { - PageElements.discordButtonContainer.style.display = null; - - if (hideDiscordLaunches == undefined) { - hideDiscordLaunches = 1; - } - Config.config.hideDiscordLaunches = hideDiscordLaunches + 1; - } - } //show proper disable skipping button const disableSkipping = Config.config.disableSkipping; if (disableSkipping != undefined && disableSkipping) { PageElements.disableSkipping.style.display = "none"; PageElements.enableSkipping.style.display = "unset"; + PageElements.toggleSwitch.checked = false; } - //if the don't show notice again variable is true, an option to + //if the don't show notice again variable is true, an option to // disable should be available const dontShowNotice = Config.config.dontShowNotice; if (dontShowNotice != undefined && dontShowNotice) { PageElements.showNoticeAgain.style.display = "unset"; } + utils.sendRequestToServer("GET", "/api/getUsername?userID=" + Config.config.userID, (res) => { + if (res.status === 200) { + PageElements.usernameValue.innerText = JSON.parse(res.responseText).userName + } + }) + //get the amount of times this user has contributed and display it to thank them if (Config.config.sponsorTimesContributed != undefined) { - if (Config.config.sponsorTimesContributed !== 1) { - PageElements.sponsorTimesContributionsDisplayEndWord.innerText = chrome.i18n.getMessage("Segments"); - } else { - PageElements.sponsorTimesContributionsDisplayEndWord.innerText = chrome.i18n.getMessage("Segment"); - } - PageElements.sponsorTimesContributionsDisplay.innerText = Config.config.sponsorTimesContributed; - PageElements.sponsorTimesContributionsContainer.style.display = "unset"; + PageElements.sponsorTimesContributionsDisplay.innerText = Config.config.sponsorTimesContributed.toLocaleString(); + PageElements.sponsorTimesContributionsContainer.classList.remove("hidden"); //get the userID const userID = Config.config.userID; @@ -178,7 +166,7 @@ async function runThePopup(messageListener?: MessageListener): Promise { PageElements.sponsorTimesViewsDisplayEndWord.innerText = chrome.i18n.getMessage("Segment"); } - PageElements.sponsorTimesViewsDisplay.innerText = viewCount; + PageElements.sponsorTimesViewsDisplay.innerText = viewCount.toLocaleString(); PageElements.sponsorTimesViewsContainer.style.display = "unset"; } } @@ -196,7 +184,6 @@ async function runThePopup(messageListener?: MessageListener): Promise { } PageElements.sponsorTimesOthersTimeSavedDisplay.innerText = getFormattedHours(minutesSaved); - PageElements.sponsorTimesOthersTimeSavedContainer.style.display = "unset"; } } }); @@ -211,7 +198,7 @@ async function runThePopup(messageListener?: MessageListener): Promise { PageElements.sponsorTimesSkipsDoneEndWord.innerText = chrome.i18n.getMessage("Segment"); } - PageElements.sponsorTimesSkipsDoneDisplay.innerText = Config.config.skipCount; + PageElements.sponsorTimesSkipsDoneDisplay.innerText = Config.config.skipCount.toLocaleString(); PageElements.sponsorTimesSkipsDoneContainer.style.display = "unset"; } @@ -224,14 +211,16 @@ async function runThePopup(messageListener?: MessageListener): Promise { } PageElements.sponsorTimeSavedDisplay.innerText = getFormattedHours(Config.config.minutesSaved); - PageElements.sponsorTimeSavedContainer.style.display = "unset"; } - + + // Must be delayed so it only happens once loaded + setTimeout(() => PageElements.sponsorblockPopup.classList.remove("preload"), 250); + messageHandler.query({ active: true, currentWindow: true }, onTabs); - + function onTabs(tabs) { messageHandler.sendMessage(tabs[0].id, {message: 'getVideoID'}, function(result) { if (result != undefined && result.videoID) { @@ -250,9 +239,9 @@ async function runThePopup(messageListener?: MessageListener): Promise { displayNoVideo(); return; } - - //load video times for this video - const sponsorTimesStorage = Config.config.segmentTimes.get(currentVideoID); + + //load video times for this video + let sponsorTimesStorage = Config.config.segmentTimes.get(currentVideoID); if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) { if (sponsorTimesStorage[sponsorTimesStorage.length - 1] != undefined && sponsorTimesStorage[sponsorTimesStorage.length - 1].segment.length < 2) { startTimeChosen = true; @@ -266,7 +255,7 @@ async function runThePopup(messageListener?: MessageListener): Promise { showSubmitTimesIfNecessary(); } - + //check if this video's sponsors are known messageHandler.sendMessage( tabs[0].id, @@ -274,18 +263,19 @@ async function runThePopup(messageListener?: MessageListener): Promise { infoFound ); } - + function infoFound(request: {found: boolean, sponsorTimes: SponsorTime[]}) { if(chrome.runtime.lastError) { //This page doesn't have the injected content script, or at least not yet displayNoVideo(); return; } - + //if request is undefined, then the page currently being browsed is not YouTube if (request != undefined) { //remove loading text - PageElements.mainControls.style.display = "unset" + PageElements.mainControls.style.display = "flex"; + PageElements.whitelistButton.classList.remove("hidden"); PageElements.loadingIndicator.style.display = "none"; if (request.found) { @@ -309,15 +299,14 @@ async function runThePopup(messageListener?: MessageListener): Promise { if (response.value) { PageElements.whitelistChannel.style.display = "none"; PageElements.unwhitelistChannel.style.display = "unset"; - - PageElements.downloadedSponsorMessageTimes.innerText = chrome.i18n.getMessage("channelWhitelisted"); - PageElements.downloadedSponsorMessageTimes.style.fontWeight = "bold"; + PageElements.whitelistToggle.checked = true; + document.querySelectorAll('.SBWhitelistIcon')[0].classList.add("rotated"); } }); } ); } - + function sendSponsorStartMessage() { //the content script will get the message if a YouTube page is open messageHandler.query({ @@ -331,10 +320,10 @@ async function runThePopup(messageListener?: MessageListener): Promise { ); }); } - + function startSponsorCallback(response) { - const sponsorTimesIndex = sponsorTimes.length - (startTimeChosen ? 1 : 0); - + let sponsorTimesIndex = sponsorTimes.length - (startTimeChosen ? 1 : 0); + if (sponsorTimes[sponsorTimesIndex] == undefined) { sponsorTimes[sponsorTimesIndex] = { segment: [], @@ -342,12 +331,12 @@ async function runThePopup(messageListener?: MessageListener): Promise { UUID: null }; } - + sponsorTimes[sponsorTimesIndex].segment[startTimeChosen ? 1 : 0] = response.time; const localStartTimeChosen = startTimeChosen; Config.config.segmentTimes.set(currentVideoID, sponsorTimes); - + //send a message to the client script if (localStartTimeChosen) { messageHandler.query({ @@ -360,391 +349,102 @@ async function runThePopup(messageListener?: MessageListener): Promise { ); }); } - + updateStartTimeChosen(); - + //show submission section PageElements.submissionSection.style.display = "unset"; - + showSubmitTimesIfNecessary(); } - + //display the video times from the array at the top, in a different section function displayDownloadedSponsorTimes(request: {found: boolean, sponsorTimes: SponsorTime[]}) { if (request.sponsorTimes != undefined) { - //set it to the message - if (PageElements.downloadedSponsorMessageTimes.innerText != chrome.i18n.getMessage("channelWhitelisted")) { - PageElements.downloadedSponsorMessageTimes.innerText = getSponsorTimesMessage(request.sponsorTimes); - } + + // Sort list by start time + let segmentTimes = request.sponsorTimes + .sort((a, b) => a.segment[1] - b.segment[1]) + .sort((a, b) => a.segment[0] - b.segment[0]); //add them as buttons to the issue reporting container - const container = document.getElementById("issueReporterTimeButtons"); - for (let i = 0; i < request.sponsorTimes.length; i++) { - const sponsorTimeButton = document.createElement("button"); - sponsorTimeButton.className = "warningButton popupElement"; + let container = document.getElementById("issueReporterTimeButtons"); + for (let i = 0; i < segmentTimes.length; i++) { + let UUID = segmentTimes[i].UUID; + + let sponsorTimeButton = document.createElement("button"); + sponsorTimeButton.className = "segmentTimeButton popupElement"; + + let prefix = chrome.i18n.getMessage("category_" + segmentTimes[i].category) + ": "; let extraInfo = ""; - if (request.sponsorTimes[i].hidden === SponsorHideType.Downvoted) { + if (segmentTimes[i].hidden === SponsorHideType.Downvoted) { //this one is downvoted extraInfo = " (" + chrome.i18n.getMessage("hiddenDueToDownvote") + ")"; - } else if (request.sponsorTimes[i].hidden === SponsorHideType.MinimumDuration) { + } else if (segmentTimes[i].hidden === SponsorHideType.MinimumDuration) { //this one is too short extraInfo = " (" + chrome.i18n.getMessage("hiddenDueToDuration") + ")"; } - sponsorTimeButton.innerText = getFormattedTime(request.sponsorTimes[i].segment[0]) + " " + chrome.i18n.getMessage("to") + " " + getFormattedTime(request.sponsorTimes[i].segment[1]) + extraInfo; - - const votingButtons = document.createElement("div"); - - const UUID = request.sponsorTimes[i].UUID; - + sponsorTimeButton.innerText = prefix + getFormattedTime(segmentTimes[i].segment[0]) + " " + chrome.i18n.getMessage("to") + " " + getFormattedTime(segmentTimes[i].segment[1]) + extraInfo; + + let categoryColorCircle = document.createElement("span"); + categoryColorCircle.id = "sponsorTimesCategoryColorCircle" + UUID; + categoryColorCircle.style.backgroundColor = Config.config.barTypes[segmentTimes[i].category].color; + categoryColorCircle.classList.add("dot"); + categoryColorCircle.classList.add("sponsorTimesCategoryColorCircle"); + + let votingButtons = document.createElement("div"); + votingButtons.classList.add("votingButtons"); + //thumbs up and down buttons const voteButtonsContainer = document.createElement("div"); voteButtonsContainer.id = "sponsorTimesVoteButtonsContainer" + UUID; voteButtonsContainer.setAttribute("align", "center"); voteButtonsContainer.style.display = "none" - - const upvoteButton = document.createElement("img"); + + let upvoteButton = document.createElement("img"); upvoteButton.id = "sponsorTimesUpvoteButtonsContainer" + UUID; - upvoteButton.className = "voteButton popupElement"; - upvoteButton.src = chrome.extension.getURL("icons/upvote.png"); + upvoteButton.className = "voteButton"; + upvoteButton.src = chrome.extension.getURL("icons/thumbs_up.svg"); upvoteButton.addEventListener("click", () => vote(1, UUID)); - - const downvoteButton = document.createElement("img"); + + let downvoteButton = document.createElement("img"); downvoteButton.id = "sponsorTimesDownvoteButtonsContainer" + UUID; - downvoteButton.className = "voteButton popupElement"; - downvoteButton.src = chrome.extension.getURL("icons/downvote.png"); + downvoteButton.className = "voteButton"; + downvoteButton.src = chrome.extension.getURL("icons/thumbs_down.svg"); downvoteButton.addEventListener("click", () => vote(0, UUID)); - + //add thumbs up and down buttons to the container - voteButtonsContainer.appendChild(document.createElement("br")); - voteButtonsContainer.appendChild(document.createElement("br")); voteButtonsContainer.appendChild(upvoteButton); voteButtonsContainer.appendChild(downvoteButton); - + //add click listener to open up vote panel sponsorTimeButton.addEventListener("click", function() { - voteButtonsContainer.style.display = "unset"; + voteButtonsContainer.style.removeProperty("display"); }); - - container.appendChild(sponsorTimeButton); - container.appendChild(voteButtonsContainer); - - //if it is not the last iteration - if (i != request.sponsorTimes.length - 1) { - container.appendChild(document.createElement("br")); - container.appendChild(document.createElement("br")); - } + + // Will contain request status + let voteStatusContainer = document.createElement("div"); + voteStatusContainer.id = "sponsorTimesVoteStatusContainer" + UUID; + voteStatusContainer.classList.add("sponsorTimesVoteStatusContainer"); + voteStatusContainer.style.display = "none"; + + let thanksForVotingText = document.createElement("div"); + thanksForVotingText.id = "sponsorTimesThanksForVotingText" + UUID; + thanksForVotingText.classList.add("sponsorTimesThanksForVotingText"); + voteStatusContainer.appendChild(thanksForVotingText); + + votingButtons.append(categoryColorCircle); + votingButtons.append(sponsorTimeButton); + votingButtons.append(voteButtonsContainer); + votingButtons.append(voteStatusContainer); + + container.appendChild(votingButtons); } } } - - //get the message that visually displays the video times - function getSponsorTimesMessage(sponsorTimes: SponsorTime[]) { - let sponsorTimesMessage = ""; - - for (let i = 0; i < sponsorTimes.length; i++) { - for (let s = 0; s < sponsorTimes[i].segment.length; s++) { - let timeMessage = getFormattedTime(sponsorTimes[i].segment[s]); - //if this is an end time - if (s == 1) { - timeMessage = " " + chrome.i18n.getMessage("to") + " " + timeMessage; - } else if (i > 0) { - //add commas if necessary - timeMessage = ", " + timeMessage; - } - if (sponsorTimes[i].hidden === SponsorHideType.Downvoted) { - //this one is downvoted - timeMessage += " (" + chrome.i18n.getMessage("hiddenDueToDownvote") + ")"; - } else if (sponsorTimes[i].hidden === SponsorHideType.MinimumDuration) { - //this one is too short - timeMessage += " (" + chrome.i18n.getMessage("hiddenDueToDuration") + ")"; - } - - sponsorTimesMessage += timeMessage; - } - } - - return sponsorTimesMessage; - } - - //get the message that visually displays the video times - //this version is a div that contains each with delete buttons - function getSponsorTimesMessageDiv(sponsorTimes) { - // let sponsorTimesMessage = ""; - const sponsorTimesContainer = document.createElement("div"); - sponsorTimesContainer.id = "sponsorTimesContainer"; - - for (let i = 0; i < sponsorTimes.length; i++) { - const currentSponsorTimeContainer = document.createElement("div"); - currentSponsorTimeContainer.id = "sponsorTimeContainer" + i; - currentSponsorTimeContainer.className = "sponsorTime popupElement"; - let currentSponsorTimeMessage = ""; - - const deleteButton = document.createElement("span"); - deleteButton.id = "sponsorTimeDeleteButton" + i; - deleteButton.innerText = "Delete"; - deleteButton.className = "mediumLink popupElement"; - const index = i; - deleteButton.addEventListener("click", () => deleteSponsorTime(index)); - - const previewButton = document.createElement("span"); - previewButton.id = "sponsorTimePreviewButton" + i; - previewButton.innerText = "Preview"; - previewButton.className = "mediumLink popupElement"; - previewButton.addEventListener("click", () => previewSponsorTime(index)); - - const editButton = document.createElement("span"); - editButton.id = "sponsorTimeEditButton" + i; - editButton.innerText = "Edit"; - editButton.className = "mediumLink popupElement"; - editButton.addEventListener("click", () => editSponsorTime(index)); - - for (let s = 0; s < sponsorTimes[i].length; s++) { - let timeMessage = getFormattedTime(sponsorTimes[i][s]); - //if this is an end time - if (s == 1) { - timeMessage = " " + chrome.i18n.getMessage("to") + " " + timeMessage; - } else if (i > 0) { - //add commas if necessary - timeMessage = timeMessage; - } - - currentSponsorTimeMessage += timeMessage; - } - - currentSponsorTimeContainer.innerText = currentSponsorTimeMessage; - - sponsorTimesContainer.appendChild(currentSponsorTimeContainer); - sponsorTimesContainer.appendChild(deleteButton); - - //only if it is a complete sponsor time - if (sponsorTimes[i].length > 1) { - sponsorTimesContainer.appendChild(previewButton); - sponsorTimesContainer.appendChild(editButton); - - currentSponsorTimeContainer.addEventListener("click", () => editSponsorTime(index)); - } - } - - return sponsorTimesContainer; - } - - function previewSponsorTime(index) { - let skipTime = sponsorTimes[index].segment[0]; - - if (document.getElementById("startTimeMinutes" + index) != null) { - //edit is currently open, use that time - - skipTime = getSponsorTimeEditTimes("startTime", index); - - //save the edit - saveSponsorTimeEdit(index, false); - } - - messageHandler.query({ - active: true, - currentWindow: true - }, tabs => { - messageHandler.sendMessage( - tabs[0].id, { - message: "skipToTime", - time: skipTime - 2 - } - ); - }); - } - - function editSponsorTime(index) { - if (document.getElementById("startTimeMinutes" + index) != null) { - //already open - return; - } - - //hide submit button - document.getElementById("submitTimesContainer").style.display = "none"; - - const sponsorTimeContainer = document.getElementById("sponsorTimeContainer" + index); - - //the button to set the current time - const startTimeNowButton = document.createElement("span"); - startTimeNowButton.id = "startTimeNowButton" + index; - startTimeNowButton.innerText = "(Now)"; - startTimeNowButton.className = "tinyLink popupElement"; - startTimeNowButton.addEventListener("click", () => setEditTimeToCurrentTime("startTime", index)); - - //get sponsor time minutes and seconds boxes - const startTimeMinutes = document.createElement("input"); - startTimeMinutes.id = "startTimeMinutes" + index; - startTimeMinutes.className = "sponsorTime popupElement"; - startTimeMinutes.type = "text"; - startTimeMinutes.value = String(getTimeInMinutes(sponsorTimes[index].segment[0])); - startTimeMinutes.style.width = "45px"; - - const startTimeSeconds = document.createElement("input"); - startTimeSeconds.id = "startTimeSeconds" + index; - startTimeSeconds.className = "sponsorTime popupElement"; - startTimeSeconds.type = "text"; - startTimeSeconds.value = getTimeInFormattedSeconds(sponsorTimes[index].segment[0]); - startTimeSeconds.style.width = "60px"; - - const endTimeMinutes = document.createElement("input"); - endTimeMinutes.id = "endTimeMinutes" + index; - endTimeMinutes.className = "sponsorTime popupElement"; - endTimeMinutes.type = "text"; - endTimeMinutes.value = String(getTimeInMinutes(sponsorTimes[index].segment[1])); - endTimeMinutes.style.width = "45px"; - - const endTimeSeconds = document.createElement("input"); - endTimeSeconds.id = "endTimeSeconds" + index; - endTimeSeconds.className = "sponsorTime popupElement"; - endTimeSeconds.type = "text"; - endTimeSeconds.value = getTimeInFormattedSeconds(sponsorTimes[index].segment[1]); - endTimeSeconds.style.width = "60px"; - - //the button to set the current time - const endTimeNowButton = document.createElement("span"); - endTimeNowButton.id = "endTimeNowButton" + index; - endTimeNowButton.innerText = "(Now)"; - endTimeNowButton.className = "tinyLink popupElement"; - endTimeNowButton.addEventListener("click", () => setEditTimeToCurrentTime("endTime", index)); - - const colonText = document.createElement("span"); - colonText.innerText = ":"; - - const toText = document.createElement("span"); - toText.innerText = " " + chrome.i18n.getMessage("to") + " "; - - //remove all children to replace - while (sponsorTimeContainer.firstChild) { - sponsorTimeContainer.removeChild(sponsorTimeContainer.firstChild); - } - - sponsorTimeContainer.appendChild(startTimeNowButton); - sponsorTimeContainer.appendChild(startTimeMinutes); - sponsorTimeContainer.appendChild(colonText); - sponsorTimeContainer.appendChild(startTimeSeconds); - sponsorTimeContainer.appendChild(toText); - sponsorTimeContainer.appendChild(endTimeMinutes); - sponsorTimeContainer.appendChild(colonText); - sponsorTimeContainer.appendChild(endTimeSeconds); - sponsorTimeContainer.appendChild(endTimeNowButton); - - //add save button and remove edit button - const saveButton = document.createElement("span"); - saveButton.id = "sponsorTimeSaveButton" + index; - saveButton.innerText = "Save"; - saveButton.className = "mediumLink popupElement"; - saveButton.addEventListener("click", () => saveSponsorTimeEdit(index)); - - const editButton = document.getElementById("sponsorTimeEditButton" + index); - const sponsorTimesContainer = document.getElementById("sponsorTimesContainer"); - - sponsorTimesContainer.replaceChild(saveButton, editButton); - } - - function setEditTimeToCurrentTime(idStartName, index) { - messageHandler.query({ - active: true, - currentWindow: true - }, tabs => { - messageHandler.sendMessage( - tabs[0].id, - {message: "getCurrentTime"}, - function (response) { - const minutes = document.getElementById(idStartName + "Minutes" + index); - const seconds = document.getElementById(idStartName + "Seconds" + index); - - minutes.value = String(getTimeInMinutes(response.currentTime)); - seconds.value = getTimeInFormattedSeconds(response.currentTime); - }); - }); - } - - //id start name is whether it is the startTime or endTime - //gives back the time in seconds - function getSponsorTimeEditTimes(idStartName, index): number { - const minutes = document.getElementById(idStartName + "Minutes" + index); - const seconds = document.getElementById(idStartName + "Seconds" + index); - - return parseInt(minutes.value) * 60 + parseFloat(seconds.value); - } - - function saveSponsorTimeEdit(index, closeEditMode = true) { - sponsorTimes[index].segment[0] = getSponsorTimeEditTimes("startTime", index); - sponsorTimes[index].segment[1] = getSponsorTimeEditTimes("endTime", index); - - //save this - Config.config.segmentTimes.set(currentVideoID, sponsorTimes); - - messageHandler.query({ - active: true, - currentWindow: true - }, tabs => { - messageHandler.sendMessage( - tabs[0].id, - {message: "sponsorDataChanged"} - ); - }); - - if (closeEditMode) { - showSubmitTimesIfNecessary(); - } - } - - //deletes the sponsor time submitted at an index - function deleteSponsorTime(index) { - //if it is not a complete sponsor time - if (sponsorTimes[index].segment.length < 2) { - messageHandler.query({ - active: true, - currentWindow: true - }, function(tabs) { - messageHandler.sendMessage(tabs[0].id, { - message: "changeStartSponsorButton", - showStartSponsor: true, - uploadButtonVisible: false - }); - }); - - resetStartTimeChosen(); - } - - sponsorTimes.splice(index, 1); - - //save this - Config.config.segmentTimes.set(currentVideoID, sponsorTimes); - - //if they are all removed - if (sponsorTimes.length == 0) { - //update chrome tab - messageHandler.query({ - active: true, - currentWindow: true - }, function(tabs) { - messageHandler.sendMessage(tabs[0].id, { - message: "changeStartSponsorButton", - showStartSponsor: true, - uploadButtonVisible: false - }); - }); - - //hide submission section - document.getElementById("submissionSection").style.display = "none"; - } - - messageHandler.query({ - active: true, - currentWindow: true - }, tabs => { - messageHandler.sendMessage( - tabs[0].id, - {message: "sponsorDataChanged"} - ); - }); - } - function submitTimes() { if (sponsorTimes.length > 0) { messageHandler.query({ @@ -786,7 +486,7 @@ async function runThePopup(messageListener?: MessageListener): Promise { //check if an end time has been specified for the latest sponsor time if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].segment.length > 1) { //show submit times button - document.getElementById("submitTimesContainer").style.display = "unset"; + document.getElementById("submitTimesContainer").style.display = "flex"; } else { //hide submit times button document.getElementById("submitTimesContainer").style.display = "none"; @@ -798,29 +498,24 @@ async function runThePopup(messageListener?: MessageListener): Promise { chrome.runtime.sendMessage({"message": "openConfig"}); } + function openHelp() { + chrome.runtime.sendMessage({"message": "openHelp"}); + } + //make the options username setting option visible function setUsernameButton() { - //get username from the server - utils.sendRequestToServer("GET", "/api/getUsername?userID=" + Config.config.userID, function (response) { - if (response.status == 200) { - PageElements.usernameInput.value = JSON.parse(response.responseText).userName; + PageElements.usernameInput.value = PageElements.usernameValue.innerText; - PageElements.submitUsername.style.display = "unset"; - PageElements.usernameInput.style.display = "unset"; + PageElements.submitUsername.style.display = "unset"; + PageElements.usernameInput.style.display = "unset"; - PageElements.setUsernameContainer.style.display = "none"; - PageElements.setUsername.style.display = "unset"; - PageElements - PageElements.setUsernameStatusContainer.style.display = "none"; - } else { - PageElements.setUsername.style.display = "unset"; - PageElements.submitUsername.style.display = "none"; - PageElements.usernameInput.style.display = "none"; + PageElements.setUsernameContainer.style.display = "none"; + PageElements.setUsername.style.display = "flex"; + PageElements.setUsername.classList.add("SBExpanded"); + + PageElements.setUsernameStatusContainer.style.display = "none"; - PageElements.setUsernameStatusContainer.style.display = "unset"; - PageElements.setUsernameStatus.innerText = utils.getErrorMessage(response.status); - } - }); + PageElements.sponsorTimesContributionsContainer.classList.add("hidden"); } //submit the new username @@ -829,15 +524,20 @@ async function runThePopup(messageListener?: MessageListener): Promise { PageElements.setUsernameStatusContainer.style.display = "unset"; PageElements.setUsernameStatus.innerText = chrome.i18n.getMessage("Loading"); - //get the userID utils.sendRequestToServer("POST", "/api/setUsername?userID=" + Config.config.userID + "&username=" + PageElements.usernameInput.value, function (response) { if (response.status == 200) { //submitted PageElements.submitUsername.style.display = "none"; PageElements.usernameInput.style.display = "none"; - PageElements.setUsernameStatus.innerText = chrome.i18n.getMessage("success"); - } else { + PageElements.setUsernameContainer.style.removeProperty("display"); + PageElements.setUsername.classList.remove("SBExpanded"); + PageElements.usernameValue.innerText = PageElements.usernameInput.value; + + PageElements.setUsernameStatusContainer.style.display = "none"; + + PageElements.sponsorTimesContributionsContainer.classList.remove("hidden"); + } else { PageElements.setUsernameStatus.innerText = utils.getErrorMessage(response.status); } }); @@ -852,24 +552,15 @@ async function runThePopup(messageListener?: MessageListener): Promise { document.getElementById("loadingIndicator").innerText = chrome.i18n.getMessage("noVideoID"); } - function reportAnIssue() { - document.getElementById("issueReporterContainer").style.display = "unset"; - PageElements.reportAnIssue.style.display = "none"; - } - function addVoteMessage(message, UUID) { - const container = document.getElementById("sponsorTimesVoteButtonsContainer" + UUID); - //remove all children - while (container.firstChild) { - container.removeChild(container.firstChild); - } - - const thanksForVotingText = document.createElement("h2"); + let voteButtonsContainer = document.getElementById("sponsorTimesVoteButtonsContainer" + UUID); + voteButtonsContainer.style.display = "none"; + + let voteStatusContainer = document.getElementById("sponsorTimesVoteStatusContainer" + UUID); + voteStatusContainer.style.removeProperty("display"); + + let thanksForVotingText = document.getElementById("sponsorTimesThanksForVotingText" + UUID); thanksForVotingText.innerText = message; - //there are already breaks there - thanksForVotingText.style.marginBottom = "0px"; - - container.appendChild(thanksForVotingText); } function vote(type, UUID) { @@ -894,11 +585,6 @@ async function runThePopup(messageListener?: MessageListener): Promise { }); } - function hideDiscordButton() { - Config.config.hideDiscordLink = true; - PageElements.discordButtonContainer.style.display = "none"; - } - //converts time in seconds to minutes:seconds function getFormattedTime(seconds) { const minutes = Math.floor(seconds / 60); @@ -942,10 +628,9 @@ async function runThePopup(messageListener?: MessageListener): Promise { //change button PageElements.whitelistChannel.style.display = "none"; PageElements.unwhitelistChannel.style.display = "unset"; - if (!Config.config.forceChannelCheck) PageElements.whitelistForceCheck.style.display = "unset"; + document.querySelectorAll('.SBWhitelistIcon')[0].classList.add("rotated"); - PageElements.downloadedSponsorMessageTimes.innerText = chrome.i18n.getMessage("channelWhitelisted"); - PageElements.downloadedSponsorMessageTimes.style.fontWeight = "bold"; + if (!Config.config.forceChannelCheck) PageElements.whitelistForceCheck.classList.remove("hidden"); //save this Config.config.whitelistedChannels = whitelistedChannels; @@ -990,9 +675,7 @@ async function runThePopup(messageListener?: MessageListener): Promise { //change button PageElements.whitelistChannel.style.display = "unset"; PageElements.unwhitelistChannel.style.display = "none"; - - PageElements.downloadedSponsorMessageTimes.innerText = ""; - PageElements.downloadedSponsorMessageTimes.style.fontWeight = "unset"; + document.querySelectorAll('.SBWhitelistIcon')[0].classList.remove("rotated"); //save this Config.config.whitelistedChannels = whitelistedChannels; @@ -1067,10 +750,6 @@ async function runThePopup(messageListener?: MessageListener): Promise { } if (chrome.tabs != undefined) { - //add the width restriction (because Firefox) - const link = document.getElementById("sponsorBlockStyleSheet"); - ( link.sheet).insertRule('.popupBody { width: 325 }', 0); - //this means it is actually opened in the popup runThePopup(); }