diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index efacc6d9..c940165e 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -3,6 +3,12 @@ description: File a bug report! # title: "(Bug): " labels: ["bug"] body: + - type: checkboxes + attributes: + label: Have you tried to find similar issues (open or recently closed)? + options: + - label: "Yes, this issue is not a duplicate" + required: true - type: input attributes: label: Browser diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 00000000..adb3fd1c --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,53 @@ +name: Test Build Extension + +on: + push: + branches: [main] + paths: + - Extensions/combined/** + + pull_request: + branches: [main] + paths: + - Extensions/combined/** + +jobs: + build: + runs-on: ubuntu-latest + + defaults: + run: + working-directory: ./Extensions/combined + + steps: + - name: Checkout + uses: actions/checkout@main + + - name: Setup Node 20 + uses: actions/setup-node@v3 + with: + node-version: '20.x' + + - name: Install dependencies + run: npm ci + + - name: Build extension + run: npm run build + + - name: 'Upload Chrome artifact' + uses: actions/upload-artifact@v4 + with: + name: ryd-chrome + path: ./Extensions/combined/dist/chrome + + - name: 'Upload Firefox artifact' + uses: actions/upload-artifact@v4 + with: + name: ryd-firefox + path: ./Extensions/combined/dist/firefox + + - name: 'Upload Safari artifact' + uses: actions/upload-artifact@v4 + with: + name: ryd-safari + path: ./Extensions/combined/dist/safari diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 00000000..d24fdfc6 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +npx lint-staged diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..84bce597 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v12.18.4 \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2a65ac17..302cd232 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -Read this in other languages: [Français](CONTRIBUTINGfr.md) +Read this in other languages: [русский](CONTRIBUTINGru.md), [Nederlands](CONTRIBUTINGnl.md), [Français](CONTRIBUTINGfr.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Polski](CONTRIBUTINGpl.md), [Deutsch](CONTRIBUTINGde.md) # Welcome To Return YouTube Dislikes contributing guide diff --git a/CONTRIBUTINGde.md b/CONTRIBUTINGde.md new file mode 100644 index 00000000..7f8623fe --- /dev/null +++ b/CONTRIBUTINGde.md @@ -0,0 +1,67 @@ +Read this in other languages: [русский](CONTRIBUTINGru.md), [Nederlands](CONTRIBUTINGnl.md), [Français](CONTRIBUTINGfr.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Polski](CONTRIBUTINGpl.md) + +# Willkommen beim Leitfaden für Beitragende von Return YouTube Dislikes + +Vielen Dank, dass du deine Zeit investierst, um zu unserem Projekt beizutragen! Alle deine Änderungen werden in der nächsten Version der Erweiterung (oder der [Website](https://www.returnyoutubedislike.com/)) reflektiert. + +## Erste Schritte + +Bitte verwende Prettier mit den Standardeinstellungen für die Formatierung. + +#### Voraussetzungen + +Du musst Node und npm installiert haben, um die gebündelte Version der Quelle zu erstellen. + +Verwendete Versionen beim Einrichten: + +- Node: 12.18.4 +- npm: 6.14.6 + +Um die `bundled-content-script.js` zu erstellen, die den Großteil der Geschäftslogik dieser Erweiterung enthält, musst du zuerst alle Abhängigkeiten installieren. + +1. Gehe zum Root-Verzeichnis des Repos und führe aus: + +``` +npm install +``` + +2. Führe den folgenden Befehl aus, um `bundled-content-script.js` zu erstellen, das in `manifest.json` verwendet wird: + +``` +npm start // um die Build-Datei(en) zu erstellen und einen Datei-Watcher zu starten, der bei jedem Speichern neu lädt + +// oder + +npm run build // um die Build-Datei(en) einmal zu erstellen +``` + +Herzlichen Glückwunsch, du bist jetzt bereit zum Entwickeln! + +Wenn du neu in der Entwicklung von Chrome-Erweiterungen bist oder zusätzliche Hilfe benötigst, sieh dir bitte [dieses YouTube-Tutorial](https://www.youtube.com/watch?v=mdOj6HYE3_0) an. + +### Probleme + +#### Öffnen eines neuen Problems + +Wenn du Probleme mit der Erweiterung hast, suche bitte, um sicherzustellen, dass das Problem noch nicht gemeldet wurde. Wenn nicht, öffne ein Problem. Die Verwendung des Problemformulars wird dringend empfohlen, ist aber nicht zwingend erforderlich. + +#### Lösung eines Problems + +Wenn du ein Problem gefunden hast, das du lösen könntest, sei nicht schüchtern. Öffne einen PR mit der Lösung und vergewissere dich, dass du das behobene Problem erwähnst. + +### Feature-Anfrage + +#### Öffnen einer neuen Feature-Anfrage + +Wenn du eine Idee für die Erweiterung hast, kannst du gerne eine Feature-Anfrage öffnen, aber suche bitte zuerst, um sicherzustellen, dass das Feature noch nicht vorgeschlagen wurde. Die Verwendung des Feature-Formulars wird dringend empfohlen, ist aber nicht zwingend erforderlich. + +#### Implementierung einer Feature-Anfrage + +Wenn du ein Feature gefunden hast, das du implementieren könntest, sei nicht schüchtern. Öffne einen PR mit der Implementierung und vergewissere dich, dass du das implementierte Feature erwähnst. + +### Welche PRs akzeptieren wir? + +- Fehlerbehebungen. +- Implementierung von Funktionen. +- Rechtschreibfehler oder bessere und einfachere Wörter zur Verwendung. +- Beiträge zur Website. diff --git a/CONTRIBUTINGfr.md b/CONTRIBUTINGfr.md index 95ece722..0aa1c52b 100644 --- a/CONTRIBUTINGfr.md +++ b/CONTRIBUTINGfr.md @@ -1,4 +1,4 @@ -Lisez ceci dans d'autres langues : [English](CONTRIBUTING.md) +Lisez ceci dans d'autres langues : [English](CONTRIBUTING.md), [русский](CONTRIBUTINGru.md), Nederlands](CONTRIBUTINGnl.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Polski](CONTRIBUTINGpl.md), [Deutsch](CONTRIBUTINGde.md) # Bienvenue dans le guide de contribution à Return YouTube Dislikes diff --git a/CONTRIBUTINGnl.md b/CONTRIBUTINGnl.md new file mode 100644 index 00000000..d6831833 --- /dev/null +++ b/CONTRIBUTINGnl.md @@ -0,0 +1,67 @@ +Lees dit in andere talen: [English](CONTRIBUTINGen.md), [русский](CONTRIBUTINGru.md), [Français](CONTRIBUTINGfr.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Polski](CONTRIBUTINGpl.md), [Deutsch](CONTRIBUTINGde.md) + +# Welkom bij de YouTube Dislikes bijdragengids + +Bedankt voor het investeren van uw tijd in het bijdragen aan ons project! Al uw wijzigingen worden weergegeven in de volgende versie van de extensie (of de [website](https://www.returnyoutubedislike.com/)). + +## Aan de slag + +Gebruik Prettier met standaardinstellingen voor opmaak. + +#### Vereisten + +U moet node en npm hebben geïnstalleerd om de gebundelde versie van de broncode te maken. + +Versies gebruikt bij het instellen: + +- node: 12.18.4 +- npm: 6.14.6 + +Om de `bundled-content-script.js` te maken die de meeste bedrijfslogica van deze extensie bevat, moet u eerst alle afhankelijkheden installeren. + +1. Ga naar de hoofdmap van de repo en voer het volgende uit: + +``` +npm install +``` + +2. Voer de volgende opdracht uit om `bundled-content-script.js` aan te maken dat wordt gebruikt in `manifest.json` + +``` +npm start // om het (de) buildbestand(en) te maken en een bestandswachter te starten die bij het opslaan opnieuw wordt geladen + +// of + +npm run build // om het (de) buildbestand(en) eenmaal te maken +``` + +Gefeliciteerd, je bent nu klaar om te ontwikkelen! + +Als je nieuw bent in het ontwikkelen van Chrome-extensies of extra hulp nodig hebt, bekijk dan [deze YouTube-tutorial](https://www.youtube.com/watch?v=mdOj6HYE3_0) + +### Problemen + +#### Een nieuw probleem openen + +Als je problemen hebt met de extensie, zoek dan eerst of het probleem nog niet is gemeld. Als dit niet het geval is, open dan een probleem, het gebruik van het probleemformulier wordt sterk aanbevolen, maar is niet verplicht. + +#### Een probleem oplossen + +Als je een probleem hebt gevonden waarvan je denkt dat je het zou kunnen oplossen, wees dan niet verlegen. Open een PR met de oplossing en vermeld het probleem dat u aan het oplossen bent. + +### Functieverzoek: + +#### Een nieuw functieverzoek openen + +Als je een idee hebt voor de extensie, kun je een functieverzoek openen, maar zoek het eerst op om er zeker van te zijn dat de functie niet al is voorgesteld. Het gebruik van het functieformulier wordt sterk aanbevolen, maar is niet verplicht. + +#### Een functieverzoek implementeren + +Als je een functie hebt gevonden waarvan je denkt dat je die zou kunnen implementeren, wees dan niet verlegen. Open een PR met de oplossing en zorg ervoor dat u de functie vermeldt die u implementeert. + +### Welke PR's accepteren we? + +- Probleemoplossingen. +- Implementatie van functies. +- Typefouten of betere en gemakkelijkere woorden om te gebruiken. +- Website bijdragen. diff --git a/CONTRIBUTINGpl.md b/CONTRIBUTINGpl.md new file mode 100644 index 00000000..953df488 --- /dev/null +++ b/CONTRIBUTINGpl.md @@ -0,0 +1,67 @@ +Read this in other languages: [English](CONTRIBUTING.md), [русский](CONTRIBUTINGru.md), [Nederlands](CONTRIBUTINGnl.md), [Français](CONTRIBUTINGfr.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Deutsch](CONTRIBUTINGde.md) + +# Witamy w przewodniku współtworzenia Return YouTube Dislike + +Dziękujemy za zainwestowanie czasu w rozwój naszego projektu! Wszystkie Twoje zmiany znajdą się w następnej wersji rozszerzenia ([bądź strony](https://www.returnyoutubedislike.com/)). + +## Początek + +Prosimy używać Prettier z domyślnymi ustawieniami do formatowania. + +#### Wymagania wstępne + +Musisz mieć zainstalowane node i npm, aby utworzyć dołączoną wersję źródła. + +Wersje używane przy ustawianiu: + +- node: 12.18.4 +- npm: 6.14.6 + +Aby utworzyć `bundled-content-script.js`, które zawiera większość logiki tego rozszerzenia, musisz najpierw zainstalować wszystkie zależności. + +1. Przejdź do korzenia tego repo i uruchom: + +``` +npm install +``` + +2. Użyj polecenia poniżej aby stworzyć `bundled-content-script.js`, które jest używane w `manifest.json` + +``` +npm start // aby utworzyć plik(i) build-u i uruchomić obserwatora pliku, który przeładowuje po zapisie + +// lub + +npm run build // aby jednorazowo utworzyć plik(i) build-u +``` + +Gratulacje, jesteś gotów pisać! + +Jeśli jesteś nowy w pisaniu rozszerzeń do Chrome, lub potrzebujesz dodatkowej pomocy, obejrzyj [ten poradnik na YouTube](https://www.youtube.com/watch?v=mdOj6HYE3_0) + +### Problemy + +#### Otwieranie nowego problemu + +Jeśli masz jakiekolwiek problemy z rozszerzeniem, najpierw wyszukaj go aby upewnić się, że dany problem nie został już zgłoszony. Jeżeli nie, otwórz problem. Używanie formularza problemu jest zalecane, ale nie jest konieczne. + +#### Rozwiązywanie problemu + +Jeżeli znalazłeś problem, który myślisz, że jesteś w stanie rozwiązać, nie wstydź się. Otwórz PR z fix-em i opisz problem, który naprawiasz. + +### Prośba o funkcjonalność + +#### Otwieranie nowej prośby o funkcjonalność + +Jeżeli masz pomysł na rozszerzenie, śmiało otwórz nowe żądanie o funkcjonalność, ale prosimy o wyszukanie swojego pomysłu, aby upewnić się, że nie został on już zasugerowany. Używanie formularza jest zalecane, ale nie jest konieczne. + +#### Implementacja prośby o funkcjonalność + +Jeżeli znalazłeś pomysł na funkcjonalność, którą myślisz, że jesteś w stanie zaimplementować, nie wstydź się. Otwórz PR z fix-em, i opisz funkcjonalność, którą implementujesz. + +### Jakie PR-y przyjmujemy? + +- Naprawy problemów. +- Implementacja funkcjonalności. +- Literówki lub lepsze i łatwiejsze w zrozumieniu słowa. +- Współtworzenie strony. diff --git a/CONTRIBUTINGpt_BR.md b/CONTRIBUTINGpt_BR.md new file mode 100644 index 00000000..107e412c --- /dev/null +++ b/CONTRIBUTINGpt_BR.md @@ -0,0 +1,67 @@ +Read this in other languages: [русский](CONTRIBUTINGru.md), [Nederlands](CONTRIBUTINGnl.md), [Français](CONTRIBUTINGfr.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Polski](CONTRIBUTINGpl.md) + +# Bem-vindo ao Guia de contribuição do Return YouTube Dislikes + +Thank you for investing your time in contributing to our project! All your changes will be reflected in the next version of the extension (or the [website](https://www.returnyoutubedislike.com/)). + +## Vamos ao começo + +Por favor use o Prettir com a configurações padrão de formatação. + +#### Prerequisites + +vocÊ precisa ter node e npm instalado para criar um You need to have node and npm installed to create the bundled version of the source. + +Versões que usará quando estiver trabalhando nisso: + +- node: 12.18.4 +- npm: 6.14.6 + +To create the `bundled-content-script.js` that contains most of the business logic of this extension you have to install all dependencies first. + +1. Vá para a raiz do repositorio e execute: + +``` +npm install +``` + +2. Execute o seguinte comando para criar `bundled-content-script.js` which (what is?) e usando no `manifest.json` + +``` +npm start // to create the build file(s) and start a file watcher that hot-reloads on save + +// ou + +npm run build // para criar uma build para cria um arquivo de build +``` + +Congratulations, You are now ready to develop! + +If you are new to developing Chrome extensions, or need extra help, please see [this YouTube tutorial](https://www.youtube.com/watch?v=mdOj6HYE3_0) + +### Problemas + +#### Abrindo um novo problema + +Se voce tiver qualquer problema com a extensão, por favor pesquisa o que faz o problema antes de reporta-lo de fato. Se não houver, abra um probelma, usando o formulario de problema é recomendado mas não é uma obrigação. + +#### Solucionando um problema + +Se você tiver um problema If you found an issue that you feel you might be able to solve, Não seja "shy"? . Abra um PR(Pull Request)com a correção e faça uma menção do problema que está consertando. + +### Requisitação de Recurso + +#### Abrindo uma nova requisitação de recurso + +Se você tem alguma ideia para a extensão, sinta livre para abrir uma requisitação de recurso, mas por favor pesquise isso antes para não perder seu tempo com sua sugestão. Usando o formulario de recurso é altamente recomendado mas não é um obrigação. + +#### Implementando uma requisitação de recurso + +If you found a feature that you feel you might be able to implement, don't be shy. Open a PR with the fix and make sure to mention the feature you are implementing. + +### What PRs do we accept? + +- Resolução de problemas. +- Implementação de recurso. +- Marcação, melhoria facilitação de palavras usadas. +- Contribuição para o Website. diff --git a/CONTRIBUTINGru.md b/CONTRIBUTINGru.md index 82b7bc1b..589a914a 100644 --- a/CONTRIBUTINGru.md +++ b/CONTRIBUTINGru.md @@ -1,4 +1,4 @@ -Прочитать на других языках: [English](CONTRIBUTING.md) +Прочитать на других языках: [English](CONTRIBUTING.md), [Nederlands](CONTRIBUTINGnl.md), [Français](CONTRIBUTINGfr.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Polski](CONTRIBUTINGpl.md), [Deutsch](CONTRIBUTINGde.md) # Добро пожаловать в руководство по внесению вклада Return YouTube Dislikes diff --git a/CONTRIBUTINGtr.md b/CONTRIBUTINGtr.md new file mode 100644 index 00000000..fec4805b --- /dev/null +++ b/CONTRIBUTINGtr.md @@ -0,0 +1,67 @@ +Bunu diğer dillerde okuyun: [English](CONTRIBUTING.md), [русский](CONTRIBUTINGru.md), [Nederlands](CONTRIBUTINGnl.md), [Français](CONTRIBUTINGfr.md), [українська](CONTRIBUTINGuk.md), [Polski](CONTRIBUTINGpl.md), [Deutsch](CONTRIBUTINGde.md) + +# "YouTube Dislike Sayısını Geri Getir"in katkı kılavuzuna Hoş Geldiniz + +Projemize katkıda bulunmak için zaman ayırdığınız için teşekkür ederiz! Tüm değişiklikleriniz, uzantının bir sonraki sürümüne (veya [internet sitesi](https://www.returnyoutubedislike.com/)ne) yansıtılacaktır. + +## Başlarken + +Lütfen formatlama işlemi için, Prettier'i varsayılan ayarlardayken kullanın. + +#### Ön Şartlar + +Kaynağın paketlenmiş sürümünü oluşturmak için node ve npm'nin kurulu olması gerekir. + +Kurulum sırasında kullanılan sürümler: + +- node: 12.18.4 +- npm: 6.14.6 + +Bu uzantının iş mantığının çoğunu içeren `bundled-content-script.js`yi oluşturmak için, önce tüm bağımlılıkları yüklemeniz gerekir. + +1. Deponun köküne gidin ve şu komutu çalıştırın: + +``` +npm install +``` + +2. `manifest.json` içinde kullanılan `bundled-content-script.js` dosyasını oluşturmak için aşağıdaki komutu çalıştırın. + +``` +npm start // derleme dosyasının/dosyalarının oluşturulması ve kaydedilmesi sırasında çalışırken yeniden yüklenen bir dosya izleyicisini başlatmak için + +// ya da + +npm run build // derleme dosyasını/dosyalarını bir kez oluşturmak için +``` + +Tebrikler, artık geliştirmeye hazırsınız! + +Chrome uzantıları geliştirme konusunda yeniyseniz veya fazladan yardıma ihtiyacınız olursa lütfen [bu YouTube öğreticisi](https://www.youtube.com/watch?v=mdOj6HYE3_0)ne bakın. + +### Issue'lar + +#### Yeni bir issue başlatmak + +Uzantıyla ilgili herhangi bir sorununuz varsa, sorunun önceden bildirilmediğinden emin olmak için lütfen arama yapın. Eğer daha önce bildirilmediyse, bir konu açın. Sorun formunu kullanmanız şiddetle tavsiye edilir ancak zorunlu değildir. + +#### Bir issue'yu çözmek + +Çözebileceğinizi düşündüğünüz bir sorun bulduysanız, çekinmeyin. Düzeltmeyi içeren bir PR açın ve düzelttiğiniz sorunu belirttiğinizden emin olun. + +### Özellik Talebi + +#### Yeni bir özellik talebi açmak + +Uzantı hakkında bir fikriniz varsa, bir özellik isteği açmaktan çekinmeyin, ancak özelliğin daha önce önerilmediğinden emin olmak için lütfen önce arama yapın. Özellik formunun kullanılması şiddetle tavsiye edilir ancak zorunlu değildir. + +#### Bir özellik isteğini uygulamak + +Uygulayabileceğinizi düşündüğünüz bir özellik bulduysanız, çekinmeyin. Düzeltmeyi içeren bir PR açın ve uyguladığınız özelliği belirttiğinizden emin olun. + +### Hangi tür PR'leri kabul ediyoruz? + +- Sorun düzeltmeleri. +- Özellik uygulaması. +- Yazım hataları veya daha anlaşılabilir ve kullanımı daha kolay kelimeler. +- Site katkıları. diff --git a/CONTRIBUTINGuk.md b/CONTRIBUTINGuk.md new file mode 100644 index 00000000..7c7fd21f --- /dev/null +++ b/CONTRIBUTINGuk.md @@ -0,0 +1,67 @@ +Read this in other languages: [English](CONTRIBUTING.md), [русский](CONTRIBUTINGru.md), [Français](CONTRIBUTINGfr.md), [Türkçe](CONTRIBUTINGtr.md), [Polski](CONTRIBUTINGpl.md), [Deutsch](CONTRIBUTINGde.md) + +# Вітаємо у посібнику внеску в Return YouTube Dislikes + +Дякуємо, що вкладаєте свій час у розвиток нашого проєкту! Усі ваші зміни буде відображено в наступній версії розширення (або ж [вебсайту](https://www.returnyoutubedislike.com/)). + +## Почнімо працювати + +Будь ласка, використовуйте Prettier із налаштуваннями за замовчуванням для форматування коду. + +#### Заздалегідь + +Вам потрібно встановити node і npm, щоб створити bundled версію джерела. + +Версії, що використовувались при налаштуванні: + +- node: 12.18.4 +- npm: 6.14.6 + +Для створення `bundled-content-script.js`, який містить більшу частину бізнес-логіки цього розширення, спочатку потрібно встановити всі залежності. + +1. Перейдіть в корінь репозиторію та виконайте наступне: + +``` +npm install +``` + +2. Виконайте наступну команду, щоб створити `bundled-content-script.js`, який використовується в `manifest.json` + +``` +npm start // для створення файлу(ів) збірки та запуску спостерігача за файлами, який виконує hot-reload при збереженні + +// або ж + +npm run build // для створення файлу(ів) збірки один раз +``` + +Вітаємо, тепер ви готові до розробки! + +Якщо ви новачок у розробці розширення Chrome або вам потрібна додаткова допомога, перегляньте [це керівництво на YouTube](https://www.youtube.com/watch?v=mdOj6HYE3_0) (англ.) + +### Проблеми + +#### Відкриття нової проблеми + +Якщо у вас виникли проблеми з розширенням, здійсніть пошук і переконайтеся, що про цю проблему ще не повідомляли. Якщо ні, створіть Issue, використання форми проблеми наполегливо рекомендується, але не є обов’язковим. + +#### Вирішення проблеми + +Якщо ви знайшли проблему, і гадаєте, що можете її вирішити, не соромтеся. Створіть Pull Request на вилучення з виправленням і обов'язково вкажіть проблему, яку ви усуваєте. + +### Запит функції + +#### Відкриття запиту на нову функцію + +Якщо у вас є ідея щодо розширення, не соромтеся створіть Pull Request, але, будь ласка, здійсніть пошук і переконайтеся, що ця функція ще не запропонована. Використання форми функції наполегливо рекомендується, але не є обов’язковим. + +#### Реалізація запиту функції + +Якщо ви знайшли функцію, і гадаєте, що можете її реалізувати, не соромтеся. Створіть Pull Request із виправленням і обов’язково вкажіть функцію, яку ви впроваджуєте. + +### Які Pull Request ми приймаємо? + +- Виправлення проблем. +- Впровадження нових функцій. +- Виправлення помилок та спрощення тексту. +- Поліпшення сайту. diff --git a/Docs/FAQ.md b/Docs/FAQ.md index d539b4f8..dab31a36 100644 --- a/Docs/FAQ.md +++ b/Docs/FAQ.md @@ -1,4 +1,5 @@ -Read this in other languages: [Français](FAQfr.md) +Read this in other languages: [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Polski](FAQpl.md), [Deutsch](FAQde.md), [Português do Brasil](FAQpt_BRmd) + # Frequently Asked Questions @@ -36,11 +37,11 @@ The backend will switch to using a combination of archived dislike stats, estima ### **5. How is the dislike count calculated?** -RYD uses the votes from it's users to extrapolate the dislike count. +RYD uses the votes from its users to extrapolate the dislike count. - If the video was uploaded after the API was shut down: - $$ \textup{RYD Dislike Count} = \left( \frac{\textup{RYD Users Like Count}}{\textup{RYD Users Dislike Count}} \right) \times \textup{Public Like Count} $$ + $$ \textup{RYD Dislike Count} = \left( \frac{\textup{RYD Users Dislike Count}}{\textup{RYD Users Like Count}} \right) \times \textup{Public Like Count} $$ - If the RYD database somehow had the actual like and dislike count (provided by the uploader or from the archive), the dislike count will be calculated based on both - the users' votes and the archived value. The archived value will have less influence on the final count as it ages. diff --git a/Docs/FAQde.md b/Docs/FAQde.md new file mode 100644 index 00000000..1f5c53fa --- /dev/null +++ b/Docs/FAQde.md @@ -0,0 +1,61 @@ +Read this in other languages: [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Polski](FAQpl.md) + +# Häufig gestellte Fragen + +## Bevor Sie eine Frage auf GitHub oder Discord stellen, sehen Sie bitte hier nach. + +
+ +### **1. Woher stammt die Datenquelle dieser Erweiterung?** + +Eine Kombination aus Google-APIs und gescrapten Daten. + +Wir speichern alle verfügbaren Daten in unserer Datenbank, damit sie verfügbar sind, nachdem Google die Anzahl der Dislikes in ihrer API abschaltet. + +
+ +### **2. Die Anzahl der Dislikes bei Videos aktualisiert sich nicht** + +Aktuell werden die Dislikes bei Videos zwischengespeichert und nicht sehr häufig aktualisiert. Etwa alle 2-3 Tage, nicht öfter. + +Ja, das ist nicht ideal, aber es ist wie es ist. Wir arbeiten daran, wie oft wir sie aktualisieren können, zu verbessern. + +
+ +### **3. Wie funktioniert das?** + +Die Erweiterung sammelt die Video-ID des von Ihnen angesehenen Videos, ruft die Dislikes (und andere Felder wie Aufrufe, Likes usw.) über unsere API ab. Wenn dies das erste Mal ist, dass das Video von unserer API abgerufen wurde, wird die YouTube-API verwendet, um die Daten zu erhalten. Anschließend werden die Daten für den Zwischenspeicher (ca. 2-3 Tage zwischengespeichert) und Archivierungszwecke in einer Datenbank gespeichert und an Sie zurückgegeben. Die Erweiterung zeigt Ihnen dann die Dislikes an. + +
+ +### **4. Was passiert, wenn die YouTube-API aufhört, die Anzahl der Dislikes zurückzugeben?** + +Der Backend wird auf eine Kombination aus archivierten Dislike-Statistiken, Schätzungen, die aus den Daten der Erweiterungsnutzer extrapoliert werden, und Schätzungen basierend auf Ansichts-/Like-Verhältnissen für Videos, deren Dislikes nicht archiviert wurden, und veralteten Dislike-Archiven umstellen. + +
+ +### **5. Wie wird die Anzahl der Dislikes berechnet?** + +RYD verwendet die Stimmen seiner Benutzer, um die Anzahl der Dislikes zu extrapolieren. + +- Wenn das Video nach dem Abschalten der API hochgeladen wurde: + + $$ \textup{RYD Dislike Count} = \left( \frac{\textup{RYD Users Dislike Count}}{\textup{RYD Users Like Count}} \right) \times \textup{Public Like Count} $$ + +- Wenn die RYD-Datenbank auf irgendeine Weise die tatsächliche Anzahl von Likes und Dislikes enthielt (vom Ersteller bereitgestellt oder aus dem Archiv), wird die Anzahl der Dislikes basierend auf beiden - den Stimmen der Benutzer und dem archivierten Wert - berechnet. Der archivierte Wert wird mit zunehmendem Alter weniger Einfluss auf die endgültige Zählung haben. + +
+ +--- + +Dies in Videoform + +[![IReturn YouTube Dislike Explained](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ) + +--- + +
+ +## Ich habe Sicherheits-/Privatsphärebedenken + +Siehe [diese Seite](SECURITY-FAQde.md) für weitere Informationen. diff --git a/Docs/FAQfr.md b/Docs/FAQfr.md index 76b481ec..ed1c81c5 100644 --- a/Docs/FAQfr.md +++ b/Docs/FAQfr.md @@ -1,4 +1,4 @@ -Lisez ceci dans d'autres langues : [English](FAQ.md) +Lisez ceci dans d'autres langues : [English](FAQ.md), [русский](FAQru.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Polski](FAQpl.md), [Deutsch](FAQde.md) # Foire Aux Questions diff --git a/Docs/FAQnl.md b/Docs/FAQnl.md new file mode 100644 index 00000000..e6bc4ee8 --- /dev/null +++ b/Docs/FAQnl.md @@ -0,0 +1,61 @@ +Lees dit in andere talen: [Engels](FAQ.md), [русский](FAQru.md), [Français](FAQfr.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Polski](FAQpl.md), [Deutsch](FAQde.md) + +# Veel Gestelde Vragen + +## Raadpleeg deze voordat u een vraag stelt op GitHub of Discord. + +
+ +### **1. Waar haalt deze extensie de gegevens vandaan?** + +Een combinatie van Google API's en geschraapte gegevens. + +We slaan alle beschikbare gegevens op in onze database, zodat deze beschikbaar is nadat Google het aantal dislikes in hun API heeft stopgezet. + +
+ +### **2. Het aantal video-dislikes wordt niet bijgewerkt** + +Op dit moment worden video's die niet leuk zijn in het cachegeheugen opgeslagen en worden niet erg vaak bijgewerkt. Eens in de 2-3 dagen, niet vaker. + +Ja, het is niet ideaal, maar het is wat het is. Werken aan het verbeteren van hoe vaak we ze kunnen bijwerken. + +
+ +### **3. Hoe werkt dit?** + +De extensie verzamelt de video-ID van de video die je aan het bekijken bent, haalt de dislike (en andere velden zoals views, likes etc) op met behulp van onze API. Als dit de eerste keer is dat de video wordt opgehaald door onze API, zal deze de YouTube API gebruiken om de gegevens op te halen, slaat de gegevens vervolgens op in een database voor caching (cache voor ongeveer 2-3 dagen) en archiveringsdoeleinden en stuurt ze naar u terug. De extensie geeft vervolgens de antipathieën aan u weer. + +
+ +### **4. Wat gebeurt er nadat de YouTube API stopt met het teruggeven van het aantal dislikes?** + +De backend zal overschakelen naar het gebruik van een combinatie van afkeer statistieken en afkeer archieven, schattingen geëxtrapoleerd uit gebruikersgegevens van extensies en schattingen op basis van weergave/vind-ik-leuk-verhoudingen voor video's waarvan de afkeuren niet zijn gearchiveerd en voor verouderde afkeer-archieven. + +
+ +### **5. Hoe wordt het aantal dislikes berekend?** + +RYD gebruikt de stemmen van zijn gebruikers om het aantal dislikes te extrapoleren. + +- Als de video is geüpload nadat de API was afgesloten: + + $$ \textup{RYD Dislike Count} = \left( \frac{\textup{RYD Users Like Count}}{\textup{RYD Users Dislike Count}} \right) \times \textup{Public Like Count} $$ + +- Als de RYD-database op de een of andere manier het werkelijke aantal likes en dislikes had (geleverd door de uploader of uit het archief), wordt het aantal dislikes berekend op basis van zowel de stemmen van de gebruikers als de gearchiveerde waarde. De gearchiveerde waarde heeft minder invloed op de uiteindelijke telling naarmate deze ouder wordt. + +
+ +--- + +Dit in videovorm + +[![IReturn YouTube Dislike Uitgelegd (Engels)](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ) + +--- + +
+ +## Ik heb zorgen over de beveiliging/privacy + +Bekijk [deze pagina](SECURITY-FAQnl.md) voor meer informatie. diff --git a/Docs/FAQpl.md b/Docs/FAQpl.md new file mode 100644 index 00000000..2fccb1fa --- /dev/null +++ b/Docs/FAQpl.md @@ -0,0 +1,61 @@ +Read this in other languages: [English](FAQ.md), [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Deutsch](FAQde.md) + +# Często zadawane pytania + +## Przeczytaj poniższe przed zadawaniem pytań na GitHubie lub Discordzie. + +
+ +### **1.Skąd rozszerzenie otrzymuje swoje dane?** + +Kombinacja API Google i danych scrape-owanych. + +Zapisujemy wszystkie dostępne dane do naszej bazy danych, żeby były dostępne po tym jak Google wyłączy liczniki łapek w dół w swoim API. + +
+ +### **2. Licznik łapek w dół się nie aktualizuje** + +Na chwile obecną łapki w dół są buforowane i nie są bardzo często aktualizowane. Raz na 2-3 dni, nie częściej. + +No nie jest to idealne, ale tak już jest. Pracujemy nad tym jak częściej możemy to aktualizować. + +
+ +### **3. Jak to działa?** + +Rozszerzenie zbiera ID filmu, którego oglądasz, pobiera ilość łapek w dół (i inne pola, takie jak wyświetlenia, łapki w górę itd.) za pomocą naszego API. Jeżeli film jest pierwszy raz pobrany przez nasze API, zostanie użyte YouTube API do pobrania danych, a potem przechowania w bazie danych do buforu (przez jakieś 2-3 dni) i archiwizacji, po czym zwracane jest Tobie. Rozszerzenie potem wyświetla ilość łapek w dół. + +
+ +### **4. Co się wydarzy gdy YouTube API przestanie zwracać liczbę łapek w dół?** + +Backend przełączy się na używanie kombinacji zarchiwizowanych statystyk łapek w dół, szacunków ekstrapolowanych z danych użytkowników rozszerzenia i szacowań opartych na stosunkach wyświetleń/łapek w górę dla filmów, których ilość łapek w dół nie została zarchiwizowana i dla przestarzałych archiwów. + +
+ +### **5. Jak wyliczana jest liczba łapek w dół?** + +RYD używa głosów użytkowników, aby ekstrapolować liczbę łapek w dół. + +- Jeżeli film został wrzucony przed wyłączeniem API: + + $$ \textup{Liczba łapek w dół RYD} = \left( \frac{\textup{Liczba łapek w dół użytkowników RYD}}{\textup{Liczba łapek w górę użytkowników RYD}} \right) \times \textup{Publiczna liczba łapek w górę} $$ + +- Jeśli baza danych RYD jakimś cudem miałaby prawidłową liczbę łapek w górę i dół (zapewnione przez twórce lub z archiwum), liczba łapek w dół będzie obliczana w oparciu jednocześnie głosów użytkowników i wartości zarchiwizowanych. Zarchiwizowana wartość będzie miała mniejszy wpływ na ostateczną liczbę z biegiem czasu. + +
+ +--- + +To samo w formie filmu. + +[![IReturn YouTube Dislike Explained](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ) + +--- + +
+ +## Mam zastrzeżenia co do bezpieczeństwa / prywatności + +Przejdź [tutaj](SECURITY-FAQ.md) aby uzyskać więcej informacji. diff --git a/Docs/FAQpt_BR.md b/Docs/FAQpt_BR.md new file mode 100644 index 00000000..7dc5448f --- /dev/null +++ b/Docs/FAQpt_BR.md @@ -0,0 +1,61 @@ +Leia isso em outros Idiomas: [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Polski](FAQpl.md) + +# Frequently Asked Questions + +## Before asking a question on GitHub or Discord, please refer to this. + +
+ +### **1. Where does this extension get the data?** + +A Combination of Google APIs and scraped data. + +We save all available data to our DB for it to be available after Google shuts down dislike counts in their API. + +
+ +### **2. Video dislike count doesn't update** + +Right now video dislikes are cached, and aren't updated very frequenly. Once every 2-3 days, not more often. + +Yeah, it's not ideal, but it is what it is. Working on improving how often we can update them. + +
+ +### **3. How does this work?** + +The extension collects the video id of the video you are watching, fetches the dislike (and other fields like views, likes etc) using our API, if this is the first time the video was fetched by our API, it will use the YouTube API to get the data, then stores the data in a database for caching (cached for around 2-3 days) and archiving purposes and returns it to you. The extension then displays the dislikes to you. + +
+ +### **4. What will happen after the YouTube API stops returning the dislike count?** + +The backend will switch to using a combination of archived dislike stats, estimates extrapolated from extension user data and estimates based on view/like ratios for videos whose dislikes weren't archived and for outdated dislike archives. + +
+ +### **5. How is the dislike count calculated?** + +RYD uses the votes from its users to extrapolate the dislike count. + +- If the video was uploaded after the API was shut down: + + $$ \textup{RYD Dislike Count} = \left( \frac{\textup{RYD Users Dislike Count}}{\textup{RYD Users Like Count}} \right) \times \textup{Public Like Count} $$ + +- If the RYD database somehow had the actual like and dislike count (provided by the uploader or from the archive), the dislike count will be calculated based on both - the users' votes and the archived value. The archived value will have less influence on the final count as it ages. + +
+ +--- + +Essa a This in video form + +[![IReturn YouTube Dislike Explained](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ) + +--- + +
+ +## I have security / privacy concerns + +See [this page](SECURITY-FAQpt_BR.md) for more info. diff --git a/Docs/FAQru.txt b/Docs/FAQru.md similarity index 92% rename from Docs/FAQru.txt rename to Docs/FAQru.md index 5c770df1..d1363f3d 100644 --- a/Docs/FAQru.txt +++ b/Docs/FAQru.md @@ -1,21 +1,29 @@ -# Часто задаваемые вопросы -## Прежде чем задать вопрос на GitHub или в Discord, пожалуйста, ознакомьтесь с этим. - -### **1. Откуда это расширение получает данные?** -Комбинация API Google и старых данных. - -Мы сохраняем все имеющиеся данные в нашей базе данных, чтобы они были доступны после того, как Google прекратит подсчёт отметок «Не нравится» в своём API. - -### **2. Количество не понравившихся видео не обновляется** -В настоящее время видео с отметками «Не нравится» кэшируются и обновляются не очень часто. Раз в 2-3 дня, не чаще. - -Да, это не идеально, но это то, что есть. Мы работаем над тем, чтобы улучшить частоту их обновления. - -### **3. Как это работает?** -Расширение собирает идентификатор видео, которое вы смотрите, извлекает данные об отметках «Не нравится» (и другие поля, такие как просмотры, отметки «Нравится» и т.д.) с помощью нашего API, если видео было извлечено нашим API впервые, оно использует YouTube API для получения данных, затем сохраняет данные в базе данных для кэширования (кэшируются около 2-3 дней) и архивирования и возвращает их вам. После этого расширение отображает отметки «Не нравится» вам. - -### **4. Что произойдёт после того, как API YouTube перестанет возвращать данные о количестве отметок «Не нравится»?** -Внутренняя часть нашего сервера переключится на использование комбинации архивных статистик отметок «Не нравится», оценок, экстраполированных из данных о пользователях расширения, и оценок, основанных на соотношении просмотров и отметок «Нравится» для видео, чьи отметки «Не нравится» не были заархивированы, и для устаревших архивов с отметками «Не нравится». - -## Я беспокоюсь о безопасности / конфиденциальности -Более подробную информацию смотрите на [этой странице](SECURITY-FAQ.md). \ No newline at end of file +Read this in other languages: [English](FAQ.md), [Nederlands](FAQnl.md), [Français](FAQfr.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Polski](FAQpl.md), [Deutsch](FAQde.md) + +# Часто задаваемые вопросы + +## Прежде чем задать вопрос на GitHub или в Discord, пожалуйста, ознакомьтесь с этим. + +### **1. Откуда это расширение получает данные?** + +Комбинация API Google и старых данных. + +Мы сохраняем все имеющиеся данные в нашей базе данных, чтобы они были доступны после того, как Google прекратит подсчёт отметок «Не нравится» в своём API. + +### **2. Количество не понравившихся видео не обновляется** + +В настоящее время видео с отметками «Не нравится» кэшируются и обновляются не очень часто. Раз в 2-3 дня, не чаще. + +Да, это не идеально, но это то, что есть. Мы работаем над тем, чтобы улучшить частоту их обновления. + +### **3. Как это работает?** + +Расширение собирает идентификатор видео, которое вы смотрите, извлекает данные об отметках «Не нравится» (и другие поля, такие как просмотры, отметки «Нравится» и т.д.) с помощью нашего API, если видео было извлечено нашим API впервые, оно использует YouTube API для получения данных, затем сохраняет данные в базе данных для кэширования (кэшируются около 2-3 дней) и архивирования и возвращает их вам. После этого расширение отображает отметки «Не нравится» вам. + +### **4. Что произойдёт после того, как API YouTube перестанет возвращать данные о количестве отметок «Не нравится»?** + +Внутренняя часть нашего сервера переключится на использование комбинации архивных статистик отметок «Не нравится», оценок, экстраполированных из данных о пользователях расширения, и оценок, основанных на соотношении просмотров и отметок «Нравится» для видео, чьи отметки «Не нравится» не были заархивированы, и для устаревших архивов с отметками «Не нравится». + +## Я беспокоюсь о безопасности / конфиденциальности + +Более подробную информацию смотрите на [этой странице](SECURITY-FAQ.md). diff --git a/Docs/FAQtr.md b/Docs/FAQtr.md new file mode 100644 index 00000000..4f17d497 --- /dev/null +++ b/Docs/FAQtr.md @@ -0,0 +1,61 @@ +Bunu diğer dillerde okuyun: [English](FAQ.md), [русский](FAQru.md), [Nederlands](FAQnl.md), [Français](FAQfr.md), [українська](FAQuk.md), [Polski](FAQpl.md), [Deutsch](FAQde.md) + +# Sıkça Sorulan Sorular + +## GitHub'da veya Discord'da bir soru sormadan önce, lütfen buraya göz atın. + +
+ +### **1. Bu uzantı verileri nereden alıyor?** + +Google API'lerinin ve kazınmış verilerin bir kombinasyonu. + +Google, API'lerinde dislike sayılarını kapattıktan sonra kullanılabilir olması için mevcut tüm verileri DB'mize kaydederiz. + +
+ +### **2. Video'nun dislike sayısı güncellenmiyor** + +Şu anda video dislike'ları önbelleğe alınır ve çok sık güncellenmez. Her 2-3 günde bir, daha sık değil. + +Evet, ideal değil, ama olan bu. Bunları nasıl daha sık güncelleyebileceğimizi öğrenmeye çalışıyoruz. + +
+ +### **3. Bu uzantı nasıl çalışıyor?** + +Uzantı, izlediğiniz videonun video kimliğini alır, dislike'larını (ve görüntülemeleri, like'ları vb. diğer alanları) API'mizi kullanarak getirir; video, API'miz tarafından ilk kez getiriliyorsa YouTube API'sini kullanır. Verileri almak için, verileri önbelleğe alma (yaklaşık 2-3 gün önbelleğe alınır) ve arşivleme amacıyla bir veritabanında saklanır ve size geri döndürülür. Uzantı daha sonra size dislike'ları gösterir. + +
+ +### **4. YouTube API'si, dislike sayısını döndürmeyi durdurduğunda ne olacak?** + +Backend, arşivlenmiş dislike istatistikleri, uzantı kullanıcı verilerinden tahmin edilen tahminler ve like'ları arşivlenmemiş videolar ve eski dislike arşivleri için izlenme/like oranlarına dayalı tahminlerin bir kombinasyonunu kullanmaya geçecektir. + +
+ +### **5. Dislike sayısı nasıl hesaplanıyor?** + +YDS, dislike sayısını tahmin etmek için kullanıcılarının oylarını kullanır. + +- Video, API kapatıldıktan sonra yüklendiyse: + + $$ \textup{YDS'nin Dislike Sayısı} = \left( \frac{\textup{YDS Kullanıcılarının Like Sayısı}}{\textup{YDS Kullanıcılarının Dislike Sayısı}} \right) \times \textup{Halka Açık Like Sayısı} $$ + +- YDS veritabanı bir şekilde gerçek like ve dislike sayısına sahipse (yükleyici tarafından veya arşivden sağlanır), dislike sayısı hem kullanıcıların oyları hem de arşivlenen değer temelinde hesaplanacaktır. Arşivlenen değer, eskidikçe son sayım üzerinde daha az etkiye sahip olacaktır. + +
+ +--- + +Bu video şeklinde + +[![IReturn YouTube Dislike Explained](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ) + +--- + +
+ +## Gizlilik / güvenlik hakkında endişelerim var + +Daha fazla bilgi için [bu sayfa](SECURITY-FAQtr.md)ya göz atın. diff --git a/Docs/FAQuk.md b/Docs/FAQuk.md new file mode 100644 index 00000000..726c6c60 --- /dev/null +++ b/Docs/FAQuk.md @@ -0,0 +1,61 @@ +Read this in other languages: [English](FAQ.md), [русский](FAQru.md), [Français](FAQfr.md), [Türkçe](FAQtr.md), [Deutsch](FAQde.md) + +# Часті питання + +## Перш ніж задавати питання на GitHub або у Discord, будь ласка, ознайомтеся з цим. + +
+ +### **1. Звідки це розширення отримує дані?** + +Комбінація Google API та старих даних. + +Ми зберігаємо всі доступні дані в нашій базі, аби вони були доступні після того, як Google вимкне лічильник відміток «Не подобається» у своєму API. + +
+ +### **2. Лічильник «Не подобається» не оновлюється** + +Наразі відео з відмітками «Не подобається» кешуються і оновлюються не надто часто. Не частіше, ніж раз в 2-3 дні. + +Так, це не ідеально, але маємо те, що маємо. Ми працюємо над тим, щоб збільшити частоту їх оновлення. + +
+ +### **3. Як це працює?** + +Розширення отримує ID відео, яке ви переглядаєте, та дізнається кількість відміток «Не подобається» (та інші дані: перегляди, відмітки «Подобається» тощо) за допомогою нашого API, якщо відео було витягнуте нашим API вперше, воно використовує YouTube API для отримання даних, потім зберігає дані в базі даних для кешування (кешуються близько 2-3 днів) та архівування й повертає їх вам. Після цього розширення відображає відмітки «Не подобається» вам. + +
+ +### **4. Що станеться після того, як YouTube API перестане повертати кількість відміток «Не подобається»?** + +Сервер перейде на використання комбінації заархівованих статистичних даних відміток «Не подобається» екстрапольованих із даними . + +
+ +### **5. Як розраховується кількість відміток «Не подобається»?** + +RYD використовує відмітки своїх користувачів, щоб екстраполювати кількість відміток «Не подобається». + +- Якщо відео було завантажено після вимкнення API: + + $$ \textup{К-ть відміток «Не подобається» у RYD} = \left( \frac{\textup{К-ть відміток «Подобається» серед користувачів RYD}}{\textup{К-ть відміток «Не подобається» серед користувачів RYD}} \right) \times \textup{Публічна к-ть відміток «Подобається»} $$ + +- Якщо база даних RYD якимось чином мала фактичну кількість відміток «Подобається» та «Не подобається» (надану завантажувачем або з архіву), кількість відміток «Не подобається» буде розраховано на основі відміток користувачів і архівного значення. Архівне значення матиме менший вплив на остаточний підрахунок у міру актуальності. + +
+ +--- + +Це все, але у відео форматі + +[![IReturn YouTube Dislike Explained](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ) + +--- + +
+ +## Я турбуюся про безпеку/конфіденційність + +Детальніше про це дивіться [тут](SECURITY-FAQuk.md). diff --git a/Docs/Privacy Policy b/Docs/Privacy Policy new file mode 100644 index 00000000..5dfbca3e --- /dev/null +++ b/Docs/Privacy Policy @@ -0,0 +1,7 @@ +The only data collected from users is their likes and dislikes made while the extension is installed. + +No personal info, account name or watch history is collected or saved. + +Users are identified by a random user ID, which is not directly linked to any of their accounts, the only purpose of this user ID is to make voting process possible. + +None of the saved data is shared with any third parties, diff --git a/Docs/SECURITY-FAQ.md b/Docs/SECURITY-FAQ.md index dfbbbca7..e075e0a7 100644 --- a/Docs/SECURITY-FAQ.md +++ b/Docs/SECURITY-FAQ.md @@ -1,4 +1,4 @@ -Read this in other languages: [Français](SECURITY-FAQfr.md) +Read this in other languages: [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md), [Deutsch](SECURITY-FAQde.md) # Security diff --git a/Docs/SECURITY-FAQde.md b/Docs/SECURITY-FAQde.md new file mode 100644 index 00000000..ae1ce8fd --- /dev/null +++ b/Docs/SECURITY-FAQde.md @@ -0,0 +1,32 @@ +Read this in other languages: [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md) + + +# Sicherheit + +### Verfolgen Sie meine Anzeigehistorie? + +Nein. Der Code der Erweiterung ist öffentlich und Sie können ihn selbst einsehen. Die einzige übermittelte Information ist die Video-ID, die benötigt wird, um die Anzahl der Dislikes für die Videos abzurufen. Es werden keine zusätzlichen Header gesendet. Über die Kommunikationsschicht wird Ihre öffentliche IP-Adresse an den Server übermittelt, sowie die Zeit, zu der die Anfrage gestellt wurde. Keine dieser Informationen identifiziert Sie auf eindeutige Weise. Unter der Annahme einer Zero-Trust-Umgebung ist das Beste, was wir bekommen können, eine dynamische IP. Die heute Ihnen gehört, gehört morgen Ihrem Nachbarn. Wenn Sie sich wirklich Sorgen machen, dass Ihre IP zurückverfolgt wird, verwenden Sie wahrscheinlich bereits ein VPN. + +### Können Sie mich eindeutig identifizieren, wenn ich etwas dislike? + +Ja. Wenn Sie ein Video nicht mögen, erstellen wir eine zufällig generierte eindeutige ID für Sie, die nicht mit Ihrem Google-Konto verknüpft ist. Dies geschieht, um das Botting zu verhindern. Es gibt jedoch keine Möglichkeit, diese zufällige ID mit Ihnen oder Ihrem persönlichen YouTube-Konto zu verknüpfen. + +### Welche Informationen haben Sie genau? + +Nur die Video-ID. Nicht Ihre Kommentare, nicht Ihren Benutzernamen, nicht mit wem Sie das Video geteilt haben, keine zusätzlichen Metadaten. Nichts. Nur die Video-ID. + +### Wie wird meine IP gespeichert? + +Der Backend speichert nicht gehashte IP-Adressen nur im flüchtigen Speicher (RAM). Diese Adressen werden nicht auf einer Festplatte gespeichert und daher nicht protokolliert. Wir hashen die IP-Adressen und speichern diese stattdessen. Dies geschieht, um Datenbankvandalismus zu verhindern. + +### Ich habe etwas über OAuth gehört und den Zugriff auf mein YouTube-Konto! + +Diese Funktion wird optional sein und sehr stark opt-in. Wenn Sie ein YouTube-Ersteller sind und Ihre Dislike-Statistiken mit uns teilen möchten, können Sie dies tun. Die Art und Weise, wie [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) strukturiert wurde, ist tatsächlich sehr sicher. Sie können den Zugriff auf Ihr Konto jederzeit widerrufen und uns sehr spezifische Berechtigungen erteilen. Wir werden nicht nach Berechtigungen fragen, die nicht erforderlich sind. Wir werden nur um Berechtigungen bitten, um Ihre Video-Statistiken anzeigen zu können. + +### Wie kann ich diesem Dislike-Zähler vertrauen? + +Wir haben Maßnahmen implementiert, um Bot-Angriffe zu verhindern, und werden weiterhin daran arbeiten, die Effektivität des Bot-Präventionssystems zu verbessern: Dies wird uns helfen, den Dislike-Zähler als gute Repräsentation der tatsächlichen Anzahl zu halten. Natürlich wird es nie zu 100% genau sein, also liegt es an Ihnen zu entscheiden, ob Sie dem Zähler vertrauen oder nicht. + +### Warum teilen Sie den Backend-Code nicht? + +Wir werden ihn irgendwann teilen - aber es gibt wirklich keinen echten Grund, ihn jetzt zu teilen. Es vermittelt ein falsches Sicherheitsgefühl - denn in einem Zero-Trust-System könnten wir genauso gut eine Version offenlegen, aber eine andere bereitstellen. Es gibt viele Gründe, den Code verborgen zu halten, insbesondere wie wir gegen Spam kämpfen. Das Verbergen/Verfremden des Spam-Behandlungscodes ist eine ziemlich standardmäßige Praxis. diff --git a/Docs/SECURITY-FAQfr.md b/Docs/SECURITY-FAQfr.md index 877a95ab..2e30032b 100644 --- a/Docs/SECURITY-FAQfr.md +++ b/Docs/SECURITY-FAQfr.md @@ -1,8 +1,8 @@ -Lisez ceci dans d'autres langues : [English](SECURITY-FAQ.md) +Lisez ceci dans d'autres langues : [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md), [Deutsch](SECURITY-FAQde.md) # Sécurité -### Est-ce que vous traquer l'historique des vidéos que je visionne ? +### Est-ce que vous traquez l'historique des vidéos que je visionne ? Non. Le code de l'extension est public et vous pouvez le voir par vous-même. La seule information envoyée est l'ID de la vidéo, qui est nécessaire pour récupérer le nombre de dislikes des vidéos. Aucun en-tête (headers) supplémentaire n'est envoyé. Sur la [couche de communication](https://fr.wikipedia.org/wiki/Mod%C3%A8le_OSI#Caract%C3%A9risation_r%C3%A9sum%C3%A9e_des_couches), votre adresse IP publique sera exposée au serveur, ainsi que l'heure à laquelle la demande a été faite. Toutefois, aucun de ces éléments ne permet de vous identifier de manière unique. Dans un environnement où vous ne pouvez avoir confiance en personne (zero-trust environment), le mieux que l'on puisse obtenir est une IP dynamique. Qui, aujourd'hui est la vôtre, demain est celle de votre voisin. Si vous êtes vraiment inquiet que votre IP soit tracée, vous utilisez probablement déjà un VPN. diff --git a/Docs/SECURITY-FAQnl.md b/Docs/SECURITY-FAQnl.md new file mode 100644 index 00000000..d7b9570d --- /dev/null +++ b/Docs/SECURITY-FAQnl.md @@ -0,0 +1,41 @@ +Lees dit in andere talen: [English](SECURITY_FAQ.md), [русский](SECURITY-FAQru.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md), [Deutsch](SECURITY-FAQde.md) + +# Veiligheid + +### Houd je mijn kijkgeschiedenis bij? + +Nee. De code van de extensie is openbaar en u kunt deze zelf zien. De enige informatie die wordt verzonden, is de video-ID, die +nodig is om het aantal dislikes voor de video's op te halen. Er worden geen extra headers verzonden. Via de communicatielaag +wordt uw openbare IP-adres zichtbaar voor de server, evenals het tijdstip waarop het verzoek is gedaan. Geen van deze +identificeert u echter op enigerlei wijze uniek. Uitgaande van een zero-trust-omgeving, is het beste wat we kunnen krijgen een +dynamisch IP-adres. Wat vandaag van jou is, morgen van je buurman. Als u zich echt zorgen maakt dat uw IP-adres wordt +getraceerd, gebruikt u waarschijnlijk al een VPN. + +### Kun je me uniek identificeren als ik een hekel heb? + +Ja. Als je een video niet leuk vindt, maken we een willekeurig gegenereerde unieke ID voor je die niet is gekoppeld aan je +Google-account. Dit wordt gedaan om botting te voorkomen. Maar er is geen manier om deze willekeurige id aan jou of je +persoonlijke YouTube-account te koppelen. + +### Welke informatie heb je precies? + +Alleen de video-ID. Niet je opmerkingen, niet je gebruikersnaam, niet met wie je de video hebt gedeeld, geen aanvullende +metadata. Niks. Alleen de video-ID. + +### Hoe wordt mijn IP opgeslagen? + +De backend bewaart niet-gehashte IP-adressen alleen in vluchtig geheugen (RAM). Deze adressen worden niet opgeslagen op een +harde schijf en worden daarom niet gelogd. We hashen de IP-adressen en dat wordt in plaats daarvan opgeslagen. Dit wordt gedaan +om databasevandalisme te voorkomen. + +### Ik hoorde wat discussie over OAuth en toegang tot mijn YouTube-account! + +Deze functie zal optioneel zijn, en zeer veel opt-in. Als je een YouTube-creator bent en je wilt je afkeerstatistieken met ons delen, dan kan dat. De weg [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) gestructureerd was, is het eigenlijk heel veilig. U kunt op elk moment de toegang tot uw account intrekken en ons zeer specifieke machtigingen geven. We zullen geen toestemming vragen die niet vereist zijn. We vragen alleen toestemming om je videostatistieken te bekijken. + +### Hoe kan ik deze afkeertelling vertrouwen? + +We hebben maatregelen genomen om botaanvallen te voorkomen en zullen blijven werken aan het verbeteren van de effectiviteit van het botpreventiesysteem: dit zal ons helpen het aantal afkeer als een goede vertegenwoordiger van het werkelijke aantal te houden. Natuurlijk zal het nooit 100% nauwkeurig zijn, dus het is aan jou om te beslissen of je de telling vertrouwt of niet. + +### Waarom deel je de backend-code niet? + +We zullen het op een gegeven moment delen - maar er is echt geen echte reden om het nu te delen. Het geeft een vals gevoel van veiligheid - omdat we in een zero-trust-systeem net zo goed de ene versie kunnen onthullen, maar een andere kunnen implementeren. Er zijn tal van redenen om de code verborgen te houden, met name hoe we spam bestrijden. Het verbergen/verduisteren van de spamverwerkingscode is een vrij standaardpraktijk. diff --git a/Docs/SECURITY-FAQpl.md b/Docs/SECURITY-FAQpl.md new file mode 100644 index 00000000..c61af460 --- /dev/null +++ b/Docs/SECURITY-FAQpl.md @@ -0,0 +1,31 @@ +Read this in other languages: [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md), [Deutsch](SECURITY-FAQde.md) + +# Security + +### Czy śledzicie moją historię wyświetleń? + +Nie. Kod rozszerzenia jest publiczny i można samemu to zobaczyć. Jedyne informacje, które są wysyłane, to ID filmu, które jest wymagane do pobrania liczby łapek w dół dla filmów. Nie są wysyłane żadne dodatkowe nagłówki. W warstwie sieciowej, Twój adres IP będzie jawny dla serwera wraz z czasem wykonania żądania. Jednakże, żadne z tych danych nie identyfikują Ciebie jednoznacznie w żaden sposób. Zakładając środowisko zerowego zaufania, najczulsze dane, jakie możemy otrzymać, jest dynamiczny adres IP, który dzisiaj jest Twój, a jutro Twojego sąsiada. Jeżeli boisz się śledzenia poprzez adres IP, pewnie już korzystasz z VPN. + +### Czy możecie mnie jednoznacznie zidentyfikować, jeżeli zostawię łapkę w dół? + +Tak. Kiedy zostawiasz łapkę w dół, tworzymy losowo generowane ID dla Ciebie, które nie jest związane z Twoim kontem Google. Powodem takiego rozwiązania jest zapobieganie botowaniu. Mimo to, nie ma sposobu powiązania tego losowego ID z Tobą lub Twoim osobistym kontem Google. + +### Jakie informacje wy macie, konkretnie? + +Tylko ID filmu. Komentarze - nie. Nazwa użytkownika - nie. Osoby, którym udostępniłeś film - nie. Jakiekolwiek dodatkowe metadane - nie. Nic. Tylko ID filmu. + +### Jak mój adres IP jest przechowywany? + +Backend trzyma niehashowane adresy IP tylko w pamięci zmiennej (RAM). Te adresy nie są przechowywane na dysku twardym, przez co nie są rejestrowane. Zamiast tego przechowujemy zhashowany adres IP. Jest to zrobione po to aby zapobiec wandalizmom. + +### Słyszałem jakąś dyskusję o OAuth, i dostępie do mojego konta YouTube. + +Ta funkcjonalność będzie opcjonalna i z całą pewnością wymagała ręcznego dołączenia. Jeżeli jesteś twórcą na YouTube i chcesz podzielić się z nami swoimi statystykami, to możesz. Sposób w jaki [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) został ustrukturyzowany jest właściwie bardzo bezpieczny. Możesz wycofać dostęp do konta w każdej chwili i dać nam specyficzne uprawnienia. Nie będziemy prosić o żadne uprawnienia, które nie są wymagane. Poprosimy tylko o możliwość wyświetlenia statystyk filmów. + +### Jak bardzo mogę ufać licznikowi łapek w dół? + +Zaimplementowaliśmy środki zapobiegające atakom botów i będziemy kontynuować pracę nad systemem zapobiegającym botom: to pomoże nam utrzymać licznik łapek w dół jako dobrą reprezentację prawdziwej wartości. Oczywiście, wartość ta nigdy nie będzie w 100% dokładna, więc to czy zaufasz tej liczbie zależy tylko od Ciebie. + +### Dlaczego nie udostępnicie kodu backendu? + +Kiedyś go udostępnimy - ale nie ma za bardzo sensu robić to teraz. Wprowadziłoby to fałszywe poczucie bezpieczeństwa - bo w systemie zerowego zaufania równie dobrze moglibyśmy przedstawić jeden system, a uruchomić inny. Jest dużo powodów do ukrywania kodu, specyficznie do walki ze spamem. Ukrywanie/Obfuskacja kodu jest dość standardową praktyką. diff --git a/Docs/SECURITY-FAQpt_BR.md b/Docs/SECURITY-FAQpt_BR.md new file mode 100644 index 00000000..ea19804e --- /dev/null +++ b/Docs/SECURITY-FAQpt_BR.md @@ -0,0 +1,31 @@ +Leia isso em outros idiomas: [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md) + +# Segurança + +### Are you tracking my viewing history? + +No. The extension's code is public and you can see it for yourself. The only information being sent is the video ID, which is required to fetch the dislike count for the videos. There are no additional headers being sent. Over the communication layer, your public IP will be exposed to the server, as well as the time when the request was made. However, none of these are uniquely identifying you in any way. Assuming a zero-trust environment, the best we could get is a dynamic IP. Which, today is yours, tomorrow is your neighbor's. If you're really worried about your IP being traced, you probably already use a VPN. + +### Can you uniquely identify me if I dislike? + +Yes. When you dislike a video, we create a randomly generated unique ID for you that is not tied to your Google account. This is done to prevent botting. But there is no way to tie this random Id to you or your personal YouTube account. + +### Quais as informações que você tem, exatamente? + +Somente seu video ID. Não temos seus comentarios, seu nome de usuario, ou qualquer outro Not your comments, not your username, not who you've shared the video with, not any additional metadata. NADA. Apenas seu Video ID. + +### How is my IP stored? + +The backend keeps unhashed IP addresses in volatile memory (RAM) only. These addresses aren't stored on a hard drive, and therefore aren't logged. We hash the IP addresses, and that's stored instead. This is done to prevent database vandalism. + +### I heard some discussion over OAuth, and access to my YouTube account! + +This feature will be optional, and very much opt-in. If you are a YouTube creator, and would like to share your dislike stats with us, you can. The way [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) was structured, it's actually very secure. You can revoke access to your account at any time, and can give very specific permissions to us. We will not ask for any permissions that aren't required. We'll only ask for permissions to view your video stats. + +### How can I trust this dislike count? + +We have implemented measures to prevent bot attacks and are gonna continue to work on improving the effectiveness of the bot prevention system: this will help us keep the dislike count as a good representative of the actual count. Of course it will never be 100% accurate so it's up to you to decide whether you trust the count or not. + +### Why don't you share the backend code? + +We will share it at some point - but there's really no real reason to share it right now. It gives a false sense of security - because in a zero-trust system, we could just as well disclose one version but deploy another. There are plenty of reasons to keep the code hidden, specifically, how we battle spam. Hiding/Obfuscating the spam handling code is a fairly standard practice. diff --git a/Docs/SECURITY-FAQru.md b/Docs/SECURITY-FAQru.md index 34526993..90c6519e 100644 --- a/Docs/SECURITY-FAQru.md +++ b/Docs/SECURITY-FAQru.md @@ -1,4 +1,4 @@ -Прочитать на других языках: [English](SECURITY-FAQ.md) +Прочитать на других языках: [English](SECURITY-FAQ.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md), [Deutsch](SECURITY-FAQde.md) # Безопасность diff --git a/Docs/SECURITY-FAQtr.md b/Docs/SECURITY-FAQtr.md new file mode 100644 index 00000000..d3f60d4f --- /dev/null +++ b/Docs/SECURITY-FAQtr.md @@ -0,0 +1,31 @@ +Read this in other languages: [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md), [Deutsch](SECURITY-FAQde.md) + +# Güvenlik + +### İzleme geçmişimi takip ediyor musunuz? + +Hayır. Uzantının kodu herkese açıktır ve kendiniz görebilirsiniz. Gönderilen tek bilgi, videolar için dislike sayısını almak için gereken video kimliğidir. Gönderilen başka bir ek header yoktur. İletişim katmanı üzerinden, genel IP'niz sunucuya ve isteğin yapıldığı zamana maruz kalacaktır. Ancak, bunların hiçbiri sizi hiçbir şekilde benzersiz bir şekilde tanımlamıyor. Sıfır güven ortamını varsayarsak, elde edebileceğimizin en iyisi dinamik bir IP'dir. Ki, bu IP bugün sizin, yarın komşunuzun olabilir. IP'nizin izlenmesinden gerçekten endişeleniyorsanız, muhtemelen zaten bir VPN kullanıyorsunuzdur. + +### Bir videoya dislike atarsam, beni benzersiz bir şekilde tanımlayabilir misiniz? + +Evet. Bir videoya dislike attığınızda, sizin için Google hesabınızla bağlantılı olmayan rastgele oluşturulmuş benzersiz bir kimlik oluştururuz. Bu, bot kullanılmasını önlemek için yapılır. Ancak bu rastgele kimliği, size veya kişisel YouTube hesabınıza bağlamanın bir yolu yoktur. + +### Tam olarak hangi bilgilere sahipsiniz, gerçekten? + +Sadece video ID'si. Yorumlarınızı değil, kullanıcı adınızı değil, videoyu kiminle paylaştığınız değil, ek meta verilerinden hiçbiri değil. Hiç bir şey. Sadece video ID'si. + +### IP adresim nasıl saklanıyor? + +Backend, karma olmayan IP adreslerini yalnızca geçici bellekte (RAM'de) tutar. Bu adresler, bir sabit sürücüde depolanmaz ve bu nedenle günlüğe kaydedilmez. IP adreslerini hash ederiz ve bunun yerine depolanır. Bu, veri tabanı vandalizmini önlemek için yapılır. + +### OAuth üzerinden YouTube hesabıma erişmek konusunda bazı tartışmalar duydum! + +Bu özellik isteğe bağlı olacak ve çok fazla tercih edilecek. Bir YouTube içerik üreticisiyseniz ve dislike istatistiklerinizi bizimle paylaşmak istiyorsanız, bunu yapabilirsiniz. [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) yapılandırılma şekli, aslında çok güvenlidir. Hesabınıza erişimi istediğiniz zaman iptal edebilir ve bize çok özel izinler verebilirsiniz. Gerekli olmayan herhangi bir izini istemeyeceğiz. Yalnızca video istatistiklerinizi görüntülemek için izin isteyeceğiz. + +### Bu dislike sayısına nasıl güvenebilirim? + +Bot saldırılarını önlemek için önlemler aldık ve bot önleme sisteminin etkinliğini arttırmak için çalışmaya devam edeceğiz: bu, dislike sayısını gerçek sayının iyi bir temsilcisi olarak tutmamıza yardımcı olacaktır. Tabii ki hiçbir zaman %100 doğru olmayacaktır, bu yüzden sayıma güvenip güvenmemek size kalmıştır. + +### Neden backend kodunu paylaşmıyorsunuz? + +Bir noktada paylaşacağız - ama şu anda paylaşmak için ortada gerçekten gerçek bir sebep yok. Yanlış bir güvenlik hissi verebilir - çünkü sıfır güvenli bir sistemde, bir sürümü ifşa edebilir, ancak bir başkasını devreye alabiliriz. Özellikle spam ile nasıl mücadele ettiğimiz gibi, kodu gizli tutmak için birçok neden vardır. İstenmeyen posta işleme kodunu örtmek/gizlemek oldukça standart bir uygulamadır. diff --git a/Docs/SECURITY-FAQuk.md b/Docs/SECURITY-FAQuk.md new file mode 100644 index 00000000..b4fe3c2f --- /dev/null +++ b/Docs/SECURITY-FAQuk.md @@ -0,0 +1,31 @@ +Read this in other languages: [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [Polski](SECURITY-FAQpl.md), [Deutsch](SECURITY-FAQde.md) + +# Безпека + +### Ви відстежуєте мою історію переглядів? + +Ні. Код розширення знаходиться у відкритому доступі, і ви можете ознайомитись з ним самостійно. Єдина інформація, що передається - це ID відео, який необхідний для отримання даних про кількість відміток. Жодних додаткових заголовків не передається. На комунікаційному рівні серверу буде передано вашу публічну IP-адресу, а також час, коли було зроблено запит. Однак ніщо з цього ніяк не здатно вас ідентифіквати. Припускаючи середовище з нульовою довірою, найцінніше, що ми можемо отримати це динамічний IP. Який сьогодні ваш, а завтра – вашого сусіда. Якщо ви дійсно турбуєтеся про те, що ваш IP може бути відстежений, ви, ймовірно, вже використовуєте якийсь VPN. + +### Чи можете ви однозначно ідентифікувати мене, коли я залишаю відмітку «Не подобається»? + +Так. Коли ви залишаєте відео позначку «Не подобається», ми створюємо для вас випадковий унікальний ID, який не прив'язаний до вашого облікового запису Google. Це робиться для уникнення атаки ботів. Але немає жодного способу зв'язати цей випадковий ID до вас або вашого особистого облікового запису YouTube. + +### Якою саме інформацією ви володієте? + +Лише ID відео. Ні ваших коментарів, ні вашого імені користувача, ні того, з ким ви поділилися відео, ні будь-яких інших додаткових метаданих. Нічого. Лише ID відео. + +### Як зберігається моя IP-адреса? + +Внутрішня частина нашого сервера зберігає нехешовані IP-адреси лише в енергозалежній пам'яті (ОЗП). Ці адреси не зберігаються на жорсткому диску і тому ніде не записані. Ми хешуємо IP-адреси, і вони зберігаються замість інших. Це зроблено для запобігання вандалізму у базі даних. + +### Я чув дискусію щодо OAuth і доступу до мого облікового запису YouTube! + +Ця функція буде необов'язковою та дуже необхідною. Якщо ви творець YouTube і хочете поділитися з нами кількістю ваших відміток «Не подобається», ви зможете це зробити. За структурою [OAuth](https://uk.wikipedia.org/wiki/OAuth#:~:text=%D0%B1%D0%B5%D0%B7%20%D0%BD%D0%B5%D0%BE%D0%B1%D1%85%D1%96%D0%B4%D0%BD%D0%BE%D1%81%D1%82%D1%96%20%D0%B2%D0%B2%D0%BE%D0%B4%D1%83%20%D1%96%D0%BC%D0%B5%D0%BD%D1%96%20%D0%BA%D0%BE%D1%80%D0%B8%D1%81%D1%82%D1%83%D0%B2%D0%B0%D1%87%D0%B0%20%D1%82%D0%B0%20%D0%BF%D0%B0%D1%80%D0%BE%D0%BB%D1%8E) надбезпечний. Ви зможете відкликати доступ до свого облікового запису в будь-яку мить, і зможете дати нам обмежені дозволи. Ми не будемо вимагати жодних дозволів, крім необжідних. Ми будемо вимагати лише дозволи перегляду статистики ваших відео. + +### Наскільки достовірна ця кількость відміток «Не подобається»? + +Ми вжили заходів щодо запобігання атакам ботів і збираємося продовжувати працювати над підвищенням ефективності цієї сисеми надалі: це допоможе нам зберегти підрахунок відміток «Не подобається» як хороше представлення фактичної кількості. Звичайно, він ніколи не буде точним на всі 100%, тож ви самі вирішуєте, довіряти йому чи ні. + +### Чому б вам не поділитися внутрішнім кодом вашого сервера? + +Ми поділимося ним у якийсь момент – але зараз немає жодних причин це робити. Це дасть хибне почуття безпеки - адже в системі з нульовою довірою ми можемо з таким самим успіхом поділитися однією версією, але розгорнути іншу. Є багато причин тримати код у таємниці, зокрема, як ми боремося зі спамом. Приховування та затьмарення коду обробки спаму є доволі стандартною практикою. diff --git a/Docs/readme.md b/Docs/readme.md index b6949e05..e014fe8f 100644 --- a/Docs/readme.md +++ b/Docs/readme.md @@ -1,4 +1,4 @@ -Read this in other languages: [Français](readmefr.md) +Read this in other languages: [Nederlands](readmenl.md), [Français](readmefr.md), [Türkçe](readmetr.md) **Contents** @@ -22,8 +22,8 @@ Read this in other languages: [Français](readmefr.md) ## FAQs -- [General](https://github.com/Anarios/return-youtube-dislike/blob/main/Guides/FAQ.md) -- [Security](https://github.com/Anarios/return-youtube-dislike/blob/main/Guides/SECURITY-FAQ.md) +- [General](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQ.md) +- [Security](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/SECURITY-FAQ.md) + +
+ +## Gidsen + +- [Downloaden, installeren en gebruiken](https://github.com/Anarios/return-youtube-dislike/wiki/Downloading,-Installing-&-Using) +- [Probleemoplossen](https://github.com/Anarios/return-youtube-dislike/wiki/Troubleshooting-Guide) + + + +
+ +## FAQs + +- [Algemeen](https://github.com/Anarios/return-youtube-dislike/blob/main/Guides/FAQ.md) +- [Beveiliging](https://github.com/Anarios/return-youtube-dislike/blob/main/Guides/SECURITY-FAQ.md) + + diff --git a/Docs/readmept_BR.md b/Docs/readmept_BR.md new file mode 100644 index 00000000..bfe92b42 --- /dev/null +++ b/Docs/readmept_BR.md @@ -0,0 +1,39 @@ +Leia isso em outros idiomas: [Nederlands](readmenl.md), [Français](readmefr.md), [Türkçe](readmetr.md) + +**Contents** + +- [Guides](#guides) +- [FAQs](#faqs) + + +
+ +## Guides + +- [Downloading, Installing & Using](https://github.com/Anarios/return-youtube-dislike/wiki/Downloading,-Installing-&-Using) +- [Troubleshooting](https://github.com/Anarios/return-youtube-dislike/wiki/Troubleshooting-Guide) + + + +
+ +## FAQs + +- [General](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQ.md) +- [Security](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/SECURITY-FAQ.md) + + diff --git a/Docs/readmetr.md b/Docs/readmetr.md new file mode 100644 index 00000000..49145023 --- /dev/null +++ b/Docs/readmetr.md @@ -0,0 +1,39 @@ +Read this in other languages: [English](readme.md), [Nederlands](readmenl.md), [Français](readmefr.md) + +**İçerikler** + +- [Rehberler](#rehberler) +- [SSS'ler](#sss'ler) + + +
+ +## Rehberler + +- [İndirme, Yükleme ve Kullanma](https://github.com/Anarios/return-youtube-dislike/wiki/Downloading,-Installing-&-Using) +- [Sorun Giderme](https://github.com/Anarios/return-youtube-dislike/wiki/Troubleshooting-Guide) + + + +
+ +## SSS'ler + +- [Genel](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQtr.md) +- [Güvenlik](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/SECURITY-FAQtr.md) + + diff --git a/Extensions/UserScript/Return Youtube Dislike.user.js b/Extensions/UserScript/Return Youtube Dislike.user.js index 253344c7..2bb961c2 100644 --- a/Extensions/UserScript/Return Youtube Dislike.user.js +++ b/Extensions/UserScript/Return Youtube Dislike.user.js @@ -2,7 +2,7 @@ // @name Return YouTube Dislike // @namespace https://www.returnyoutubedislike.com/ // @homepage https://www.returnyoutubedislike.com/ -// @version 3.0.1 +// @version 3.1.5 // @encoding utf-8 // @description Return of the YouTube Dislike, Based off https://www.returnyoutubedislike.com/ // @icon https://github.com/Anarios/return-youtube-dislike/raw/main/Icons/Return%20Youtube%20Dislike%20-%20Transparent.png @@ -28,6 +28,7 @@ const extConfig = { // You may change the following variables to allowed values listed in the corresponding brackets (* means default). Keep the style and keywords intact. showUpdatePopup: false, // [true, false*] Show a popup tab after extension update (See what's new) disableVoteSubmission: false, // [true, false*] Disable like/dislike submission (Stops counting your likes and dislikes) + disableLogging: true, // [true*, false] Disable Logging API Response in JavaScript Console. coloredThumbs: false, // [true, false*] Colorize thumbs (Use custom colors for thumb icons) coloredBar: false, // [true, false*] Colorize ratio bar (Use custom colors for ratio bar) colorTheme: "classic", // [classic*, accessible, neon] Color theme (red/green, blue/yellow, pink/cyan) @@ -35,6 +36,7 @@ const extConfig = { numberDisplayRoundDown: true, // [true*, false] Round down numbers (Show rounded down numbers) tooltipPercentageMode: "none", // [none*, dash_like, dash_dislike, both, only_like, only_dislike] Mode of showing percentage in like/dislike bar tooltip. numberDisplayReformatLikes: false, // [true, false*] Re-format like numbers (Make likes and dislikes format consistent) + rateBarEnabled: false, // [true, false*] Enables ratio bar under like/dislike buttons // END USER OPTIONS }; @@ -44,13 +46,16 @@ const NEUTRAL_STATE = "NEUTRAL_STATE"; let previousState = 3; //1=LIKED, 2=DISLIKED, 3=NEUTRAL let likesvalue = 0; let dislikesvalue = 0; +let preNavigateLikeButton = null; let isMobile = location.hostname == "m.youtube.com"; let isShorts = () => location.pathname.startsWith("/shorts"); let mobileDislikes = 0; function cLog(text, subtext = "") { - subtext = subtext.trim() === "" ? "" : `(${subtext})`; - console.log(`[Return YouTube Dislikes] ${text} ${subtext}`); + if (!extConfig.disableLogging) { + subtext = subtext.trim() === "" ? "" : `(${subtext})`; + console.log(`[Return YouTube Dislikes] ${text} ${subtext}`); + } } function isInViewport(element) { @@ -58,6 +63,9 @@ function isInViewport(element) { const height = innerHeight || document.documentElement.clientHeight; const width = innerWidth || document.documentElement.clientWidth; return ( + // When short (channel) is ignored, the element (like/dislike AND short itself) is + // hidden with a 0 DOMRect. In this case, consider it outside of Viewport + !(rect.top == 0 && rect.left == 0 && rect.bottom == 0 && rect.right == 0) && rect.top >= 0 && rect.left >= 0 && rect.bottom <= height && @@ -68,9 +76,7 @@ function isInViewport(element) { function getButtons() { if (isShorts()) { let elements = document.querySelectorAll( - isMobile - ? "ytm-like-button-renderer" - : "#like-button > ytd-like-button-renderer" + isMobile ? "ytm-like-button-renderer" : "#like-button > ytd-like-button-renderer", ); for (let element of elements) { if (isInViewport(element)) { @@ -79,81 +85,129 @@ function getButtons() { } } if (isMobile) { - return document.querySelector(".slim-video-action-bar-actions"); + return ( + document.querySelector(".slim-video-action-bar-actions .segmented-buttons") ?? + document.querySelector(".slim-video-action-bar-actions") + ); } if (document.getElementById("menu-container")?.offsetParent === null) { - return document.querySelector("ytd-menu-renderer.ytd-watch-metadata > div"); + return ( + document.querySelector("ytd-menu-renderer.ytd-watch-metadata > div") ?? + document.querySelector("ytd-menu-renderer.ytd-video-primary-info-renderer > div") + ); + } else { + return document.getElementById("menu-container")?.querySelector("#top-level-buttons-computed"); + } +} + +function getDislikeButton() { + if (getButtons().children[0].tagName === "YTD-SEGMENTED-LIKE-DISLIKE-BUTTON-RENDERER") { + if (getButtons().children[0].children[1] === undefined) { + return document.querySelector("#segmented-dislike-button"); + } else { + return getButtons().children[0].children[1]; + } } else { - return document - .getElementById("menu-container") - ?.querySelector("#top-level-buttons-computed"); + if (getButtons().querySelector("segmented-like-dislike-button-view-model")) { + const dislikeViewModel = getButtons().querySelector("dislike-button-view-model"); + if (!dislikeViewModel) cLog("Dislike button wasn't added to DOM yet..."); + return dislikeViewModel; + } else { + return getButtons().children[1]; + } } } function getLikeButton() { - return getButtons().children[0]; + return getButtons().children[0].tagName === "YTD-SEGMENTED-LIKE-DISLIKE-BUTTON-RENDERER" + ? document.querySelector("#segmented-like-button") !== null + ? document.querySelector("#segmented-like-button") + : getButtons().children[0].children[0] + : getButtons().querySelector("like-button-view-model") ?? getButtons().children[0]; } -function getDislikeButton() { - return getButtons().children[1]; +function getLikeTextContainer() { + return ( + getLikeButton().querySelector("#text") ?? + getLikeButton().getElementsByTagName("yt-formatted-string")[0] ?? + getLikeButton().querySelector("span[role='text']") + ); } -let mutationObserver = new Object(); +function getDislikeTextContainer() { + const dislikeButton = getDislikeButton(); + let result = + dislikeButton?.querySelector("#text") ?? + dislikeButton?.getElementsByTagName("yt-formatted-string")[0] ?? + dislikeButton?.querySelector("span[role='text']"); + if (result === null) { + let textSpan = document.createElement("span"); + textSpan.id = "text"; + textSpan.style.marginLeft = "6px"; + dislikeButton?.querySelector("button").appendChild(textSpan); + if (dislikeButton) dislikeButton.querySelector("button").style.width = "auto"; + result = textSpan; + } + return result; +} -if (isShorts() && mutationObserver.exists !== true) { - cLog("initializing mutation observer"); - mutationObserver.options = { - childList: false, - attributes: true, - subtree: false, +function createObserver(options, callback) { + const observerWrapper = new Object(); + observerWrapper.options = options; + observerWrapper.observer = new MutationObserver(callback); + observerWrapper.observe = function (element) { + this.observer.observe(element, this.options); + }; + observerWrapper.disconnect = function () { + this.observer.disconnect(); }; - mutationObserver.exists = true; - mutationObserver.observer = new MutationObserver(function ( - mutationList, - observer - ) { - mutationList.forEach((mutation) => { - if ( - mutation.type === "attributes" && - mutation.target.nodeName === "TP-YT-PAPER-BUTTON" && - mutation.target.id === "button" - ) { - cLog("Short thumb button status changed"); - if (mutation.target.getAttribute("aria-pressed") === "true") { - mutation.target.style.color = - mutation.target.parentElement.parentElement.id === "like-button" - ? getColorFromTheme(true) - : getColorFromTheme(false); - } else { - mutation.target.style.color = "unset"; + return observerWrapper; +} + +let shortsObserver = null; + +if (isShorts() && !shortsObserver) { + cLog("Initializing shorts mutation observer"); + shortsObserver = createObserver( + { + attributes: true, + }, + (mutationList) => { + mutationList.forEach((mutation) => { + if ( + mutation.type === "attributes" && + mutation.target.nodeName === "TP-YT-PAPER-BUTTON" && + mutation.target.id === "button" + ) { + cLog("Short thumb button status changed"); + if (mutation.target.getAttribute("aria-pressed") === "true") { + mutation.target.style.color = + mutation.target.parentElement.parentElement.id === "like-button" + ? getColorFromTheme(true) + : getColorFromTheme(false); + } else { + mutation.target.style.color = "unset"; + } + return; } - return; - } - cLog( - "unexpected mutation observer event: " + mutation.target + mutation.type - ); - }); - }); + cLog("Unexpected mutation observer event: " + mutation.target + mutation.type); + }); + }, + ); } function isVideoLiked() { if (isMobile) { - return ( - getLikeButton().querySelector("button").getAttribute("aria-label") == - "true" - ); + return getLikeButton().querySelector("button").getAttribute("aria-label") == "true"; } return getLikeButton().classList.contains("style-default-active"); } function isVideoDisliked() { if (isMobile) { - return ( - getDislikeButton().querySelector("button").getAttribute("aria-label") == - "true" - ); + return getDislikeButton()?.querySelector("button").getAttribute("aria-label") == "true"; } - return getDislikeButton().classList.contains("style-default-active"); + return getDislikeButton()?.classList.contains("style-default-active"); } function isVideoNotLiked() { @@ -167,7 +221,7 @@ function isVideoNotDisliked() { if (isMobile) { return !isVideoDisliked(); } - return getDislikeButton().classList.contains("style-text"); + return getDislikeButton()?.classList.contains("style-text"); } function checkForUserAvatarButton() { @@ -193,11 +247,10 @@ function getState() { function setLikes(likesCount) { if (isMobile) { - getButtons().children[0].querySelector(".button-renderer-text").innerText = - likesCount; + getButtons().children[0].querySelector(".button-renderer-text").innerText = likesCount; return; } - getButtons().children[0].querySelector("#text").innerText = likesCount; + getLikeTextContainer().innerText = likesCount; } function setDislikes(dislikesCount) { @@ -205,20 +258,25 @@ function setDislikes(dislikesCount) { mobileDislikes = dislikesCount; return; } - getButtons().children[1].querySelector("#text").innerText = dislikesCount; + getDislikeTextContainer()?.removeAttribute("is-empty"); + getDislikeTextContainer().innerText = dislikesCount; } function getLikeCountFromButton() { - if (isShorts()) { - //Youtube Shorts don't work with this query. It's not nessecary; we can skip it and still see the results. - //It should be possible to fix this function, but it's not critical to showing the dislike count. + try { + if (isShorts()) { + //Youtube Shorts don't work with this query. It's not necessary; we can skip it and still see the results. + //It should be possible to fix this function, but it's not critical to showing the dislike count. + return false; + } + let likeButton = + getLikeButton().querySelector("yt-formatted-string#text") ?? getLikeButton().querySelector("button"); + + let likesStr = likeButton.getAttribute("aria-label").replace(/\D/g, ""); + return likesStr.length > 0 ? parseInt(likesStr) : false; + } catch { return false; } - let likesStr = getLikeButton() - .querySelector("yt-formatted-string#text") - .getAttribute("aria-label") - .replace(/\D/g, ""); - return likesStr.length > 0 ? parseInt(likesStr) : false; } (typeof GM_addStyle != "undefined" @@ -241,10 +299,10 @@ function getLikeCountFromButton() { } .ryd-tooltip { - position: relative; + position: absolute; display: block; height: 2px; - top: 9px; + bottom: -10px; } .ryd-tooltip-bar-container { @@ -252,24 +310,28 @@ function getLikeCountFromButton() { height: 2px; position: absolute; padding-top: 6px; - padding-bottom: 28px; + padding-bottom: 12px; top: -6px; } + + ytd-menu-renderer.ytd-watch-metadata { + overflow-y: visible !important; + } + + #top-level-buttons-computed { + position: relative !important; + } `); function createRateBar(likes, dislikes) { - if (isMobile) { + if (isMobile || !extConfig.rateBarEnabled) { return; } let rateBar = document.getElementById("return-youtube-dislike-bar-container"); - const widthPx = - getButtons().children[0].clientWidth + - getButtons().children[1].clientWidth + - 8; + const widthPx = getLikeButton().clientWidth + (getDislikeButton()?.clientWidth ?? 52); - const widthPercent = - likes + dislikes > 0 ? (likes / (likes + dislikes)) * 100 : 50; + const widthPercent = likes + dislikes > 0 ? (likes / (likes + dislikes)) * 100 : 50; var likePercentage = parseFloat(widthPercent.toFixed(1)); const dislikePercentage = (100 - likePercentage).toLocaleString(); @@ -304,7 +366,7 @@ function createRateBar(likes, dislikes) { colorDislikeStyle = "; background-color: " + getColorFromTheme(false); } - document.getElementById("menu-container").insertAdjacentHTML( + getButtons().insertAdjacentHTML( "beforeend", `
@@ -323,25 +385,18 @@ function createRateBar(likes, dislikes) { ${tooltipInnerHTML}
-` +`, ); + let descriptionAndActionsElement = document.getElementById("top-row"); + descriptionAndActionsElement.style.borderBottom = "1px solid var(--yt-spec-10-percent-layer)"; + descriptionAndActionsElement.style.paddingBottom = "10px"; } else { - document.getElementById( - "return-youtube-dislike-bar-container" - ).style.width = widthPx + "px"; - document.getElementById("return-youtube-dislike-bar").style.width = - widthPercent + "%"; - - document.querySelector("#ryd-dislike-tooltip > #tooltip").innerHTML = - tooltipInnerHTML; + document.querySelector(".ryd-tooltip").style.width = widthPx + "px"; + document.getElementById("return-youtube-dislike-bar").style.width = widthPercent + "%"; if (extConfig.coloredBar) { - document.getElementById( - "return-youtube-dislike-bar-container" - ).style.backgroundColor = getColorFromTheme(false); - document.getElementById( - "return-youtube-dislike-bar" - ).style.backgroundColor = getColorFromTheme(true); + document.getElementById("return-youtube-dislike-bar-container").style.backgroundColor = getColorFromTheme(false); + document.getElementById("return-youtube-dislike-bar").style.backgroundColor = getColorFromTheme(true); } } } @@ -350,9 +405,7 @@ function setState() { cLog("Fetching votes..."); let statsSet = false; - fetch( - `https://returnyoutubedislikeapi.com/votes?videoId=${getVideoId()}` - ).then((response) => { + fetch(`https://returnyoutubedislikeapi.com/votes?videoId=${getVideoId()}`).then((response) => { response.json().then((json) => { if (json && !("traceId" in response) && !statsSet) { const { dislikes, likes } = json; @@ -368,31 +421,22 @@ function setState() { } createRateBar(likes, dislikes); if (extConfig.coloredThumbs === true) { + const dislikeButton = getDislikeButton(); if (isShorts()) { // for shorts, leave deactived buttons in default color - let shortLikeButton = getLikeButton().querySelector( - "tp-yt-paper-button#button" - ); - let shortDislikeButton = getDislikeButton().querySelector( - "tp-yt-paper-button#button" - ); + const shortLikeButton = getLikeButton().querySelector("tp-yt-paper-button#button"); + const shortDislikeButton = dislikeButton?.querySelector("tp-yt-paper-button#button"); if (shortLikeButton.getAttribute("aria-pressed") === "true") { shortLikeButton.style.color = getColorFromTheme(true); } - if (shortDislikeButton.getAttribute("aria-pressed") === "true") { + if (shortDislikeButton && shortDislikeButton.getAttribute("aria-pressed") === "true") { shortDislikeButton.style.color = getColorFromTheme(false); } - mutationObserver.observer.observe( - shortLikeButton, - mutationObserver.options - ); - mutationObserver.observer.observe( - shortDislikeButton, - mutationObserver.options - ); + shortsObserver.observe(shortLikeButton); + shortsObserver.observe(shortDislikeButton); } else { getLikeButton().style.color = getColorFromTheme(true); - getDislikeButton().style.color = getColorFromTheme(false); + if (dislikeButton) dislikeButton.style.color = getColorFromTheme(false); } } } @@ -400,22 +444,25 @@ function setState() { }); } +function updateDOMDislikes() { + setDislikes(numberFormat(dislikesvalue)); + createRateBar(likesvalue, dislikesvalue); +} + function likeClicked() { if (checkForUserAvatarButton() == true) { if (previousState == 1) { likesvalue--; - createRateBar(likesvalue, dislikesvalue); - setDislikes(numberFormat(dislikesvalue)); + updateDOMDislikes(); previousState = 3; } else if (previousState == 2) { likesvalue++; dislikesvalue--; - setDislikes(numberFormat(dislikesvalue)); - createRateBar(likesvalue, dislikesvalue); + updateDOMDislikes(); previousState = 1; } else if (previousState == 3) { likesvalue++; - createRateBar(likesvalue, dislikesvalue); + updateDOMDislikes(); previousState = 1; } if (extConfig.numberDisplayReformatLikes === true) { @@ -431,19 +478,16 @@ function dislikeClicked() { if (checkForUserAvatarButton() == true) { if (previousState == 3) { dislikesvalue++; - setDislikes(numberFormat(dislikesvalue)); - createRateBar(likesvalue, dislikesvalue); + updateDOMDislikes(); previousState = 2; } else if (previousState == 2) { dislikesvalue--; - setDislikes(numberFormat(dislikesvalue)); - createRateBar(likesvalue, dislikesvalue); + updateDOMDislikes(); previousState = 3; } else if (previousState == 1) { likesvalue--; dislikesvalue++; - setDislikes(numberFormat(dislikesvalue)); - createRateBar(likesvalue, dislikesvalue); + updateDOMDislikes(); previousState = 2; if (extConfig.numberDisplayReformatLikes === true) { const nativeLikes = getLikeCountFromButton(); @@ -463,7 +507,7 @@ function getVideoId() { const urlObject = new URL(window.location.href); const pathname = urlObject.pathname; if (pathname.startsWith("/clip")) { - return document.querySelector("meta[itemprop='videoId']").content; + return (document.querySelector("meta[itemprop='videoId']") || document.querySelector("meta[itemprop='identifier']")).content; } else { if (pathname.startsWith("/shorts")) { return pathname.slice(8); @@ -479,7 +523,12 @@ function isVideoLoaded() { const videoId = getVideoId(); return ( - document.querySelector(`ytd-watch-flexy[video-id='${videoId}']`) !== null + // desktop: spring 2024 UI + document.querySelector(`ytd-watch-grid[video-id='${videoId}']`) !== null || + // desktop: older UI + document.querySelector(`ytd-watch-flexy[video-id='${videoId}']`) !== null || + // mobile: no video-id attribute + document.querySelector('#player[loading="false"]:not([hidden])') !== null ); } @@ -498,9 +547,7 @@ function numberFormat(numberState) { } else { numberDisplay = roundDown(numberState); } - return getNumberFormatter(extConfig.numberDisplayFormat).format( - numberDisplay - ); + return getNumberFormatter(extConfig.numberDisplayFormat).format(numberDisplay); } function getNumberFormatter(optionSelect) { @@ -514,12 +561,10 @@ function getNumberFormatter(optionSelect) { userLocales = new URL( Array.from(document.querySelectorAll("head > link[rel='search']")) ?.find((n) => n?.getAttribute("href")?.includes("?locale=")) - ?.getAttribute("href") + ?.getAttribute("href"), )?.searchParams?.get("locale"); } catch { - cLog( - "Cannot find browser locale. Use en as default for number formatting." - ); + cLog("Cannot find browser locale. Use en as default for number formatting."); userLocales = "en"; } } @@ -576,28 +621,54 @@ function getColorFromTheme(voteIsLike) { return colorString; } +let smartimationObserver = null; + function setEventListeners(evt) { let jsInitChecktimer; function checkForJS_Finish() { - console.log(); + //console.log(); if (isShorts() || (getButtons()?.offsetParent && isVideoLoaded())) { const buttons = getButtons(); + const dislikeButton = getDislikeButton(); - if (!window.returnDislikeButtonlistenersSet) { + if (preNavigateLikeButton !== getLikeButton() && dislikeButton) { cLog("Registering button listeners..."); try { - buttons.children[0].addEventListener("click", likeClicked); - buttons.children[1].addEventListener("click", dislikeClicked); - buttons.children[0].addEventListener("touchstart", likeClicked); - buttons.children[1].addEventListener("touchstart", dislikeClicked); + getLikeButton().addEventListener("click", likeClicked); + dislikeButton?.addEventListener("click", dislikeClicked); + getLikeButton().addEventListener("touchstart", likeClicked); + dislikeButton?.addEventListener("touchstart", dislikeClicked); + dislikeButton?.addEventListener("focusin", updateDOMDislikes); + dislikeButton?.addEventListener("focusout", updateDOMDislikes); + preNavigateLikeButton = getLikeButton(); + + if (!smartimationObserver) { + smartimationObserver = createObserver( + { + attributes: true, + subtree: true, + }, + updateDOMDislikes, + ); + smartimationObserver.container = null; + } + + const smartimationContainer = buttons.querySelector("yt-smartimation"); + if (smartimationContainer && smartimationObserver.container != smartimationContainer) { + cLog("Initializing smartimation mutation observer"); + smartimationObserver.disconnect(); + smartimationObserver.observe(smartimationContainer); + smartimationObserver.container = smartimationContainer; + } } catch { return; } //Don't spam errors into the console - window.returnDislikeButtonlistenersSet = true; } - setInitialState(); - clearInterval(jsInitChecktimer); + if (dislikeButton) { + setInitialState(); + clearInterval(jsInitChecktimer); + } } } @@ -618,7 +689,11 @@ if (isMobile) { return originalPush.apply(history, args); }; setInterval(() => { - getDislikeButton().querySelector(".button-renderer-text").innerText = - mobileDislikes; + const dislikeButton = getDislikeButton(); + if (dislikeButton?.querySelector(".button-renderer-text") === null) { + getDislikeTextContainer().innerText = mobileDislikes; + } else { + if (dislikeButton) dislikeButton.querySelector(".button-renderer-text").innerText = mobileDislikes; + } }, 1000); } diff --git a/Extensions/combined/_locales/cs/messages.json b/Extensions/combined/_locales/cs/messages.json index f80e3aca..a786b6a1 100644 --- a/Extensions/combined/_locales/cs/messages.json +++ b/Extensions/combined/_locales/cs/messages.json @@ -42,7 +42,7 @@ "message": "aktualizovat na" }, "version30installed": { - "message": "Verze 3.0.0.1 nainstalována" + "message": "Verze __RYD_VERSION__ nainstalována" }, "whatsnew": { "message": "Co je nového" diff --git a/Extensions/combined/_locales/de/messages.json b/Extensions/combined/_locales/de/messages.json index 9b0a7ba2..288012ae 100644 --- a/Extensions/combined/_locales/de/messages.json +++ b/Extensions/combined/_locales/de/messages.json @@ -23,20 +23,68 @@ "linkHelp": { "message": "Hilfe" }, + "linkChangelog": { + "message": "Änderungshistorie" + }, "legendSettings": { "message": "Einstellungen" }, "textSettings": { "message": "Deaktiviere Like/Dislike-Übermittlung" }, + "textLikesDisabled": { + "message": "Deaktiviert vom Ersteller" + }, "textSettingsHover": { "message": "Stoppt deine Likes und Dislikes zu zählen." }, + "textRoundingNumbers": { + "message": "Runde Likes/Dislikes ab (Standardverhalten von YouTube)" + }, + "textRoundingNumbersHover": { + "message": "Zeige abgerundete Zahlen." + }, + "textConsistentFormat": { + "message": "Mach das Format der Likes und Dislikes einheitlich." + }, + "textConsistentFormatHover": { + "message": "Wie Zahlen neu formatieren" + }, + "textNumberFormat": { + "message": "Zahlenformat:" + }, + "textColorizeRatioBar": { + "message": "Verhältnisbalken einfärben" + }, + "textColorizeRatioBarHover": { + "message": "Benutzerdefinierte Farben für die Verhältnisleiste verwenden." + }, + "textColorizeThumbs": { + "message": "Färbe Daumen-Icons" + }, + "textColorizeThumbsHover": { + "message": "Nutze benutzerdefinierte Farben für die Daumen-Icons." + }, + "textColorTheme": { + "message": "Farbschema:" + }, + "textColorTheme1": { + "message": "Klassisch" + }, + "textColorTheme2": { + "message": "Zugänglich" + }, + "textColorTheme3": { + "message": "Neon" + }, + "textTempUnavailable": { + "message": "Temporär nicht erreichbar" + }, "textUpdate": { "message": "aktualisieren auf" }, "version30installed": { - "message": "Version 3.0.0.1 installiert" + "message": "Version __RYD_VERSION__ installiert" }, "whatsnew": { "message": "Was ist neu" @@ -63,7 +111,7 @@ "message": "Wie Zahlen neu formatieren" }, "reformatLikesHover": { - "message": "Machen Sie das Format der Vorlieben und Abneigungen konsistent." + "message": "Mach das Format der Likes und Dislikes einheitlich." }, "numberFormat": { "message": "Zahlenformat:" diff --git a/Extensions/combined/_locales/el/messages.json b/Extensions/combined/_locales/el/messages.json new file mode 100644 index 00000000..2d8d0553 --- /dev/null +++ b/Extensions/combined/_locales/el/messages.json @@ -0,0 +1,134 @@ +{ + "extensionName": { + "message": "Επιστροφή του YouTube Dislike" + }, + "extensionNameBeta": { + "message": "Return YouTube Dislike Beta" + }, + "extensionDesc": { + "message": "Επιστρέφει τα dislikes" + }, + "textDeveloper": { + "message": "από τον Dmitry Selivanov & την κοινότητα" + }, + "linkWebsite": { + "message": "Ιστοσελίδα" + }, + "linkFAQ": { + "message": "Συχνές ερωτήσεις" + }, + "linkDonate": { + "message": "Στηρίξτε" + }, + "linkHelp": { + "message": "Βοήθεια" + }, + "linkChangelog": { + "message": "Αρχείο αλλαγών" + }, + "legendSettings": { + "message": "Ρυθμίσεις" + }, + "textSettings": { + "message": "Διακοπή υποβολής like/dislike" + }, + "textLikesDisabled": { + "message": "Απενεργοποιήθηκε από τον κάτοχο" + }, + "textSettingsHover": { + "message": "Σταματάει να μετράει τα likes & dislikes που κάνεις." + }, + "textRoundingNumbers": { + "message": "Στρογγυλοποιήστε την τιμή μέτρησης (προεπιλεγμένη επιλογή του YouTube)." + }, + "textRoundingNumbersHover": { + "message": "Εμφάνιση στρογγυλεμένων αριθμών." + }, + "textConsistentFormat": { + "message": "Κάνει σταθερή την μορφοποίηση των likes & dislikes." + }, + "textConsistentFormatHover": { + "message": "Μορφοποίηση του αριθμού των likes." + }, + "textNumberFormat": { + "message": "Μορφή αριθμών:" + }, + "textColorizeRatioBar": { + "message": "Χρωματισμός μπάρας αναλογιών." + }, + "textColorizeRatioBarHover": { + "message": "Προσαρμοζόμενο χρώμα για την μπάρα αναλογιών." + }, + "textColorizeThumbs": { + "message": "Χρωματισμός των thumbs" + }, + "textColorizeThumbsHover": { + "message": "Προσαρμοζόμενο χρώμα για τα thumb icons." + }, + "textColorTheme": { + "message": "Θέματα χρωμάτων:" + }, + "textColorTheme1": { + "message": "Classic" + }, + "textColorTheme2": { + "message": "Accessible" + }, + "textColorTheme3": { + "message": "Neon" + }, + "textTempUnavailable": { + "message": "Προσωρινά μη διαθέσιμο" + }, + "textUpdate": { + "message": "Ενημέρωση σε" + }, + "version30installed": { + "message": "Εκδοση __RYD_VERSION__ εγκαταστάθηκε" + }, + "whatsnew": { + "message": "Τί νέο υπάρχει" + }, + "shortsSupport": { + "message": "Υποστήριξη για YouTube Shorts" + }, + "customColors": { + "message": "Προσαρμοζόμενα χρώματα για τα κουμπιά και την μπάρα dislike" + }, + "customNumberFormats": { + "message": "Προσαρμοζόμενη μορφή αριθμών" + }, + "considerDonating": { + "message": "Το μόνο πράγμα που διατηρεί την επέκταση σε λειτουργία είναι οι δωρεές σας, σκεφτείτε να υποστηρίξετε το έργο." + }, + "roundNumbers": { + "message": "Εμφάνιση στρογγυλεμένων αριθμών" + }, + "roundNumbersHover": { + "message": "Στρογγυλοποιήστε την τιμή μέτρησης (προεπιλεγμένη επιλογή του YouTube)." + }, + "reformatLikes": { + "message": "Μορφοποίηση του αριθμού των likes" + }, + "reformatLikesHover": { + "message": "Σταθερή μορφοποίηση των likes & dislikes." + }, + "numberFormat": { + "message": "Μορφή αριθμών:" + }, + "colorizeRatio": { + "message": "Χρωματισμός μπάρας σχέσης" + }, + "colorizeRatioHover": { + "message": "Προσαρμοζόμενο χρώμα για την μπάρα αναλογιών." + }, + "colorizeThumbs": { + "message": "Χρωματισμός των thumbs" + }, + "colorizeThumbsHover": { + "message": "Προσαρμοζόμενο χρώμα για τα thumb icons." + }, + "colorTheme": { + "message": "Χρωματικό θέμα:" + } +} diff --git a/Extensions/combined/_locales/en/messages.json b/Extensions/combined/_locales/en/messages.json index a5ba9c0d..e481943b 100644 --- a/Extensions/combined/_locales/en/messages.json +++ b/Extensions/combined/_locales/en/messages.json @@ -84,7 +84,7 @@ "message": "Update to" }, "version30installed": { - "message": "Version 3.0.0.1 installed" + "message": "Version __RYD_VERSION__ installed" }, "whatsnew": { "message": "What's new" diff --git a/Extensions/combined/_locales/es/messages.json b/Extensions/combined/_locales/es/messages.json index 3d1ffc41..d44c3e1f 100644 --- a/Extensions/combined/_locales/es/messages.json +++ b/Extensions/combined/_locales/es/messages.json @@ -84,7 +84,7 @@ "message": "actualizar a" }, "version30installed": { - "message": "Versión 3.0.0.1 instalada" + "message": "Versión __RYD_VERSION__ instalada" }, "whatsnew": { "message": "Novedades" diff --git a/Extensions/combined/_locales/fr/messages.json b/Extensions/combined/_locales/fr/messages.json index 95d61936..126ff8bd 100644 --- a/Extensions/combined/_locales/fr/messages.json +++ b/Extensions/combined/_locales/fr/messages.json @@ -6,7 +6,7 @@ "message": "Return YouTube Dislike Beta" }, "extensionDesc": { - "message": "Ré-affiche les pouces rouges/dislikes des vidées" + "message": "Ré-affiche les pouces rouges/dislikes des vidéos" }, "textDeveloper": { "message": "par Dmitry Selivanov & Communauté" @@ -42,7 +42,7 @@ "message": "mettre à jour vers" }, "version30installed": { - "message": "Version 3.0.0.1 installée" + "message": "Version __RYD_VERSION__ installée" }, "whatsnew": { "message": "Quoi de neuf" diff --git a/Extensions/combined/_locales/gr/messages.json b/Extensions/combined/_locales/gr/messages.json deleted file mode 100644 index 269504cd..00000000 --- a/Extensions/combined/_locales/gr/messages.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "extensionName": { - "message": "Επιστροφή του YouTube Dislike" - }, - "extensionNameBeta": { - "message": "Return YouTube Dislike Beta" - }, - "extensionDesc": { - "message": "Επιστρέφει τα dislikes" - }, - "textDeveloper": { - "message": "από τον Dmitry Selivanov & την κοινότητα" - }, - "linkWebsite": { - "message": "Ιστοσελίδα" - }, - "linkFAQ": { - "message": "Γρήγορες Ερωτήσεις & Απαντήσεις" - }, - "linkDonate": { - "message": "Στηρίξτε" - }, - "linkHelp": { - "message": "Βοήθεια" - }, - "legendSettings": { - "message": "Ρυθμίσεις" - }, - "textSettings": { - "message": "Διακοπή υποβολής like/dislike" - }, - "textSettingsHover": { - "message": "Σταματάει να μετράει τα likes & dislikes που κάνεις." - }, - "textUpdate": { - "message": "ενημέρωση σε" - }, - "version30installed": { - "message": "Εκδοση 3.0.0.1 εγκαταστάθηκε" - }, - "whatsnew": { - "message": "Τι είναι νέο;" - }, - "shortsSupport": { - "message": "Υποστήριξη για YouTube Shorts" - }, - "customColors": { - "message": "Προσαρμοζόμενα χρώματα για τα κουμπιά και την μπάρα dislike" - }, - "customNumberFormats": { - "message": "Προσαρμοζόμενη μορφή αριθμών." - }, - "considerDonating": { - "message": "Το μόνο πράγμα που διατηρεί την επέκταση σε λειτουργία είναι οι δωρεές σας, σκεφτείτε να υποστηρίξετε το έργο." - }, - "roundNumbers": { - "message": "Εμφάνιση στρογγυλεμένων αριθμών" - }, - "roundNumbersHover": { - "message": "Στρογγυλοποιήστε την τιμή μέτρησης (αυτή είναι η προεπιλεγμένη επιλογή του YouTube)." - }, - "reformatLikes": { - "message": "Μορφοποίηση του αριθμού των likes" - }, - "reformatLikesHover": { - "message": "Κάνει την αξία των στατιστικών πιο συνεπή." - }, - "numberFormat": { - "message": "Αριθμητική μορφή" - }, - "colorizeRatio": { - "message": "Χρωματίστε τη γραμμή dislikes" - }, - "colorizeRatioHover": { - "message": "Χρωματίστε τη γραμμή dislikes με προσαρμοσμένα χρώματα." - }, - "colorizeThumbs": { - "message": "Χρωματίστε τα κουμπιά" - }, - "colorizeThumbsHover": { - "message": "Χρωματίστε τα κουμπιά likes και dislikes με προσαρμοσμένα χρώματα." - }, - "colorTheme": { - "message": "Χρωματικός συνδυασμός:" - } -} diff --git a/Extensions/combined/_locales/it/messages.json b/Extensions/combined/_locales/it/messages.json index adf6dcbe..14107ef4 100644 --- a/Extensions/combined/_locales/it/messages.json +++ b/Extensions/combined/_locales/it/messages.json @@ -36,7 +36,7 @@ "message": "aggiorna a" }, "version30installed": { - "message": "Versione 3.0.0.1 installata" + "message": "Versione __RYD_VERSION__ installata" }, "whatsnew": { "message": "Quali sono le novità" diff --git a/Extensions/combined/_locales/ja/messages.json b/Extensions/combined/_locales/ja/messages.json index 6a587cc3..2515a0bb 100644 --- a/Extensions/combined/_locales/ja/messages.json +++ b/Extensions/combined/_locales/ja/messages.json @@ -42,7 +42,7 @@ "message": "アップデート:" }, "version30installed": { - "message": "バージョン 3.0.0.1 がインストールされました。" + "message": "バージョン __RYD_VERSION__ がインストールされました。" }, "whatsnew": { "message": "新機能" diff --git a/Extensions/combined/_locales/ko/messages.json b/Extensions/combined/_locales/ko/messages.json new file mode 100644 index 00000000..a1cc6fb5 --- /dev/null +++ b/Extensions/combined/_locales/ko/messages.json @@ -0,0 +1,134 @@ +{ + "extensionName": { + "message": "Return YouTube Dislike" + }, + "extensionNameBeta": { + "message": "Return YouTube Dislike 베타" + }, + "extensionDesc": { + "message": "대략적인 싫어요 갯수를 볼 수 있게 합니다" + }, + "textDeveloper": { + "message": "Dmitry Selivanov와 커뮤니티 제작" + }, + "linkWebsite": { + "message": "웹사이트" + }, + "linkFAQ": { + "message": "FAQ" + }, + "linkDonate": { + "message": "기부" + }, + "linkHelp": { + "message": "도움말" + }, + "linkChangelog": { + "message": "변경사항" + }, + "legendSettings": { + "message": "설정" + }, + "textSettings": { + "message": "좋아요/싫어요 제출 비활성화" + }, + "textLikesDisabled": { + "message": "업로더가 비활성화함" + }, + "textSettingsHover": { + "message": "당신의 좋아요와 싫어요 갯수 계산을 중지합니다." + }, + "textRoundingNumbers": { + "message": "좋아요/싫어요 통계 비활성화(기본 YouTube 동작)" + }, + "textRoundingNumbersHover": { + "message": "반올림된 통계 보이기" + }, + "textConsistentFormat": { + "message": "좋아요와 싫어요 형식을 일관되게 만듭니다" + }, + "textConsistentFormatHover": { + "message": "좋아요 갯수 표시 형식 재정의" + }, + "textNumberFormat": { + "message": "숫자 표시 형식:" + }, + "textColorizeRatioBar": { + "message": "비율 막대 컬러화" + }, + "textColorizeRatioBarHover": { + "message": "비율 막대에 커스텀 색상을 사용합니다." + }, + "textColorizeThumbs": { + "message": "엄지 컬러화" + }, + "textColorizeThumbsHover": { + "message": "엄지 아이콘에 커스텀 색상을 사용합니다." + }, + "textColorTheme": { + "message": "컬러 테마:" + }, + "textColorTheme1": { + "message": "클래식" + }, + "textColorTheme2": { + "message": "Accessible" + }, + "textColorTheme3": { + "message": "네온" + }, + "textTempUnavailable": { + "message": "일시적으로 사용할 수 없음" + }, + "textUpdate": { + "message": "업데이트" + }, + "version30installed": { + "message": "__RYD_VERSION__ 버전이 설치됨" + }, + "whatsnew": { + "message": "새로운 점" + }, + "shortsSupport": { + "message": "유튜브 쇼츠 지원" + }, + "customColors": { + "message": "싫어요 바와 버튼의 색을 커스텀" + }, + "customNumberFormats": { + "message": "숫자 표시 형식 커스텀" + }, + "considerDonating": { + "message": "확장 프로그램을 계속 돌아가게 할 수 있는 유일한 방법은 당신의 기부이며, 프로젝트에 지원하는 것을 고려해 주세요." + }, + "roundNumbers": { + "message": "반올림된 숫자 표시" + }, + "roundNumbersHover": { + "message": "반올림된 숫자(기본 유튜브 동작)." + }, + "reformatLikes": { + "message": "좋아요 갯수 표시 형식 재정의" + }, + "reformatLikesHover": { + "message": "좋아요와 싫어요 형식을 일관되게 만듭니다." + }, + "numberFormat": { + "message": "숫자 표시 형식:" + }, + "colorizeRatio": { + "message": "비율 막대 컬러화" + }, + "colorizeRatioHover": { + "message": "비율 막대에 커스텀 색상을 사용합니다." + }, + "colorizeThumbs": { + "message": "엄지 컬러화" + }, + "colorizeThumbsHover": { + "message": "엄지 아이콘에 커스텀 색상을 사용합니다." + }, + "colorTheme": { + "message": "컬러 테마:" + } +} diff --git a/Extensions/combined/_locales/nl/messages.json b/Extensions/combined/_locales/nl/messages.json new file mode 100644 index 00000000..1a08974d --- /dev/null +++ b/Extensions/combined/_locales/nl/messages.json @@ -0,0 +1,135 @@ +{ + + "extensionName": { + "message": "Return YouTube Dislike" + }, + "extensionNameBeta": { + "message": "Return YouTube Dislike Beta" + }, + "extensionDesc": { + "message": "Herstelt de functie om dislikes te kunnen zien" + }, + "textDeveloper": { + "message": "door Dmitry Selivanov & Gemeenschap" + }, + "linkWebsite": { + "message": "Website" + }, + "linkFAQ": { + "message": "FAQ" + }, + "linkDonate": { + "message": "Doneer" + }, + "linkHelp": { + "message": "Help" + }, + "linkChangelog": { + "message": "Wijzigingslog" + }, + "legendSettings": { + "message": "Instellingen" + }, + "textSettings": { + "message": "Inzending voor leuk/niet leuk uitschakelen" + }, + "textLikesDisabled": { + "message": "Uitgeschakeld door eigenaar" + }, + "textSettingsHover": { + "message": "Stopt met het tellen van je leuks en niet leuks" + }, + "textRoundingNumbers": { + "message": "Statistieken voor leuk/niet leuk naar beneden afronden (standaard YouTube-gedrag)" + }, + "textRoundingNumbersHover": { + "message": "Afgeronde statistieken weergeven." + }, + "textConsistentFormat": { + "message": "Maak het formaat voor likes en dislikes consistent" + }, + "textConsistentFormatHover": { + "message": "Herformatteer als getallen." + }, + "textNumberFormat": { + "message": "Getalnotatie:" + }, + "textColorizeRatioBar": { + "message": "Verhoudingsbalk inkleuren" + }, + "textColorizeRatioBarHover": { + "message": "Gebruik aangepaste kleuren voor de verhoudingsbalk." + }, + "textColorizeThumbs": { + "message": "Duimpjes inkleuren" + }, + "textColorizeThumbsHover": { + "message": "Gebruik aangepaste kleuren voor duimpictogrammen." + }, + "textColorTheme": { + "message": "Kleurenthema:" + }, + "textColorTheme1": { + "message": "Klassiek" + }, + "textColorTheme2": { + "message": "Beschikbaar" + }, + "textColorTheme3": { + "message": "Neon" + }, + "textTempUnavailable": { + "message": "Tijdelijk niet beschikbaar" + }, + "textUpdate": { + "message": "Actualiseer naar" + }, + "version30installed": { + "message": "Versie 3.0.0.13 geïnstalleerd" + }, + "whatsnew": { + "message": "Wat is er nieuw" + }, + "shortsSupport": { + "message": "Ondersteuning voor YouTube Shorts" + }, + "customColors": { + "message": "Aangepaste kleuren voor afkeerbalk en knoppen" + }, + "customNumberFormats": { + "message": "Aangepaste getalnotaties" + }, + "considerDonating": { + "message": "Het enige dat de extensie draaiende houdt, zijn uw donaties. Overweeg alstublieft om het project te steunen." + }, + "roundNumbers": { + "message": "Afgeronde getallen weergeven" + }, + "roundNumbersHover": { + "message": "Rond getallen naar beneden af (standaard YouTube-gedrag)." + }, + "reformatLikes": { + "message": "Opnieuw formatteren zoals getallen" + }, + "reformatLikesHover": { + "message": "Maak het formaat voor leuk en niet leuk consistent." + }, + "numberFormat": { + "message": "Getalnotatie:" + }, + "colorizeRatio": { + "message": "Verhoudingsbalk inkleuren" + }, + "colorizeRatioHover": { + "message": "Gebruik aangepaste kleuren voor de verhoudingsbalk." + }, + "colorizeThumbs": { + "message": "Duimpjes inkleuren" + }, + "colorizeThumbsHover": { + "message": "Gebruik aangepaste kleuren voor de duimpictogrammen." + }, + "colorTheme": { + "message": "Kleurenthema:" + } +} diff --git a/Extensions/combined/_locales/pl/messages.json b/Extensions/combined/_locales/pl/messages.json new file mode 100644 index 00000000..67cee3bb --- /dev/null +++ b/Extensions/combined/_locales/pl/messages.json @@ -0,0 +1,134 @@ +{ + "extensionName": { + "message": "Return YouTube Dislike" + }, + "extensionNameBeta": { + "message": "Return YouTube Dislike Beta" + }, + "extensionDesc": { + "message": "Przywraca licznik łapek w dół" + }, + "textDeveloper": { + "message": "przez Dmitry Selivanov & Społeczność" + }, + "linkWebsite": { + "message": "Strona" + }, + "linkFAQ": { + "message": "FAQ" + }, + "linkDonate": { + "message": "Wesprzyj" + }, + "linkHelp": { + "message": "Pomoc" + }, + "linkChangelog": { + "message": "Zmiany" + }, + "legendSettings": { + "message": "Ustawienia" + }, + "textSettings": { + "message": "Wyłącz przesyłanie łapek" + }, + "textLikesDisabled": { + "message": "Wyłączone przez twórcę" + }, + "textSettingsHover": { + "message": "Przestaje liczyć Twoje łapki." + }, + "textRoundingNumbers": { + "message": "Zaokrąglaj łapki w górę/dół (domyślne zachowanie YouTube)" + }, + "textRoundingNumbersHover": { + "message": "Pokaż zaokrąglone w dół statystyki." + }, + "textConsistentFormat": { + "message": "Ujednolica format liczbowy łapek." + }, + "textConsistentFormatHover": { + "message": "Zmień formatowanie liczby łapek." + }, + "textNumberFormat": { + "message": "Format liczbowy:" + }, + "textColorizeRatioBar": { + "message": "Koloruj pasek ocen" + }, + "textColorizeRatioBarHover": { + "message": "Użyj własnych kolorów paska." + }, + "textColorizeThumbs": { + "message": "Koloruj łapki" + }, + "textColorizeThumbsHover": { + "message": "Użyj własnych kolorów łapek." + }, + "textColorTheme": { + "message": "Motyw kolorystyczny:" + }, + "textColorTheme1": { + "message": "Klasyczny" + }, + "textColorTheme2": { + "message": "Dostępny" + }, + "textColorTheme3": { + "message": "Neonowy" + }, + "textTempUnavailable": { + "message": "Tymczasowo niedostępny" + }, + "textUpdate": { + "message": "Zaktualizuj do" + }, + "version30installed": { + "message": "Zainstalowana wersja __RYD_VERSION__" + }, + "whatsnew": { + "message": "Co nowego" + }, + "shortsSupport": { + "message": "Wsparcie dla YouTube Shorts" + }, + "customColors": { + "message": "Własne kolory paska łapek i guzików" + }, + "customNumberFormats": { + "message": "Własne formaty liczbowe" + }, + "considerDonating": { + "message": "Jedyne co napędza ten projekt to wasze dotacje, prosimy o rozważenie wsparcia tego projektu." + }, + "roundNumbers": { + "message": "Pokaż zaokrąglone w dół liczby" + }, + "roundNumbersHover": { + "message": "Zaokrąglaj w dół liczby (domyślne zachowanie YouTube)." + }, + "reformatLikes": { + "message": "Zmień formatowanie liczby łapek." + }, + "reformatLikesHover": { + "message": "Ujednolica format liczbowy łapek." + }, + "numberFormat": { + "message": "Format liczbowy:" + }, + "colorizeRatio": { + "message": "Koloruj pasek ocen" + }, + "colorizeRatioHover": { + "message": "Użyj własnych kolorów paska." + }, + "colorizeThumbs": { + "message": "Koloruj łapki" + }, + "colorizeThumbsHover": { + "message": "Użyj własnych kolorów łapek." + }, + "colorTheme": { + "message": "Motyw kolorystyczny:" + } +} diff --git a/Extensions/combined/_locales/pt_BR/messages.json b/Extensions/combined/_locales/pt_BR/messages.json index fac12a21..03df46d3 100644 --- a/Extensions/combined/_locales/pt_BR/messages.json +++ b/Extensions/combined/_locales/pt_BR/messages.json @@ -6,10 +6,10 @@ "message": "Voltar Dislikes do YouTube Beta" }, "extensionDesc": { - "message": "Voltar os Deslikes do YouTube" + "message": "Retorna a capacidade de ver os não-gostados" }, "textDeveloper": { - "message": "por Dmitry Selivanov e Comunidade" + "message": "por Dmitry Selivanov & Comunidade" }, "linkWebsite": { "message": "Website" @@ -23,40 +23,112 @@ "linkHelp": { "message": "Ajuda" }, + "linkChangelog": { + "message": "O que mudou?" + }, "legendSettings": { "message": "Configurações" }, "textSettings": { - "message": "Desativar envio de Curtidas/Não Curtidas" + "message": "Desativar envios de Gostei/Não gostei" }, "textLikesDisabled": { "message": "Desativado pelo proprietário" }, "textSettingsHover": { - "message": "Parar de contar suas curtidas e não curtidas." + "message": "Pare de contar os gostei e Não gostei." + }, + "textRoundingNumbers": { + "message": "Arredondar estatísticas gostei/não gostei (comportamento padrão do YouTube)" + }, + "textRoundingNumbersHover": { + "message": "Mostrar números arredondados." + }, + "textConsistentFormat": { + "message": "Torna consistentes os Gostados e o formato não gostei" + }, + "textConsistentFormatHover": { + "message": "Reformatar números como." + }, + "textNumberFormat": { + "message": "Formato do número:" + }, + "textColorizeRatioBar": { + "message": "Colorir barra de proporção" + }, + "textColorizeRatioBarHover": { + "message": "Use cores personalizadas para os ícones miniaturas." + }, + "textColorizeThumbs": { + "message": "Colorir miniaturas" + }, + "textColorizeThumbsHover": { + "message": "Use cores personalizadas para os ícones miniaturas." + }, + "textColorTheme": { + "message": "Tema de cor:" + }, + "textColorTheme1": { + "message": "Clássico" + }, + "textColorTheme2": { + "message": "Acessível" + }, + "textColorTheme3": { + "message": "Neon" }, "textTempUnavailable": { - "message": "Temporariamente indisponível" + "message": "Temporariamente Indisponível" }, "textUpdate": { "message": "Atualizar para" }, "version30installed": { - "message": "Versão 3.0.0.1 instalada" + "message": "Versão __RYD_VERSION__ instalada" }, "whatsnew": { - "message": "O que há de novo?" + "message": "O que há de novo?:" }, "shortsSupport": { - "message": "Suporte para Shorts" + "message": "Suporte ao Shorts do YouTube" }, "customColors": { - "message": "Cores personalizadas para barra de não curtidas e botões" + "message": "Cores personalizadas para exibir barra de não curtidas e botões" }, "customNumberFormats": { - "message": "Formato de números personalizados" + "message": "Formatos de números personalizados" }, "considerDonating": { "message": "A única coisa que mantém a extensão funcionando são suas doações, considere apoiar o projeto." + }, + "roundNumbers": { + "message": "Mostrar números arredondados" + }, + "roundNumbersHover": { + "message": "Arredondar estatísticas gostei/não gostei (comportamento padrão do YouTube)." + }, + "reformatLikes": { + "message": "Reformatar números como" + }, + "reformatLikesHover": { + "message": "Torna consistentes os Gostados e o formato não gostei." + }, + "numberFormat": { + "message": "Formato do número:" + }, + "colorizeRatio": { + "message": "Colorir barra de proporção" + }, + "colorizeRatioHover": { + "message": "Use cores personalizadas para os ícones miniaturas." + }, + "colorizeThumbs": { + "message": "Colorir miniaturas" + }, + "colorizeThumbsHover": { + "message": "Use cores personalizadas para os ícones miniaturas." + }, + "colorTheme": { + "message": "Tema de cor:" } } diff --git a/Extensions/combined/_locales/ru/messages.json b/Extensions/combined/_locales/ru/messages.json index c275bf97..85c45113 100644 --- a/Extensions/combined/_locales/ru/messages.json +++ b/Extensions/combined/_locales/ru/messages.json @@ -36,7 +36,7 @@ "message": "обновление до" }, "version30installed": { - "message": "Версия 3.0.0.1 установлена" + "message": "Версия __RYD_VERSION__ установлена" }, "whatsnew": { "message": "Что нового" diff --git a/Extensions/combined/_locales/sv_SE/messages.json b/Extensions/combined/_locales/sv_SE/messages.json new file mode 100644 index 00000000..69ec0de8 --- /dev/null +++ b/Extensions/combined/_locales/sv_SE/messages.json @@ -0,0 +1,134 @@ +{ + "extensionName": { + "message": "Return YouTube Dislike" + }, + "extensionNameBeta": { + "message": "Return YouTube Dislike Beta" + }, + "extensionDesc": { + "message": "Återställer förmågan att se ogilla" + }, + "textDeveloper": { + "message": "av Dmitry Selivanov & Community" + }, + "linkWebsite": { + "message": "Hemsida" + }, + "linkFAQ": { + "message": "FAQ" + }, + "linkDonate": { + "message": "Donera" + }, + "linkHelp": { + "message": "Hjälp" + }, + "linkChangelog": { + "message": "Ändringslogg" + }, + "legendSettings": { + "message": "Inställningar" + }, + "textSettings": { + "message": "Inaktivera gilla-/ogilla-inskickningar" + }, + "textLikesDisabled": { + "message": "Inaktiverad av ägaren" + }, + "textSettingsHover": { + "message": "Slutar räkna dina gilla och ogilla." + }, + "textRoundingNumbers": { + "message": "Avrunda statistiken neråt för gilla/ogilla (standard YouTube-beteende)" + }, + "textRoundingNumbersHover": { + "message": "Visa avrundad statistik." + }, + "textConsistentFormat": { + "message": "Gör formatet på gilla och ogilla konsekvent" + }, + "textConsistentFormatHover": { + "message": "Omformatera som siffror." + }, + "textNumberFormat": { + "message": "Sifforformat:" + }, + "textColorizeRatioBar": { + "message": "Färgsätt förhållandefältet" + }, + "textColorizeRatioBarHover": { + "message": "Använd anpassade färger för förhållandefältet." + }, + "textColorizeThumbs": { + "message": "Färglägg tummarna" + }, + "textColorizeThumbsHover": { + "message": "Använd anpassade färger för tumikoner." + }, + "textColorTheme": { + "message": "Färgtema:" + }, + "textColorTheme1": { + "message": "Klassisk" + }, + "textColorTheme2": { + "message": "Tillgänglig" + }, + "textColorTheme3": { + "message": "Neon" + }, + "textTempUnavailable": { + "message": "Tillfälligt otillgänglig" + }, + "textUpdate": { + "message": "Uppdatera till" + }, + "version30installed": { + "message": "Version __RYD_VERSION__ installerad" + }, + "whatsnew": { + "message": "Vad är nytt" + }, + "shortsSupport": { + "message": "YouTube Shorts Support" + }, + "customColors": { + "message": "Anpassade färger för knappar och fältet ogilla" + }, + "customNumberFormats": { + "message": "Anpassade sifforformat" + }, + "considerDonating": { + "message": "Det enda som håller tillägget i gång är dina donationer, överväg att stöda projektet." + }, + "roundNumbers": { + "message": "Visa avrundade siffror" + }, + "roundNumbersHover": { + "message": "Avrunda siffrorna neråt (standard YouTube-beteende)." + }, + "reformatLikes": { + "message": "Omformatera som siffror" + }, + "reformatLikesHover": { + "message": "Gör formatet på gilla och ogilla konsekvent." + }, + "numberFormat": { + "message": "Sifforformat:" + }, + "colorizeRatio": { + "message": "Färgsätt förhållandefältet" + }, + "colorizeRatioHover": { + "message": "Använd anpassade färger för förhållandefältet." + }, + "colorizeThumbs": { + "message": "Färglägg tummarna" + }, + "colorizeThumbsHover": { + "message": "Använd anpassade färger för tumikoner." + }, + "colorTheme": { + "message": "Färgtema:" + } +} diff --git a/Extensions/combined/_locales/tr/messages.json b/Extensions/combined/_locales/tr/messages.json index d2b2f899..c5e0a698 100644 --- a/Extensions/combined/_locales/tr/messages.json +++ b/Extensions/combined/_locales/tr/messages.json @@ -23,6 +23,9 @@ "linkHelp": { "message": "Yardım" }, + "linkChangelog": { + "message": "Değişim Günlüğü" + }, "legendSettings": { "message": "Ayarlar" }, @@ -30,19 +33,58 @@ "message": "Like/dislike gönderimini devre dışı bırak" }, "textLikesDisabled": { - "message": "sahibi tarafından devre dışı bırakıldı" + "message": "Sahibi tarafından devre dışı bırakıldı" }, "textSettingsHover": { - "message": "Like'larınızı ve dislike'larınızı saymayı bırakır." + "message": "Like ve dislike'larınızı saymayı bırakır." + }, + "textRoundingNumbers": { + "message": "Like/dislike istatisliklerini aşağıya yuvarlar (varsayılan YouTube davranışı)" + }, + "textRoundingNumbersHover": { + "message": "Yuvarlatılmış istatistikleri göster." + }, + "textConsistentFormat": { + "message": "Like ve dislike tarzını tutarlı hâle getirir" + }, + "textConsistentFormatHover": { + "message": "Like sayılarının tarzını yenileştir." + }, + "textNumberFormat": { + "message": "Sayı tarzı:" + }, + "textColorizeRatioBar": { + "message": "Beğeni oranı çubuğunu renklendir" + }, + "textColorizeRatioBarHover": { + "message": "Oran çubuğu için özel renkler kullanın." + }, + "textColorizeThumbs": { + "message": "Butonları renklendir" + }, + "textColorizeThumbsHover": { + "message": "Buton simgeleri için özel renkler kullanın." + }, + "textColorTheme": { + "message": "Renk teması:" + }, + "textColorTheme1": { + "message": "Klasik" + }, + "textColorTheme2": { + "message": "Anlaşılır" + }, + "textColorTheme3": { + "message": "Neon" }, "textTempUnavailable": { - "message": "geçici olarak kullanım dışı" + "message": "Geçici Olarak Kullanım Dışı" }, "textUpdate": { - "message": "şu sürüme güncelle" + "message": "Şu sürüme güncelle" }, "version30installed": { - "message": "Sürüm 3.0.0.1 yüklendi" + "message": "Sürüm __RYD_VERSION__ yüklendi" }, "whatsnew": { "message": "Yeni Ne Var" @@ -58,5 +100,35 @@ }, "considerDonating": { "message": "Uzantının var olmasını sağlayan tek şey bağışlarınızdır, lütfen projeyi desteklemeyi düşünün." + }, + "roundNumbers": { + "message": "Aşağı yuvarlanmış sayıları gösterir" + }, + "roundNumbersHover": { + "message": "Sayıları aşağıya yuvarla (varsayılan YouTube davranışı)." + }, + "reformatLikes": { + "message": "Like sayılarının tarzını yenileştir" + }, + "reformatLikesHover": { + "message": "Like ve dislike tarzını tutarlı hâle getirir." + }, + "numberFormat": { + "message": "Sayı tarzı:" + }, + "colorizeRatio": { + "message": "Beğeni oranı çubuğunu renklendir" + }, + "colorizeRatioHover": { + "message": "Beğeni oranı çubuğu için özel renkler kullanın." + }, + "colorizeThumbs": { + "message": "Butonları renklendir" + }, + "colorizeThumbsHover": { + "message": "Buton simgeleri için özel renkler kullan." + }, + "colorTheme": { + "message": "Renk teması:" } } diff --git a/Extensions/combined/_locales/uk/messages.json b/Extensions/combined/_locales/uk/messages.json new file mode 100644 index 00000000..b723cee3 --- /dev/null +++ b/Extensions/combined/_locales/uk/messages.json @@ -0,0 +1,134 @@ +{ + "extensionName": { + "message": "Return YouTube Dislike" + }, + "extensionNameBeta": { + "message": "Return YouTube Dislike Beta" + }, + "extensionDesc": { + "message": "Повертає здатність бачити відмітки «Не подобається»" + }, + "textDeveloper": { + "message": "від Дмитра Селіванова та спільноти" + }, + "linkWebsite": { + "message": "Вебсайт" + }, + "linkFAQ": { + "message": "ЧаПи" + }, + "linkDonate": { + "message": "Підтримати" + }, + "linkHelp": { + "message": "Допомога" + }, + "linkChangelog": { + "message": "Журнал змін" + }, + "legendSettings": { + "message": "Налаштування" + }, + "textSettings": { + "message": "Вимкнути надсилання відміток" + }, + "textLikesDisabled": { + "message": "Вимкнуто власником" + }, + "textSettingsHover": { + "message": "Вимикає надсилання відміток «Подобається» та «Не подобається»." + }, + "textRoundingNumbers": { + "message": "Округлює значення відміток (стандартний параметр YouTube)" + }, + "textRoundingNumbersHover": { + "message": "Показувати заокруглені значення." + }, + "textConsistentFormat": { + "message": "Зробить формат «Подобається» та «Не подобається» однаковим" + }, + "textConsistentFormatHover": { + "message": "Форматувати як числа." + }, + "textNumberFormat": { + "message": "Формат значень:" + }, + "textColorizeRatioBar": { + "message": "Обрати кольори стрічки співвідношення" + }, + "textColorizeRatioBarHover": { + "message": "Змінює кольори стрічки співвідношення на обрані вами." + }, + "textColorizeThumbs": { + "message": "Обрати кольори відміток" + }, + "textColorizeThumbsHover": { + "message": "Змінює кольори піктограм відміток на обрані вами." + }, + "textColorTheme": { + "message": "Кольорова схема:" + }, + "textColorTheme1": { + "message": "Класика" + }, + "textColorTheme2": { + "message": "Доступність" + }, + "textColorTheme3": { + "message": "Неон" + }, + "textTempUnavailable": { + "message": "Тимчасово недоступно" + }, + "textUpdate": { + "message": "Оновлення до" + }, + "version30installed": { + "message": "Версію __RYD_VERSION__ встановлено" + }, + "whatsnew": { + "message": "Що нового" + }, + "shortsSupport": { + "message": "Підтримка YouTube Shorts" + }, + "customColors": { + "message": "Користувальницькі кольори стрічки співвідношення та кнопок" + }, + "customNumberFormats": { + "message": "Користувацькі формати значень" + }, + "considerDonating": { + "message": "Розширення досі існує лише за допомогою ваших пожертв, будь ласка, підтримайте проєкт." + }, + "roundNumbers": { + "message": "Показувати заокруглені значення" + }, + "roundNumbersHover": { + "message": "Округлює значення відміток (стандартний параметр YouTube)" + }, + "reformatLikes": { + "message": "Форматувати як числа" + }, + "reformatLikesHover": { + "message": "Зробить формат «Подобається» та «Не подобається» однаковим" + }, + "numberFormat": { + "message": "Формат значень:" + }, + "colorizeRatio": { + "message": "Обрати кольори стрічки співвідношення" + }, + "colorizeRatioHover": { + "message": "Змінює кольори стрічки співвідношення на обрані вами." + }, + "colorizeThumbs": { + "message": "Обрати кольори відміток" + }, + "colorizeThumbsHover": { + "message": "Змінює кольори піктограм відміток на обрані вами." + }, + "colorTheme": { + "message": "Кольорова схема:" + } +} diff --git a/Extensions/combined/changelog/3/changelog_3.0.html b/Extensions/combined/changelog/3/changelog_3.0.html index 4ffe4bcf..f127845b 100644 --- a/Extensions/combined/changelog/3/changelog_3.0.html +++ b/Extensions/combined/changelog/3/changelog_3.0.html @@ -1,4 +1,4 @@ - + diff --git a/Extensions/combined/changelog/changelog.js b/Extensions/combined/changelog/changelog.js index 8c9e332a..fbef6c94 100644 --- a/Extensions/combined/changelog/changelog.js +++ b/Extensions/combined/changelog/changelog.js @@ -6,7 +6,6 @@ const config = { coloredBar: false, colorTheme: "classic", numberDisplayFormat: "compactShort", - numberDisplayRoundDown: true, showAdvancedMessage: '', hideAdvancedMessage: diff --git a/Extensions/combined/content-style.css b/Extensions/combined/content-style.css index d8da7db1..8444b583 100644 --- a/Extensions/combined/content-style.css +++ b/Extensions/combined/content-style.css @@ -30,12 +30,20 @@ } .ryd-tooltip { - position: relative; display: block; height: 2px; +} + +.ryd-tooltip-old-design { + position: relative; top: 9px; } +.ryd-tooltip-new-design { + position: absolute; + bottom: -10px; +} + .ryd-tooltip-bar-container { width: 100%; height: 2px; @@ -44,3 +52,12 @@ padding-bottom: 12px; top: -6px; } + +/* required to make the ratio bar visible in the new design */ +ytd-menu-renderer.ytd-watch-metadata { + overflow-y: visible !important; +} + +#top-level-buttons-computed { + position: relative !important; +} diff --git a/Extensions/combined/icons/logo.svg b/Extensions/combined/icons/logo.svg new file mode 100644 index 00000000..092f65a4 --- /dev/null +++ b/Extensions/combined/icons/logo.svg @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/Extensions/combined/manifest-chrome.json b/Extensions/combined/manifest-chrome.json index d881a756..3513a43d 100644 --- a/Extensions/combined/manifest-chrome.json +++ b/Extensions/combined/manifest-chrome.json @@ -2,7 +2,7 @@ "name": "__MSG_extensionName__", "description": "__MSG_extensionDesc__", "default_locale": "en", - "version": "3.0.0.1", + "version": "__RYD_VERSION__", "manifest_version": 3, "background": { "service_worker": "ryd.background.js" @@ -36,5 +36,9 @@ "resources": ["ryd.script.js"], "matches": ["*://*.youtube.com/*"] } - ] + ], + "options_ui": { + "page": "popup.html", + "open_in_tab": false + } } diff --git a/Extensions/combined/manifest-firefox.json b/Extensions/combined/manifest-firefox.json index 82fd897a..a1fb0e33 100644 --- a/Extensions/combined/manifest-firefox.json +++ b/Extensions/combined/manifest-firefox.json @@ -2,7 +2,7 @@ "name": "__MSG_extensionName__", "description": "__MSG_extensionDesc__", "default_locale": "en", - "version": "3.0.0.0", + "version": "__RYD_VERSION__", "manifest_version": 2, "background": { "scripts": ["ryd.background.js"] @@ -28,12 +28,16 @@ "css": ["content-style.css"], "js": ["ryd.content-script.js"] } - ] - // , - // "browser_specific_settings": { - // "gecko": { - // "id": "addon@example.com", - // "strict_min_version": "42.0" + ], + "options_ui": { + "page": "popup.html", + "open_in_tab": false + } + // uncomment this section for local storage to work in firefox locally + // ,"browser_specific_settings": { + // "gecko": { + // "id": "addon@example.com", + // "strict_min_version": "42.0" + // } // } - // } } diff --git a/Extensions/combined/manifest-safari.json b/Extensions/combined/manifest-safari.json new file mode 100644 index 00000000..0c7f8e34 --- /dev/null +++ b/Extensions/combined/manifest-safari.json @@ -0,0 +1,36 @@ +{ + "name": "__MSG_extensionName__", + "description": "__MSG_extensionDesc__", + "default_locale": "en", + "version": "__RYD_VERSION__", + "manifest_version": 2, + "background": { + "scripts": ["ryd.background.js"], + "persistent": false + }, + "icons": { + "48": "icons/icon48.png", + "128": "icons/icon128.png" + }, + "permissions": [ + "activeTab", + "*://*.youtube.com/*", + "storage", + "*://returnyoutubedislikeapi.com/*" + ], + "browser_action": { + "default_popup": "popup.html" + }, + "content_scripts": [ + { + "matches": ["*://*.youtube.com/*"], + "exclude_matches": ["*://*.music.youtube.com/*"], + "run_at": "document_idle", + "css": ["content-style.css"], + "js": ["ryd.content-script.js"] + } + ], + "options_ui": { + "page": "popup.html" + } +} diff --git a/Extensions/combined/popup.css b/Extensions/combined/popup.css index a5cdb7b9..57b8e268 100644 --- a/Extensions/combined/popup.css +++ b/Extensions/combined/popup.css @@ -1,20 +1,49 @@ /* Variables */ :root { - --primary: #cc2929; - --accent: #581111; + --primary: #f39090; + --secondary: #502e2e; + --tertiary: #221818; + --background: #352929; - --background: #111; - --secondary: #272727; - --tertiary: #424242; + --accent: #581111; --lightGrey: #999; - --white: #fff; } +/*** MATERIAL 3 ***/ +.m3-primary { + background: var(--primary) !important; + color: var(--background) !important; +} +.m3-btn { + background: var(--tertiary); + color: var(--primary); + transition: 0.4s; + border-radius: 4px; + font-weight: 500; + border-radius: 100em; + box-shadow: 0 5px 5px rgba(0,0,0,0.1); + margin: 0.25em; +} +.m3-btn:hover { + background: var(--secondary) !important; + color: var(--primary) !important; +} + +select { + border-radius: 1em; + background-color: var(--secondary); + color: var(--primary); + border: none; + outline: none; + padding: 3px 2px; +} +/*** END MATERIAL 3 ***/ + /* Window Styling */ html, body { background-color: var(--background); - color: var(--white); + color: var(--primary); min-width: 310px; min-height: 350px; padding: 0.5em; @@ -26,30 +55,19 @@ h1 { font-size: 26px; } +#ext-version { + padding: 0.25rem 0.5rem; +} + button { - color: var(--white); - background: var(--secondary); cursor: pointer; padding: 5px 16px; border: none; - border-radius: 4px; - font-weight: 500; - /* box-shadow: 0 2px 4px -1px rgb(0 0 0 / 20%), 0 4px 5px 0 rgb(0 0 0 / 14%), - 0 1px 10px 0 rgb(0 0 0 / 12%); */ - transition: 0.4s; -} - -button:hover { - background: #444; -} - -#ext-version { - padding: 0.25rem 0.5rem; } #ext-update { cursor: pointer; - color: var(--white); + color: var(--primary); text-decoration: none; background: var(--primary); border-radius: 0.25rem; @@ -74,7 +92,9 @@ button:hover { content: attr(data-hover); visibility: hidden; opacity: 0; - transition: visibility 0.1s linear, opacity 0.1s linear; + transition: + visibility 0.1s linear, + opacity 0.1s linear; width: 250px; background-color: var(--secondary); border-radius: 0.5rem; @@ -113,17 +133,17 @@ button:hover { position: fixed; background: none; box-shadow: none; - color: var(--lightGrey); + color: var(--primary); top: 26px; right: 26px; padding: 2px; z-index: 69; height: 2rem; width: 2rem; + transition-duration: .25s; } #advancedToggle:hover { - color: var(--white); transform: rotate(-90deg); } @@ -143,11 +163,10 @@ button:hover { right: 14px; width: calc(100% - 65px); height: calc(100% - 58px); - border: 2px solid var(--secondary); - border-radius: 0.5rem; padding: 1rem; overflow-y: auto; overflow-x: hidden; + border: none; } ::-webkit-scrollbar { @@ -159,7 +178,7 @@ button:hover { } ::-webkit-scrollbar-thumb { - background-color: #333; /* color of the scroll thumb */ + background-color: var(--primary); /* color of the scroll thumb */ border-radius: 1rem 0 0 1rem; /* roundness of the scroll thumb */ border-bottom: 0.25rem solid #111; /* creates padding around scroll thumb */ border-left: 0.25rem solid #111; /* creates padding around scroll thumb */ @@ -175,7 +194,7 @@ button:hover { } #advancedLegend { - color: var(--tertiary) !important; + color: var(--secondary) !important; /* margin: auto; */ /* Center the label */ /* padding: .25rem .5rem; */ /* border-radius: .25rem; */ @@ -226,7 +245,7 @@ button:hover { width: 13px; left: 2px; bottom: 2px; - background: var(--lightGrey); + background: var(--primary); transition: 0.4s; border-radius: 50%; } diff --git a/Extensions/combined/popup.html b/Extensions/combined/popup.html index aa2e5085..450c10f5 100644 --- a/Extensions/combined/popup.html +++ b/Extensions/combined/popup.html @@ -1,5 +1,7 @@ - + + + __MSG_extensionName__ @@ -11,15 +13,10 @@ rel="stylesheet" /> +
- - - - +

__MSG_extensionName__

@@ -27,27 +24,29 @@

__MSG_textDeveloper__

- - +
- - - +
-
- - __MSG_legendSettings__ - - -
-

data-hover="Display percentage in like/dislike bar tooltip." > - + Percentage in like/dislike bar tooltip.
diff --git a/Extensions/combined/popup.js b/Extensions/combined/popup.js index cf72829d..2fd52975 100644 --- a/Extensions/combined/popup.js +++ b/Extensions/combined/popup.js @@ -4,11 +4,11 @@ import { cLog } from "./src/utils"; const config = { advanced: false, disableVoteSubmission: false, + disableLogging: true, coloredThumbs: false, coloredBar: false, colorTheme: "classic", numberDisplayFormat: "compactShort", - numberDisplayRoundDown: true, showTooltipPercentage: false, tooltipPercentageMode: "dash_like", numberDisplayReformatLikes: false, @@ -16,7 +16,6 @@ const config = { '', hideAdvancedMessage: '', - links: { website: "https://returnyoutubedislike.com", github: "https://github.com/Anarios/return-youtube-dislike", @@ -69,6 +68,10 @@ document chrome.storage.sync.set({ disableVoteSubmission: ev.target.checked }); }); +document.getElementById("disable_logging").addEventListener("click", (ev) => { + chrome.storage.sync.set({ disableLogging:ev.target.checked }) +}); + document.getElementById("colored_thumbs").addEventListener("click", (ev) => { chrome.storage.sync.set({ coloredThumbs: ev.target.checked }); }); @@ -81,11 +84,6 @@ document.getElementById("color_theme").addEventListener("click", (ev) => { chrome.storage.sync.set({ colorTheme: ev.target.value }); }); -document.getElementById("number_round_down").addEventListener("click", (ev) => { - chrome.storage.sync.set({ numberDisplayRoundDown: ev.target.checked }); - updateNumberDisplayFormatContent(ev.target.checked); -}); - document.getElementById("number_format").addEventListener("change", (ev) => { chrome.storage.sync.set({ numberDisplayFormat: ev.target.value }); }); @@ -130,12 +128,12 @@ initConfig(); function initConfig() { initializeDisableVoteSubmission(); + initializeDisableLogging(); initializeVersionNumber(); initializeColoredThumbs(); initializeColoredBar(); initializeColorTheme(); initializeNumberDisplayFormat(); - initializeNumberDisplayRoundDown(); initializeTooltipPercentage(); initializeTooltipPercentageMode(); initializeNumberDisplayReformatLikes(); @@ -146,7 +144,7 @@ function initializeVersionNumber() { document.getElementById("ext-version").innerHTML = "v" + version; fetch( - "https://raw.githubusercontent.com/Anarios/return-youtube-dislike/main/Extensions/combined/manifest-chrome.json" + "https://raw.githubusercontent.com/Anarios/return-youtube-dislike/main/Extensions/combined/manifest-chrome.json", ) .then((response) => response.json()) .then((json) => { @@ -185,6 +183,12 @@ function initializeDisableVoteSubmission() { }); } +function initializeDisableLogging(){ + chrome.storage.sync.get(['disableLogging'], (res) => { + handleDisableLoggingChangeEvent(res.disableLogging); + }); +} + function initializeColoredThumbs() { chrome.storage.sync.get(["coloredThumbs"], (res) => { handleColoredThumbsChangeEvent(res.coloredThumbs); @@ -203,12 +207,6 @@ function initializeColorTheme() { }); } -function initializeNumberDisplayRoundDown() { - chrome.storage.sync.get(["numberDisplayRoundDown"], (res) => { - handleNumberDisplayRoundDownChangeEvent(res.numberDisplayRoundDown); - }); -} - function initializeTooltipPercentage() { chrome.storage.sync.get(["showTooltipPercentage"], (res) => { handleShowTooltipPercentageChangeEvent(res.showTooltipPercentage); @@ -228,13 +226,8 @@ function initializeNumberDisplayFormat() { updateNumberDisplayFormatContent(); } -function updateNumberDisplayFormatContent(roundDown) { - let testValue; - if (roundDown) { - testValue = 123000; - } else { - testValue = 123456; - } +function updateNumberDisplayFormatContent() { + let testValue = 123456; document.getElementById("number_format_compactShort").innerHTML = getNumberFormatter("compactShort").format(testValue); document.getElementById("number_format_compactLong").innerHTML = @@ -254,9 +247,12 @@ chrome.storage.onChanged.addListener(storageChangeHandler); function storageChangeHandler(changes, area) { if (changes.disableVoteSubmission !== undefined) { handleDisableVoteSubmissionChangeEvent( - changes.disableVoteSubmission.newValue + changes.disableVoteSubmission.newValue, ); } + if (changes.disableLogging !== undefined) { + handleDisableLoggingChangeEvent(changes.disableLogging.newValue); + } if (changes.coloredThumbs !== undefined) { handleColoredThumbsChangeEvent(changes.coloredThumbs.newValue); } @@ -266,22 +262,17 @@ function storageChangeHandler(changes, area) { if (changes.colorTheme !== undefined) { handleColorThemeChangeEvent(changes.colorTheme.newValue); } - if (changes.numberDisplayRoundDown !== undefined) { - handleNumberDisplayRoundDownChangeEvent( - changes.numberDisplayRoundDown.newValue - ); - } if (changes.numberDisplayFormat !== undefined) { handleNumberDisplayFormatChangeEvent(changes.numberDisplayFormat.newValue); } if (changes.showTooltipPercentage !== undefined) { handleShowTooltipPercentageChangeEvent( - changes.showTooltipPercentage.newValue + changes.showTooltipPercentage.newValue, ); } if (changes.numberDisplayReformatLikes !== undefined) { handleNumberDisplayReformatLikesChangeEvent( - changes.numberDisplayReformatLikes.newValue + changes.numberDisplayReformatLikes.newValue, ); } } @@ -291,6 +282,11 @@ function handleDisableVoteSubmissionChangeEvent(value) { document.getElementById("disable_vote_submission").checked = value; } +function handleDisableLoggingChangeEvent(value) { + config.disableLogging = value; + document.getElementById("disable_logging").checked = value; +} + function handleColoredThumbsChangeEvent(value) { config.coloredThumbs = value; document.getElementById("colored_thumbs").checked = value; @@ -319,11 +315,6 @@ function updateColorThemePreviewContent(themeName) { getColorFromTheme(themeName, false); } -function handleNumberDisplayRoundDownChangeEvent(value) { - config.numberDisplayRoundDown = value; - document.getElementById("number_round_down").checked = value; -} - function handleNumberDisplayFormatChangeEvent(value) { config.numberDisplayFormat = value; document @@ -360,7 +351,7 @@ function getNumberFormatter(optionSelect) { userLocales = new URL( Array.from(document.querySelectorAll("head > link[rel='search']")) ?.find((n) => n?.getAttribute("href")?.includes("?locale=")) - ?.getAttribute("href") + ?.getAttribute("href"), )?.searchParams?.get("locale"); } catch {} @@ -383,7 +374,7 @@ function getNumberFormatter(optionSelect) { { notation: formatterNotation, compactDisplay: formatterCompactDisplay, - } + }, ); return formatter; } @@ -392,7 +383,7 @@ function getNumberFormatter(optionSelect) { let status = document.getElementById("status"); let serverStatus = document.getElementById("server-status"); let resp = await fetch( - "https://returnyoutubedislikeapi.com/votes?videoId=YbJOTdZBX1g" + "https://returnyoutubedislikeapi.com/votes?videoId=YbJOTdZBX1g", ); let result = await resp.status; if (result === 200) { diff --git a/Extensions/combined/readme.md b/Extensions/combined/readme.md index 0818eb31..faee2306 100644 --- a/Extensions/combined/readme.md +++ b/Extensions/combined/readme.md @@ -6,7 +6,7 @@
  1. Go to the root directory of the project
  2. -
  3. Run npm i to install all project dependancies (if not done so already)
  4. +
  5. Run npm i to install all project dependencies (if not done so already)
  6. run npm run dev to compile the extension to the ~/Extensions/combined/dist/ folder.
diff --git a/Extensions/combined/ryd.background.js b/Extensions/combined/ryd.background.js index c416da94..07752305 100644 --- a/Extensions/combined/ryd.background.js +++ b/Extensions/combined/ryd.background.js @@ -6,11 +6,11 @@ let api; /** stores extension's global config */ let extConfig = { disableVoteSubmission: false, + disableLogging: true, coloredThumbs: false, coloredBar: false, colorTheme: "classic", // classic, accessible, neon numberDisplayFormat: "compactShort", // compactShort, compactLong, standard - numberDisplayRoundDown: true, // locale 'de' shows exact numbers by default numberDisplayReformatLikes: false, // use existing (native) likes number }; @@ -41,7 +41,7 @@ api.runtime.onMessage.addListener((request, sender, sendResponse) => { headers: { Accept: "application/json", }, - } + }, ) .then((response) => response.json()) .then((response) => { @@ -81,11 +81,13 @@ api.runtime.onInstalled.addListener((details) => { details.reason === "chrome_update" || // No need to show changelog if developer just reloaded the extension details.reason === "update" - ) + ) { return; - api.tabs.create({ - url: api.runtime.getURL("/changelog/3/changelog_3.0.html"), - }); + } else if (details.reason == "install") { + api.tabs.create({ + url: api.runtime.getURL("/changelog/3/changelog_3.0.html"), + }); + } }); // api.storage.sync.get(['lastShowChangelogVersion'], (details) => { @@ -152,7 +154,7 @@ async function register() { headers: { Accept: "application/json", }, - } + }, ).then((response) => response.json()); const solvedPuzzle = await solvePuzzle(registrationResponse); if (!solvedPuzzle.solution) { @@ -209,7 +211,7 @@ function countLeadingZeroes(uInt8View, limit) { async function solvePuzzle(puzzle) { let challenge = Uint8Array.from(atob(puzzle.challenge), (c) => - c.charCodeAt(0) + c.charCodeAt(0), ); let buffer = new ArrayBuffer(20); let uInt8View = new Uint8Array(buffer); @@ -254,7 +256,7 @@ function generateUserID(length = 36) { function storageChangeHandler(changes, area) { if (changes.disableVoteSubmission !== undefined) { handleDisableVoteSubmissionChangeEvent( - changes.disableVoteSubmission.newValue + changes.disableVoteSubmission.newValue, ); } if (changes.coloredThumbs !== undefined) { @@ -266,27 +268,24 @@ function storageChangeHandler(changes, area) { if (changes.colorTheme !== undefined) { handleColorThemeChangeEvent(changes.colorTheme.newValue); } - if (changes.numberDisplayRoundDown !== undefined) { - handleNumberDisplayRoundDownChangeEvent( - changes.numberDisplayRoundDown.newValue - ); - } if (changes.numberDisplayFormat !== undefined) { handleNumberDisplayFormatChangeEvent(changes.numberDisplayFormat.newValue); } if (changes.numberDisplayReformatLikes !== undefined) { handleNumberDisplayReformatLikesChangeEvent( - changes.numberDisplayReformatLikes.newValue + changes.numberDisplayReformatLikes.newValue, ); } + if (changes.disableLogging !== undefined) { + handleDisableLoggingChangeEvent(changes.disableLogging.newValue); if (changes.showTooltipPercentage !== undefined) { handleShowTooltipPercentageChangeEvent( - changes.showTooltipPercentage.newValue + changes.showTooltipPercentage.newValue, ); } if (changes.numberDisplayReformatLikes !== undefined) { handleNumberDisplayReformatLikesChangeEvent( - changes.numberDisplayReformatLikes.newValue + changes.numberDisplayReformatLikes.newValue, ); } } @@ -300,6 +299,9 @@ function handleDisableVoteSubmissionChangeEvent(value) { } } +function handleDisableLoggingChangeEvent(value) { + extConfig.disableLogging = value; +} function handleNumberDisplayFormatChangeEvent(value) { extConfig.numberDisplayFormat = value; } @@ -315,10 +317,6 @@ function handleTooltipPercentageModeChangeEvent(value) { extConfig.tooltipPercentageMode = value; } -function handleNumberDisplayRoundDownChangeEvent(value) { - extConfig.numberDisplayRoundDown = value; -} - function changeIcon(iconName) { if (api.action !== undefined) api.action.setIcon({ path: "/icons/" + iconName }); @@ -350,11 +348,11 @@ api.storage.onChanged.addListener(storageChangeHandler); function initExtConfig() { initializeDisableVoteSubmission(); + initializeDisableLogging(); initializeColoredThumbs(); initializeColoredBar(); initializeColorTheme(); initializeNumberDisplayFormat(); - initializeNumberDisplayRoundDown(); initializeNumberDisplayReformatLikes(); initializeTooltipPercentage(); initializeTooltipPercentageMode(); @@ -371,6 +369,16 @@ function initializeDisableVoteSubmission() { }); } +function initializeDisableLogging(){ + api.storage.sync.get(['disableLogging'],(res)=>{ + if (res.disableLogging === undefined) { + api.storage.sync.set({disableLogging:true}); + } + else { + extConfig.disableLogging = res.disableLogging; + } + }); +} function initializeColoredThumbs() { api.storage.sync.get(["coloredThumbs"], (res) => { if (res.coloredThumbs === undefined) { @@ -381,16 +389,6 @@ function initializeColoredThumbs() { }); } -function initializeNumberDisplayRoundDown() { - api.storage.sync.get(["numberDisplayRoundDown"], (res) => { - if (res.numberDisplayRoundDown === undefined) { - api.storage.sync.set({ numberDisplayRoundDown: true }); - } else { - extConfig.numberDisplayRoundDown = res.numberDisplayRoundDown; - } - }); -} - function initializeColoredBar() { api.storage.sync.get(["coloredBar"], (res) => { if (res.coloredBar === undefined) { diff --git a/Extensions/combined/ryd.content-script.js b/Extensions/combined/ryd.content-script.js index 3fc39417..58303833 100644 --- a/Extensions/combined/ryd.content-script.js +++ b/Extensions/combined/ryd.content-script.js @@ -1,70 +1,49 @@ //--- Import Button Functions ---// -import { - getButtons, - getLikeButton, - getDislikeButton, - checkForSignInButton, -} from "./src/buttons"; +import { getButtons } from "./src/buttons"; //--- Import State Functions ---// -import { - isMobile, - isShorts, - isVideoDisliked, - isVideoLiked, - getState, - setState, - setInitialState, - setLikes, - setDislikes, - getLikeCountFromButton, - LIKED_STATE, - DISLIKED_STATE, - NEUTRAL_STATE, - initExtConfig, - initMutationObserver, -} from "./src/state"; +import { isShorts, setInitialState, initExtConfig } from "./src/state"; //--- Import Video & Browser Functions ---// +import { getBrowser, isVideoLoaded, cLog } from "./src/utils"; import { - numberFormat, - getBrowser, - getVideoId, - isVideoLoaded, - cLog, -} from "./src/utils"; -import { createRateBar } from "./src/bar"; -import { - sendVote, - likeClicked, - dislikeClicked, addLikeDislikeEventListener, + createSmartimationObserver, storageChangeHandler, } from "./src/events"; -initMutationObserver(); -initExtConfig(); +await initExtConfig(); let jsInitChecktimer = null; - -function setEventListeners(evt) { - function checkForJS_Finish() { - if (isShorts() || (getButtons()?.offsetParent && isVideoLoaded())) { - addLikeDislikeEventListener(); - setInitialState(); - getBrowser().storage.onChanged.addListener(storageChangeHandler); - clearInterval(jsInitChecktimer); - jsInitChecktimer = null; +let isSetInitialStateDone = false; + +async function setEventListeners(evt) { + async function checkForJS_Finish() { + try { + if (isShorts() || (getButtons()?.offsetParent && isVideoLoaded())) { + clearInterval(jsInitChecktimer); + jsInitChecktimer = null; + createSmartimationObserver(); + addLikeDislikeEventListener(); + await setInitialState(); + isSetInitialStateDone = true; + getBrowser().storage.onChanged.addListener(storageChangeHandler); + } + } catch (exception) { + if (!isSetInitialStateDone) { + cLog("error"); + await setInitialState(); + } } } - jsInitChecktimer = setInterval(checkForJS_Finish, 111); + if (jsInitChecktimer !== null) clearInterval(jsInitChecktimer); + jsInitChecktimer = setInterval(await checkForJS_Finish, 111); } -setEventListeners(); +await setEventListeners(); -document.addEventListener("yt-navigate-finish", function (event) { +document.addEventListener("yt-navigate-finish", async function (event) { if (jsInitChecktimer !== null) clearInterval(jsInitChecktimer); - window.returnDislikeButtonlistenersSet = false; - setEventListeners(); + await setEventListeners(); }); diff --git a/Extensions/combined/src/bar.js b/Extensions/combined/src/bar.js index 55f21ed7..80f20aba 100644 --- a/Extensions/combined/src/bar.js +++ b/Extensions/combined/src/bar.js @@ -1,21 +1,27 @@ -import { getButtons } from "./buttons"; +import { getButtons, getDislikeButton, getLikeButton } from "./buttons"; import { extConfig, isMobile, isLikesDisabled, isNewDesign, + isRoundedDesign, isShorts, } from "./state"; -import { cLog, getColorFromTheme } from "./utils"; +import { cLog, getColorFromTheme, isInViewport } from "./utils"; function createRateBar(likes, dislikes) { + let rateBar = document.getElementById("ryd-bar-container"); if (!isLikesDisabled()) { - let rateBar = document.getElementById("ryd-bar-container"); + // sometimes rate bar is hidden + if (rateBar && !isInViewport(rateBar)) { + rateBar.remove(); + rateBar = null; + } const widthPx = - getButtons().children[0].clientWidth + - getButtons().children[1].clientWidth + - 8; + getLikeButton().clientWidth + + getDislikeButton().clientWidth + + (isRoundedDesign() ? 0 : 8); const widthPercent = likes + dislikes > 0 ? (likes / (likes + dislikes)) * 100 : 50; @@ -54,17 +60,17 @@ function createRateBar(likes, dislikes) { colorLikeStyle = "; background-color: " + getColorFromTheme(true); colorDislikeStyle = "; background-color: " + getColorFromTheme(false); } - + let actions = + isNewDesign() && getButtons().id === "top-level-buttons-computed" + ? getButtons() + : document.getElementById("menu-container"); ( - document.getElementById( - isNewDesign() ? "actions-inner" : "menu-container" - ) || document.querySelector("ytm-slim-video-action-bar-renderer") + actions || + document.querySelector("ytm-slim-video-action-bar-renderer") ).insertAdjacentHTML( "beforeend", ` -
+
${tooltipInnerHTML}
- ` + `, ); - // Add border between info and comments if (isNewDesign()) { + // Add border between info and comments let descriptionAndActionsElement = document.getElementById("top-row"); descriptionAndActionsElement.style.borderBottom = "1px solid var(--yt-spec-10-percent-layer)"; descriptionAndActionsElement.style.paddingBottom = "10px"; + + // Fix like/dislike ratio bar offset in new UI + document.getElementById("actions-inner").style.width = "revert"; + if (isRoundedDesign()) { + document.getElementById("actions").style.flexDirection = + "row-reverse"; + } } } else { - document.getElementById("ryd-bar-container").style.width = - widthPx + "px"; + document.querySelector(`.ryd-tooltip`).style.width = widthPx + "px"; document.getElementById("ryd-bar").style.width = widthPercent + "%"; document.querySelector("#ryd-dislike-tooltip > #tooltip").innerHTML = tooltipInnerHTML; @@ -106,9 +118,8 @@ function createRateBar(likes, dislikes) { } } else { cLog("removing bar"); - let ratebar = document.getElementById("ryd-bar-container"); - if (ratebar) { - ratebar.parentNode.removeChild(ratebar); + if (rateBar) { + rateBar.parentNode.removeChild(rateBar); } } } diff --git a/Extensions/combined/src/buttons.js b/Extensions/combined/src/buttons.js index 95ba1c63..074b8e53 100644 --- a/Extensions/combined/src/buttons.js +++ b/Extensions/combined/src/buttons.js @@ -1,16 +1,15 @@ -import { isMobile, isShorts } from "./state"; -import { isInViewport } from "./utils"; +import { isMobile, isShorts, extConfig } from "./state"; +import { isInViewport, querySelector, querySelectorAll } from "./utils"; function getButtons() { //--- If Watching Youtube Shorts: ---// if (isShorts()) { - let elements = document.querySelectorAll( - isMobile() - ? "ytm-like-button-renderer" - : "#like-button > ytd-like-button-renderer" - ); + let elements = isMobile() + ? querySelectorAll(extConfig.selectors.buttons.shorts.mobile) + : querySelectorAll(extConfig.selectors.buttons.shorts.desktop); + for (let element of elements) { - //Youtube Shorts can have multiple like/dislike buttons when scrolling through videos + //YouTube Shorts can have multiple like/dislike buttons when scrolling through videos //However, only one of them should be visible (no matter how you zoom) if (isInViewport(element)) { return element; @@ -19,31 +18,102 @@ function getButtons() { } //--- If Watching On Mobile: ---// if (isMobile()) { - return document.querySelector(".slim-video-action-bar-actions"); + return document.querySelector(extConfig.selectors.buttons.regular.mobile); } //--- If Menu Element Is Displayed: ---// - if (document.getElementById("menu-container")?.offsetParent === null) { - return document.querySelector("ytd-menu-renderer.ytd-watch-metadata > div"); - //--- If Menu Element Isnt Displayed: ---// + if (querySelector(extConfig.selectors.menuContainer)?.offsetParent === null) { + return querySelector(extConfig.selectors.buttons.regular.desktopMenu); + //--- If Menu Element Isn't Displayed: ---// } else { - return document - .getElementById("menu-container") - ?.querySelector("#top-level-buttons-computed"); + return querySelector(extConfig.selectors.buttons.regular.desktopNoMenu); } } function getLikeButton() { - return getButtons().children[0]; + return getButtons().children[0].tagName === + "YTD-SEGMENTED-LIKE-DISLIKE-BUTTON-RENDERER" + ? querySelector(extConfig.selectors.buttons.likeButton.segmented) ?? + querySelector( + extConfig.selectors.buttons.likeButton.segmentedGetButtons, + getButtons(), + ) + : querySelector( + extConfig.selectors.buttons.likeButton.notSegmented, + getButtons(), + ); +} + +function getLikeTextContainer() { + return querySelector(extConfig.selectors.likeTextContainer, getLikeButton()); } function getDislikeButton() { - return getButtons().children[1]; + return getButtons().children[0].tagName === + "YTD-SEGMENTED-LIKE-DISLIKE-BUTTON-RENDERER" + ? querySelector(extConfig.selectors.buttons.dislikeButton.segmented) ?? + querySelector( + extConfig.selectors.buttons.dislikeButton.segmentedGetButtons, + getButtons(), + ) + : isShorts() + ? querySelector(["#dislike-button"], getButtons()) + : querySelector( + extConfig.selectors.buttons.dislikeButton.notSegmented, + getButtons(), + ); +} + +function createDislikeTextContainer() { + const textNodeClone = ( + getLikeButton().querySelector( + ".yt-spec-button-shape-next__button-text-content", + ) || + getLikeButton().querySelector("button > div[class*='cbox']") || + ( + getLikeButton().querySelector('div > span[role="text"]') || + document.querySelector( + 'button > div.yt-spec-button-shape-next__button-text-content > span[role="text"]', + ) + ).parentNode + ).cloneNode(true); + const insertPreChild = getDislikeButton().querySelector("button"); + insertPreChild.insertBefore(textNodeClone, null); + getDislikeButton() + .querySelector("button") + .classList.remove("yt-spec-button-shape-next--icon-button"); + getDislikeButton() + .querySelector("button") + .classList.add("yt-spec-button-shape-next--icon-leading"); + if (textNodeClone.querySelector("span[role='text']") === null) { + const span = document.createElement("span"); + span.setAttribute("role", "text"); + while (textNodeClone.firstChild) { + textNodeClone.removeChild(textNodeClone.firstChild); + } + textNodeClone.appendChild(span); + } + textNodeClone.innerText = ""; + return textNodeClone; +} + +function getDislikeTextContainer() { + let result; + for (const selector of extConfig.selectors.dislikeTextContainer) { + result = getDislikeButton().querySelector(selector); + if (result !== null) { + break; + } + } + if (result == null) { + result = createDislikeTextContainer(); + } + return result; } function checkForSignInButton() { if ( document.querySelector( - "a[href^='https://accounts.google.com/ServiceLogin']" + "a[href^='https://accounts.google.com/ServiceLogin']", ) ) { return true; @@ -52,4 +122,11 @@ function checkForSignInButton() { } } -export { getButtons, getLikeButton, getDislikeButton, checkForSignInButton }; +export { + getButtons, + getLikeButton, + getDislikeButton, + getLikeTextContainer, + getDislikeTextContainer, + checkForSignInButton, +}; diff --git a/Extensions/combined/src/events.js b/Extensions/combined/src/events.js index 9b0e78ae..92511c71 100644 --- a/Extensions/combined/src/events.js +++ b/Extensions/combined/src/events.js @@ -1,5 +1,16 @@ -import { getBrowser, getVideoId, numberFormat, cLog } from "./utils"; -import { checkForSignInButton, getButtons } from "./buttons"; +import { + getBrowser, + getVideoId, + numberFormat, + cLog, + createObserver, +} from "./utils"; +import { + checkForSignInButton, + getButtons, + getDislikeButton, + getLikeButton, +} from "./buttons"; import { NEUTRAL_STATE, LIKED_STATE, @@ -22,24 +33,28 @@ function sendVote(vote) { } } +function updateDOMDislikes() { + setDislikes(numberFormat(storedData.dislikes)); + createRateBar(storedData.likes, storedData.dislikes); +} + function likeClicked() { if (checkForSignInButton() === false) { if (storedData.previousState === DISLIKED_STATE) { sendVote(1); if (storedData.dislikes > 0) storedData.dislikes--; storedData.likes++; - createRateBar(storedData.likes, storedData.dislikes); - setDislikes(numberFormat(storedData.dislikes)); + updateDOMDislikes(); storedData.previousState = LIKED_STATE; } else if (storedData.previousState === NEUTRAL_STATE) { sendVote(1); storedData.likes++; - createRateBar(storedData.likes, storedData.dislikes); + updateDOMDislikes(); storedData.previousState = LIKED_STATE; } else if ((storedData.previousState = LIKED_STATE)) { sendVote(0); if (storedData.likes > 0) storedData.likes--; - createRateBar(storedData.likes, storedData.dislikes); + updateDOMDislikes(); storedData.previousState = NEUTRAL_STATE; } if (extConfig.numberDisplayReformatLikes === true) { @@ -56,21 +71,18 @@ function dislikeClicked() { if (storedData.previousState === NEUTRAL_STATE) { sendVote(-1); storedData.dislikes++; - setDislikes(numberFormat(storedData.dislikes)); - createRateBar(storedData.likes, storedData.dislikes); + updateDOMDislikes(); storedData.previousState = DISLIKED_STATE; } else if (storedData.previousState === DISLIKED_STATE) { sendVote(0); if (storedData.dislikes > 0) storedData.dislikes--; - setDislikes(numberFormat(storedData.dislikes)); - createRateBar(storedData.likes, storedData.dislikes); + updateDOMDislikes(); storedData.previousState = NEUTRAL_STATE; } else if (storedData.previousState === LIKED_STATE) { sendVote(-1); if (storedData.likes > 0) storedData.likes--; storedData.dislikes++; - setDislikes(numberFormat(storedData.dislikes)); - createRateBar(storedData.likes, storedData.dislikes); + updateDOMDislikes(); storedData.previousState = DISLIKED_STATE; if (extConfig.numberDisplayReformatLikes === true) { const nativeLikes = getLikeCountFromButton(); @@ -83,20 +95,49 @@ function dislikeClicked() { } function addLikeDislikeEventListener() { - const buttons = getButtons(); - if (!window.returnDislikeButtonlistenersSet) { - buttons.children[0].addEventListener("click", likeClicked); - buttons.children[1].addEventListener("click", dislikeClicked); - buttons.children[0].addEventListener("touchstart", likeClicked); - buttons.children[1].addEventListener("touchstart", dislikeClicked); - window.returnDislikeButtonlistenersSet = true; + if (window.rydPreNavigateLikeButton !== getLikeButton()) { + getLikeButton().addEventListener("click", likeClicked); + getLikeButton().addEventListener("touchstart", likeClicked); + if (getDislikeButton()) { + getDislikeButton().addEventListener("click", dislikeClicked); + getDislikeButton().addEventListener("touchstart", dislikeClicked); + getDislikeButton().addEventListener("focusin", updateDOMDislikes); + getDislikeButton().addEventListener("focusout", updateDOMDislikes); + } + window.rydPreNavigateLikeButton = getLikeButton(); + } +} + +let smartimationObserver = null; + +function createSmartimationObserver() { + if (!smartimationObserver) { + smartimationObserver = createObserver( + { + attributes: true, + subtree: true, + }, + updateDOMDislikes, + ); + smartimationObserver.container = null; + } + + const smartimationContainer = getButtons().querySelector("yt-smartimation"); + if ( + smartimationContainer && + smartimationObserver.container != smartimationContainer + ) { + cLog("Initializing smartimation mutation observer"); + smartimationObserver.disconnect(); + smartimationObserver.observe(smartimationContainer); + smartimationObserver.container = smartimationContainer; } } function storageChangeHandler(changes, area) { if (changes.disableVoteSubmission !== undefined) { handleDisableVoteSubmissionChangeEvent( - changes.disableVoteSubmission.newValue + changes.disableVoteSubmission.newValue, ); } if (changes.coloredThumbs !== undefined) { @@ -108,18 +149,12 @@ function storageChangeHandler(changes, area) { if (changes.colorTheme !== undefined) { handleColorThemeChangeEvent(changes.colorTheme.newValue); } - - if (changes.numberDisplayRoundDown !== undefined) { - handleNumberDisplayRoundDownChangeEvent( - changes.numberDisplayRoundDown.newValue - ); - } if (changes.numberDisplayFormat !== undefined) { handleNumberDisplayFormatChangeEvent(changes.numberDisplayFormat.newValue); } if (changes.numberDisplayReformatLikes !== undefined) { handleNumberDisplayReformatLikesChangeEvent( - changes.numberDisplayReformatLikes.newValue + changes.numberDisplayReformatLikes.newValue, ); } } @@ -145,10 +180,6 @@ function handleNumberDisplayFormatChangeEvent(value) { extConfig.numberDisplayFormat = value; } -function handleNumberDisplayRoundDownChangeEvent(value) { - extConfig.numberDisplayRoundDown = value; -} - function handleNumberDisplayReformatLikesChangeEvent(value) { extConfig.numberDisplayReformatLikes = value; } @@ -158,5 +189,6 @@ export { likeClicked, dislikeClicked, addLikeDislikeEventListener, + createSmartimationObserver, storageChangeHandler, }; diff --git a/Extensions/combined/src/starRating.js b/Extensions/combined/src/starRating.js index 65cf18b1..74779eda 100644 --- a/Extensions/combined/src/starRating.js +++ b/Extensions/combined/src/starRating.js @@ -9,7 +9,7 @@ function createStarRating(rating, isMobile) { starSlider.setAttribute("readonly", ""); starSlider.setAttribute( "style", - `--fill:rgb(255, 215, 0);--value:${rating.toString()};};background-color: transparent;` + `--fill:rgb(255, 215, 0);--value:${rating.toString()};};background-color: transparent;`, ); starSlider.setAttribute("type", "range"); @@ -19,11 +19,11 @@ function createStarRating(rating, isMobile) { if (isMobile) { YTLikeButton = document.querySelector( - "#app > div.page-container > ytm-watch > ytm-single-column-watch-next-results-renderer > ytm-slim-video-metadata-section-renderer > ytm-slim-video-action-bar-renderer > div > ytm-slim-metadata-toggle-button-renderer:nth-child(1)" + "#app > div.page-container > ytm-watch > ytm-single-column-watch-next-results-renderer > ytm-slim-video-metadata-section-renderer > ytm-slim-video-action-bar-renderer > div > ytm-slim-metadata-toggle-button-renderer:nth-child(1)", ); } else { YTLikeButton = document.querySelector( - "#top-level-buttons-computed > ytd-toggle-button-renderer:nth-child(1)" + "#top-level-buttons-computed > ytd-toggle-button-renderer:nth-child(1)", ); } diff --git a/Extensions/combined/src/state.js b/Extensions/combined/src/state.js index 0e72e970..47b6cafb 100644 --- a/Extensions/combined/src/state.js +++ b/Extensions/combined/src/state.js @@ -1,4 +1,10 @@ -import { getLikeButton, getDislikeButton, getButtons } from "./buttons"; +import { + getLikeButton, + getDislikeButton, + getButtons, + getLikeTextContainer, + getDislikeTextContainer, +} from "./buttons"; import { createRateBar } from "./bar"; import { getBrowser, @@ -6,9 +12,10 @@ import { cLog, numberFormat, getColorFromTheme, + querySelector, + localize, + createObserver, } from "./utils"; -import { localize } from "./utils"; -import { createStarRating } from "./starRating"; //TODO: Do not duplicate here and in ryd.background.js const apiUrl = "https://returnyoutubedislikeapi.com"; @@ -18,14 +25,41 @@ const NEUTRAL_STATE = "NEUTRAL_STATE"; let extConfig = { disableVoteSubmission: false, + disableLogging: true, coloredThumbs: false, coloredBar: false, colorTheme: "classic", numberDisplayFormat: "compactShort", - numberDisplayRoundDown: true, showTooltipPercentage: false, tooltipPercentageMode: "dash_like", numberDisplayReformatLikes: false, + selectors: { + dislikeTextContainer: [], + likeTextContainer: [], + buttons: { + shorts: { + mobile: [], + desktop: [], + }, + regular: { + mobile: [], + desktopMenu: [], + desktopNoMenu: [], + }, + likeButton: { + segmented: [], + segmentedGetButtons: [], + notSegmented: [], + }, + dislikeButton: { + segmented: [], + segmentedGetButtons: [], + notSegmented: [], + }, + }, + menuContainer: [], + roundedDesign: [], + }, }; let storedData = { @@ -46,21 +80,19 @@ function isNewDesign() { return document.getElementById("comment-teaser") !== null; } -function initMutationObserver() { - let mutationObserver = new Object(); +function isRoundedDesign() { + return querySelector(extConfig.selectors.roundedDesign) !== null; +} + +let shortsObserver = null; - if (isShorts() && mutationObserver.exists !== true) { - cLog("initializing mutation observer"); - mutationObserver.options = { - childList: false, +if (isShorts() && !shortsObserver) { + cLog("Initializing shorts mutation observer"); + shortsObserver = createObserver( + { attributes: true, - subtree: false, - }; - mutationObserver.exists = true; - mutationObserver.observer = new MutationObserver(function ( - mutationList, - observer - ) { + }, + (mutationList) => { mutationList.forEach((mutation) => { if ( mutation.type === "attributes" && @@ -79,45 +111,51 @@ function initMutationObserver() { return; } cLog( - "unexpected mutation observer event: " + + "Unexpected mutation observer event: " + mutation.target + - mutation.type + mutation.type, ); }); - }); - } + }, + ); } function isLikesDisabled() { // return true if the like button's text doesn't contain any number if (isMobile()) { return /^\D*$/.test( - getButtons().children[0].querySelector(".button-renderer-text").innerText + getButtons().children[0].querySelector(".button-renderer-text").innerText, ); } - return /^\D*$/.test( - getButtons().children[0].querySelector("#text").innerText - ); + return /^\D*$/.test(getLikeTextContainer().innerText); } function isVideoLiked() { if (isMobile()) { return ( - getLikeButton().querySelector("button").getAttribute("aria-label") == + getLikeButton().querySelector("button").getAttribute("aria-label") === "true" ); } - return getLikeButton().classList.contains("style-default-active"); + return ( + getLikeButton().classList.contains("style-default-active") || + getLikeButton().querySelector("button")?.getAttribute("aria-pressed") === + "true" + ); } function isVideoDisliked() { if (isMobile()) { return ( - getDislikeButton().querySelector("button").getAttribute("aria-label") == + getDislikeButton().querySelector("button").getAttribute("aria-label") === "true" ); } - return getDislikeButton().classList.contains("style-default-active"); + return ( + getDislikeButton().classList.contains("style-default-active") || + getDislikeButton().querySelector("button")?.getAttribute("aria-pressed") === + "true" + ); } function getState(storedData) { @@ -132,42 +170,50 @@ function getState(storedData) { //--- Sets The Likes And Dislikes Values ---// function setLikes(likesCount) { - getButtons().children[0].querySelector("#text").innerText = likesCount; + cLog(`SET likes ${likesCount}`); + getLikeTextContainer().innerText = likesCount; } function setDislikes(dislikesCount) { + cLog(`SET dislikes ${dislikesCount}`); + getDislikeTextContainer()?.removeAttribute("is-empty"); if (!isLikesDisabled()) { if (isMobile()) { getButtons().children[1].querySelector( - ".button-renderer-text" + ".button-renderer-text", ).innerText = dislikesCount; return; } - getButtons().children[1].querySelector("#text").innerText = dislikesCount; + getDislikeTextContainer().innerText = dislikesCount; } else { cLog("likes count disabled by creator"); if (isMobile()) { getButtons().children[1].querySelector( - ".button-renderer-text" + ".button-renderer-text", ).innerText = localize("TextLikesDisabled"); return; } - getButtons().children[1].querySelector("#text").innerText = - localize("TextLikesDisabled"); + getDislikeTextContainer().innerText = localize("TextLikesDisabled"); } } function getLikeCountFromButton() { - if (isShorts()) { - //Youtube Shorts don't work with this query. It's not nessecary; we can skip it and still see the results. - //It should be possible to fix this function, but it's not critical to showing the dislike count. + try { + if (isShorts()) { + //Youtube Shorts don't work with this query. It's not necessary; we can skip it and still see the results. + //It should be possible to fix this function, but it's not critical to showing the dislike count. + return false; + } + + let likeButton = + getLikeButton().querySelector("yt-formatted-string#text") ?? + getLikeButton().querySelector("button"); + + let likesStr = likeButton.getAttribute("aria-label").replace(/\D/g, ""); + return likesStr.length > 0 ? parseInt(likesStr) : false; + } catch { return false; } - let likesStr = getLikeButton() - .querySelector("yt-formatted-string#text") - .getAttribute("aria-label") - .replace(/\D/g, ""); - return likesStr.length > 0 ? parseInt(likesStr) : false; } function processResponse(response, storedData) { @@ -184,12 +230,12 @@ function processResponse(response, storedData) { createRateBar(storedData.likes, storedData.dislikes); if (extConfig.coloredThumbs === true) { if (isShorts()) { - // for shorts, leave deactived buttons in default color + // for shorts, leave deactivated buttons in default color let shortLikeButton = getLikeButton().querySelector( - "tp-yt-paper-button#button" + "tp-yt-paper-button#button", ); let shortDislikeButton = getDislikeButton().querySelector( - "tp-yt-paper-button#button" + "tp-yt-paper-button#button", ); if (shortLikeButton.getAttribute("aria-pressed") === "true") { shortLikeButton.style.color = getColorFromTheme(true); @@ -197,14 +243,8 @@ function processResponse(response, storedData) { if (shortDislikeButton.getAttribute("aria-pressed") === "true") { shortDislikeButton.style.color = getColorFromTheme(false); } - mutationObserver.observer.observe( - shortLikeButton, - mutationObserver.options - ); - mutationObserver.observer.observe( - shortDislikeButton, - mutationObserver.options - ); + shortsObserver.observe(shortLikeButton); + shortsObserver.observe(shortDislikeButton); } else { getLikeButton().style.color = getColorFromTheme(true); getDislikeButton().style.color = getColorFromTheme(false); @@ -216,18 +256,17 @@ function processResponse(response, storedData) { // Tells the user if the API is down function displayError(error) { - getButtons().children[1].querySelector("#text").innerText = localize( - "textTempUnavailable" - ); + getDislikeTextContainer().innerText = localize("textTempUnavailable"); } async function setState(storedData) { storedData.previousState = isVideoDisliked() ? DISLIKED_STATE : isVideoLiked() - ? LIKED_STATE - : NEUTRAL_STATE; + ? LIKED_STATE + : NEUTRAL_STATE; let statsSet = false; + cLog("Video is loaded. Adding buttons..."); let videoId = getVideoId(window.location.href); let likeCount = getLikeCountFromButton() || null; @@ -239,7 +278,7 @@ async function setState(storedData) { headers: { Accept: "application/json", }, - } + }, ) .then((response) => { if (!response.ok) displayError(response.error); @@ -254,20 +293,35 @@ async function setState(storedData) { } } -function setInitialState() { - setState(storedData); +async function setInitialState() { + await setState(storedData); } -function initExtConfig() { +async function initExtConfig() { initializeDisableVoteSubmission(); + initializeDisableLogging(); initializeColoredThumbs(); initializeColoredBar(); initializeColorTheme(); initializeNumberDisplayFormat(); - initializeNumberDisplayRoundDown(); initializeTooltipPercentage(); initializeTooltipPercentageMode(); initializeNumberDisplayReformatLikes(); + await initializeSelectors(); +} + +async function initializeSelectors() { + console.log("initializing selectors"); + let result = await fetch(`${apiUrl}/configs/selectors`, { + method: "GET", + headers: { + Accept: "application/json", + }, + }) + .then((response) => response.json()) + .catch((error) => {}); + extConfig.selectors = result ?? extConfig.selectors; + console.log(result); } function initializeDisableVoteSubmission() { @@ -280,6 +334,16 @@ function initializeDisableVoteSubmission() { }); } +function initializeDisableLogging() { + getBrowser().storage.sync.get(["disableLogging"], (res) => { + if (res.disableLogging === undefined) { + getBrowser().storage.sync.set({ disableLogging: true }); + } else { + extConfig.disableLogging = res.disableLogging; + } + }); +} + function initializeColoredThumbs() { getBrowser().storage.sync.get(["coloredThumbs"], (res) => { if (res.coloredThumbs === undefined) { @@ -300,16 +364,6 @@ function initializeColoredBar() { }); } -function initializeNumberDisplayRoundDown() { - getBrowser().storage.sync.get(["numberDisplayRoundDown"], (res) => { - if (res.numberDisplayRoundDown === undefined) { - getBrowser().storage.sync.set({ numberDisplayRoundDown: true }); - } else { - extConfig.numberDisplayRoundDown = res.numberDisplayRoundDown; - } - }); -} - function initializeColorTheme() { getBrowser().storage.sync.get(["colorTheme"], (res) => { if (res.colorTheme === undefined) { @@ -366,6 +420,7 @@ export { isVideoDisliked, isVideoLiked, isNewDesign, + isRoundedDesign, getState, setState, setInitialState, @@ -377,7 +432,6 @@ export { NEUTRAL_STATE, extConfig, initExtConfig, - initMutationObserver, storedData, isLikesDisabled, }; diff --git a/Extensions/combined/src/utils.js b/Extensions/combined/src/utils.js index 383b17bf..1191afdf 100644 --- a/Extensions/combined/src/utils.js +++ b/Extensions/combined/src/utils.js @@ -1,23 +1,7 @@ import { extConfig } from "./state"; -function roundDown(num) { - if (num < 1000) return num; - const int = Math.floor(Math.log10(num) - 2); - const decimal = int + (int % 3 ? 1 : 0); - const value = Math.floor(num / 10 ** decimal); - return value * 10 ** decimal; -} - function numberFormat(numberState) { - let numberDisplay; - if (extConfig.numberDisplayRoundDown === false) { - numberDisplay = numberState; - } else { - numberDisplay = roundDown(numberState); - } - return getNumberFormatter(extConfig.numberDisplayFormat).format( - numberDisplay - ); + return getNumberFormatter(extConfig.numberDisplayFormat).format(numberState); } function getNumberFormatter(optionSelect) { @@ -31,12 +15,10 @@ function getNumberFormatter(optionSelect) { userLocales = new URL( Array.from(document.querySelectorAll("head > link[rel='search']")) ?.find((n) => n?.getAttribute("href")?.includes("?locale=")) - ?.getAttribute("href") + ?.getAttribute("href"), )?.searchParams?.get("locale"); } catch { - cLog( - "Cannot find browser locale. Use en as default for number formatting." - ); + cLog("Cannot find browser locale. Use en as default for number formatting."); userLocales = "en"; } } @@ -72,10 +54,7 @@ function localize(localeString) { function getBrowser() { if (typeof chrome !== "undefined" && typeof chrome.runtime !== "undefined") { return chrome; - } else if ( - typeof browser !== "undefined" && - typeof browser.runtime !== "undefined" - ) { + } else if (typeof browser !== "undefined" && typeof browser.runtime !== "undefined") { return browser; } else { console.log("browser is not supported"); @@ -87,7 +66,7 @@ function getVideoId(url) { const urlObject = new URL(url); const pathname = urlObject.pathname; if (pathname.startsWith("/clip")) { - return document.querySelector("meta[itemprop='videoId']").content; + return (document.querySelector("meta[itemprop='videoId']") || document.querySelector("meta[itemprop='identifier']")).content; } else { if (pathname.startsWith("/shorts")) { return pathname.slice(8); @@ -101,6 +80,9 @@ function isInViewport(element) { const height = innerHeight || document.documentElement.clientHeight; const width = innerWidth || document.documentElement.clientWidth; return ( + // When short (channel) is ignored, the element (like/dislike AND short itself) is + // hidden with a 0 DOMRect. In this case, consider it outside of Viewport + !(rect.top == 0 && rect.left == 0 && rect.bottom == 0 && rect.right == 0) && rect.top >= 0 && rect.left >= 0 && rect.bottom <= height && @@ -111,6 +93,9 @@ function isInViewport(element) { function isVideoLoaded() { const videoId = getVideoId(window.location.href); return ( + // desktop: spring 2024 UI + document.querySelector(`ytd-watch-grid[video-id='${videoId}']`) !== null || + // desktop: older UI document.querySelector(`ytd-watch-flexy[video-id='${videoId}']`) !== null || // mobile: no video-id attribute document.querySelector('#player[loading="false"]:not([hidden])') !== null @@ -118,11 +103,13 @@ function isVideoLoaded() { } function cLog(message, writer) { - message = `[return youtube dislike]: ${message}`; - if (writer) { - writer(message); - } else { - console.log(message); + if (!extConfig.disableLogging){ + message = `[return youtube dislike]: ${message}`; + if (writer) { + writer(message); + } else { + console.log(message); + } } } @@ -154,6 +141,40 @@ function getColorFromTheme(voteIsLike) { return colorString; } +function querySelector(selectors, element) { + let result; + for (const selector of selectors) { + result = (element ?? document).querySelector(selector); + if (result !== null) { + return result; + } + } +} + +function querySelectorAll(selectors) { + let result; + for (const selector of selectors) { + result = document.querySelectorAll(selector); + if (result.length !== 0) { + return result; + } + } + return result; +} + +function createObserver(options, callback) { + const observerWrapper = new Object(); + observerWrapper.options = options; + observerWrapper.observer = new MutationObserver(callback); + observerWrapper.observe = function (element) { + this.observer.observe(element, this.options); + }; + observerWrapper.disconnect = function () { + this.observer.disconnect(); + }; + return observerWrapper; +} + export { roundDown, numberFormat, @@ -165,4 +186,7 @@ export { cLog, getColorFromTheme, localize, + querySelector, + querySelectorAll, + createObserver, }; diff --git a/README.md b/README.md index b31aa56b..f8de4ab1 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) [![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) -Read this in other languages: [Español](READMEes.md), [русский](READMEru.md), [Français](READMEfr.md), [日本語](READMEja.md), [Türkçe](READMEtr.md) +Read this in other languages: [русский](READMEru.md), [Español](READMEes.md), [Nederlands](READMEnl.md), [Français](READMEfr.md), [日本語](READMEja.md), [Türkçe](READMEtr.md), [українська](READMEuk.md), [Deutsch](READMEde.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md), [中文](READMEcn.md), [Polski](READMEpl.md), [Português do Brasil](READMEpt_BR.md) # Return YouTube Dislike @@ -39,7 +39,7 @@ You can learn more at our website at: [returnyoutubedislike.com](https://www.ret Third-party use of this open API is allowed with the following restrictions: - **Attribution**: This project should be clearly attributed with a link to [returnyoutubedislike.com](https://returnyoutubedislike.com/). -- **Rate Limiting**: There are per client rate limits in place of 100 per minute and 10'000 per day. This will return a _429_ status code indicating that your application should back off. +- **Rate Limiting**: There are per client rate limits in place of 100 per minute and 10,000 per day. This will return a _429_ status code indicating that your application should back off. The API is accessible over the following base URL: https://returnyoutubedislikeapi.com @@ -64,7 +64,7 @@ Example to get votes of a given YouTube video ID: } ``` -None existing YouTube ID will return status code _404_ "Not Found". +Non-existent YouTube ID will return status code _404_ "Not Found". Wrong formed YouTube ID will return _400_ "Bad Request". + +Am 10. November 2021, [kündigte Google an](https://blog.youtube/news-and-events/update-to-youtube/) das der YouTube Dislike-Zähler von der Platform entfernt werden sollte. + +Zusätzlich, wurde das `dislike` Feld in der YouTube API am 13. Dezember 2021 [entfernt](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts), und damit auch jegliche Möglichkeit die Qualität der Inhalte zu bewerten bevor man das Video sah. + +## Was die Erweiterung macht + +Mit der entfernung der Statistiken der YouTube API, wechselte unser Backend zu einer Kombination von archivierten Dislike Statistiken sowie den extrapolierten Schätzungen durch die Nutzerdaten dieser Erweiterung anfallen, um die Dislike-Zahlen zu berechnen. + +[FAQ](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQ.md) + +## Warum dies wichtig ist + +Mehr erfahren Sie auf unserer Website unter: [returnyoutubedislike.com](https://www.returnyoutubedislike.com/) + +## API Dokumentierung + +Dritte dürfen diese öffentliche API mit folgenden Restriktionen benützen: + +- **Namensnennung**: Dieses Projekt sollte klar und mit folgendem Link [returnyoutubedislike.com](https://returnyoutubedislike.com/) versehen zugeordnet werden. +- **Raten Limitierung**: Es bestehen pro Nutzer limitierungen von 100 pro Minute sowie 10'000 pro Tag. Dies wird eine Statusmeldung von _429_ ausgeben, die darauf hinweist, dass sich Ihre Anwendung zurückziehen sollte. + +Die API ist unter der folgenden basis URL verfügbar: +https://returnyoutubedislikeapi.com + +Eine Liste aller verfügbaren Endpunkten finden Sie hier: +https://returnyoutubedislikeapi.com/swagger/index.html + +### Votum erhalten + +Beispiel um die Abstimmungen einer gegebenen YouTube ID zu erhalten: +`/votes?videoId=kxOuG8jMIgI` + +```json +{ + "id": "kxOuG8jMIgI", + "dateCreated": "2021-12-20T12:25:54.418014Z", + "likes": 27326, + "dislikes": 498153, + "rating": 1.212014408444885, + "viewCount": 3149885, + "deleted": false +} +``` + +Nicht existierende YouTube IDs werden den Statuscode _404_ "Not Found" zurückgeben. +Falsch geformte YouTube IDs werden den Statuscode _400_ "Bad Request" zurückgeben. + + + +## Beitragen + +Bitte lesen Sie das [Beitrags-Handbuch](https://github.com/Anarios/return-youtube-dislike/blob/main/CONTRIBUTING.md). + +## Unterstütze dieses Projekt! + +Sie können das Projekt unterstützen indem Sie unter den folgenden Link spenden: + +[Spenden](https://returnyoutubedislike.com/donate) + +## Sponsoren + +[Seed4.Me VPN](https://www.seed4.me/users/register?gift=ReturnYoutubeDislike) + +[Werde unser Sponsor](https://www.patreon.com/join/returnyoutubedislike/checkout?rid=8008601) diff --git a/READMEes.md b/READMEes.md index 63704b04..a4b091ae 100644 --- a/READMEes.md +++ b/READMEes.md @@ -7,7 +7,7 @@ [![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) [![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) -Leer en otros idiomas: [English](README.md), [русский](READMEru.md), [Français](READMEfr.md) [日本語](READMEja.md), [Türkçe](READMEtr.md) +Leer en otros idiomas: [English](README.md), [русский](READMEru.md), [Nederlands](READMEnl.md), [Français](READMEfr.md), [日本語](READMEja.md), [Türkçe](READMEtr.md), [українська](READMEuk.md), [Deutsch](READMEde.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md), [中文](READMEcn.md), [Polski](READMEpl.md) # Return YouTube Dislike diff --git a/READMEfr.md b/READMEfr.md index 6915d88c..a84131c8 100644 --- a/READMEfr.md +++ b/READMEfr.md @@ -7,9 +7,9 @@ [![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) [![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](LICENSE) -# Return YouTube Dislike +Lisez ceci dans d'autres langues : [English](README.md), [русский](READMEru.md), [Español](READMEes.md), [Nederlands](READMEnl.md),[日本語](READMEja.md), [Türkçe](READMEtr.md), [українська](READMEuk.md), [Deutsch](READMEde.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md), [中文](READMEcn.md), [Polski](READMEpl.md) -Lisez ceci dans d'autres langues : [English](README.md), [Español](READMEes.md), [русский](READMEru.md), [Türkçe](READMEtr.md) +# Return YouTube Dislike

Return YouTube Dislike est une extension open-source qui ré-affiche les dislikes (pouces rouges) sur YouTube.
@@ -64,8 +64,8 @@ Exemple pour obtenir les likes d'une vidéo YouTube avec un ID donné: } ``` -Si aucunne vidéo YouTube à cet ID, il sera retourner le code d'erreur _404_ "Not Found". -Un ID YouTube invilide renverra _400_ "Bad Request". +Si aucune vidéo YouTube n'a cet ID, le code d'erreur _404_ "Not Found" sera retourné. +Un ID YouTube invalide renverra le code d'erreur _400_ "Bad Request". + +## Συνεισφορά + +Παρακαλώ διαβάστε τον [οδηγό συνεισφοράς](https://github.com/Anarios/return-youtube-dislike/blob/main/CONTRIBUTING.md). + +## Υποστηρίξτε αυτό το project! + +Μπορείτε να υποστηρίξετε αυτό το έργο κάνοντας δωρεά προς εμάς στον παρακάτω σύνδεσμο: + +[Δωρεά](https://returnyoutubedislike.com/donate) + +## Χορηγοί + +[Piepacker](https://piepacker.com) + +[Seed4.Me VPN](https://www.seed4.me/users/register?gift=ReturnYoutubeDislike) + +[PocketTube](https://yousub.info/?utm_source=returnyoutubedislike) + +[Γίνεται χορηγός μας](https://www.patreon.com/join/returnyoutubedislike/checkout?rid=8008601) diff --git a/READMEja.md b/READMEja.md index 2aba04b7..20a564aa 100644 --- a/READMEja.md +++ b/READMEja.md @@ -7,7 +7,7 @@ [![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) [![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) -別の言語: [English](README.md), [Español](READMEes.md), [русский](READMEru.md), [Türkçe](READMEtr.md) +別の言語: [English](README.md), [русский](READMEru.md), [Español](READMEes.md), [Nederlands](READMEnl.md), [Français](READMEfr.md), [Türkçe](READMEtr.md), [українська](READMEuk.md), [Deutsch](READMEde.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md), [中文](READMEcn.md), [Polski](READMEpl.md) # Return YouTube Dislike diff --git a/READMEnl.md b/READMEnl.md new file mode 100644 index 00000000..db693862 --- /dev/null +++ b/READMEnl.md @@ -0,0 +1,94 @@ +[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Rating&style=flat&logo=google)](https://chrome.google.com/webstore/detail/youtube-dislike-button/gebbhagfogifgggkldgodflihgfeippi/) +[![Chrome Web Store Users](https://img.shields.io/chrome-web-store/users/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Users&style=flat&logo=google)](https://chrome.google.com/webstore/detail/youtube-dislike-button/gebbhagfogifgggkldgodflihgfeippi/) +[![Mozilla rating](https://img.shields.io/amo/stars/return-youtube-dislikes?label=Firefox%20Rating&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) +[![Mozilla downloads](https://img.shields.io/amo/users/return-youtube-dislikes?label=Firefox%20Users&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) +[![Commit rate](https://img.shields.io/github/commit-activity/m/Anarios/return-youtube-dislike?label=Commits&style=flat)](https://github.com/Anarios/return-youtube-dislike/commits/main) +[![Issues](https://img.shields.io/github/issues/Anarios/return-youtube-dislike?style=flat&label=Issues)](https://github.com/Anarios/return-youtube-dislike/issues) +[![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) +[![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) + +Lees dit in andere talen: [English](README.md), [Español](READMEes.md), [русский](READMEru.md), [Français](READMEfr.md), [日本語](READMEja.md), [Türkçe](READMEtr.md), [українська](READMEuk.md), [Deutsch](READMEde.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md), [中文](READMEcn.md), [Polski](READMEpl.md) + +# Return YouTube Dislike + +

+ Return YouTube Dislike is een open-source extensie die het aantal dislikes van YouTube retourneert.
+ Beschikbaar voor Chrome en Firefox als webextensie.
+ Ook beschikbaar voor andere browsers als JS Userscript.

+ +

+ +## Het Verhaal + +Op 10 november 2021 [kondigde](https://blog.youtube/news-and-events/update-to-youtube/) that the YouTube dislike count would be removed. + +Additionally, the `dislike` field in the YouTube API was [removed](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts) Google aan dat het aantal dislikes op YouTube zou worden verwijderd. + +## Wat het doet + +Met de verwijdering van afkeerstatistieken uit de YouTube API, schakelde onze backend over op het gebruik van een combinatie van geschraapte afkeerstatistieken, schattingen geëxtrapoleerd uit gebruikersgegevens van extensies. + +[FAQ](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQ.md) + +## Waarom het uitmaakt + +U kunt meer informatie vinden op onze website op: [returnyoutubedislike.com](https://www.returnyoutubedislike.com/) + +## API-documentatie + +Gebruik door derden van deze open API is toegestaan ​​met de volgende beperkingen: + +- **Naamsvermelding**: dit project moet duidelijk worden toegeschreven met een link naar [returnyoutubedislike.com](https://returnyoutubedislike.com/). +- **Snelheidsbeperking**: Er zijn tarieflimieten per klant in plaats van 100 per minuut en 10.000 per dag. Hiermee wordt een statuscode _429_ geretourneerd die aangeeft dat uw toepassing moet worden uitgeschakeld. + +De API is toegankelijk via de volgende basis-URL: +https://returnyoutubedislikeapi.com + +Lijst met beschikbare eindpunten is hier beschikbaar: +https://returnyoutubedislikeapi.com/swagger/index.html + +### Stemmen krijgen + +Voorbeeld om stemmen te krijgen voor een bepaalde YouTube-video-ID: +`/votes?videoId=kxOuG8jMIgI` + +```json +{ + "id": "kxOuG8jMIgI", + "dateCreated": "2021-12-20T12:25:54.418014Z", + "likes": 27326, + "dislikes": 498153, + "rating": 1.212014408444885, + "viewCount": 3149885, + "deleted": false +} +``` + +Geen bestaande YouTube-ID retourneert statuscode _404_ "Niet gevonden". +Verkeerd gevormde YouTube-ID retourneert _400_ "Slecht verzoek". + + + +## Bijdragen + +Lees de [bijdragengids](https://github.com/Anarios/return-youtube-dislike/blob/main/CONTRIBUTING.md). + +## Steun dit project! + +U kunt dit project steunen door aan ons te doneren via onderstaande link: + +[Doneer](https://returnyoutubedislike.com/donate) + +## Sponsoren + +[Piepacker](https://piepacker.com) + +[Seed4.Me VPN](https://www.seed4.me/users/register?gift=ReturnYoutubeDislike) + +[PocketTube](https://yousub.info/?utm_source=returnyoutubedislike) + +[Wordt een sponsor](https://www.patreon.com/join/returnyoutubedislike/checkout?rid=8008601) diff --git a/READMEpl.md b/READMEpl.md new file mode 100644 index 00000000..ce65d545 --- /dev/null +++ b/READMEpl.md @@ -0,0 +1,94 @@ +[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Rating&style=flat&logo=google)](https://chrome.google.com/webstore/detail/youtube-dislike-button/gebbhagfogifgggkldgodflihgfeippi/) +[![Chrome Web Store Users](https://img.shields.io/chrome-web-store/users/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Users&style=flat&logo=google)](https://chrome.google.com/webstore/detail/youtube-dislike-button/gebbhagfogifgggkldgodflihgfeippi/) +[![Mozilla rating](https://img.shields.io/amo/stars/return-youtube-dislikes?label=Firefox%20Rating&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) +[![Mozilla downloads](https://img.shields.io/amo/users/return-youtube-dislikes?label=Firefox%20Users&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) +[![Commit rate](https://img.shields.io/github/commit-activity/m/Anarios/return-youtube-dislike?label=Commits&style=flat)](https://github.com/Anarios/return-youtube-dislike/commits/main) +[![Issues](https://img.shields.io/github/issues/Anarios/return-youtube-dislike?style=flat&label=Issues)](https://github.com/Anarios/return-youtube-dislike/issues) +[![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) +[![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) + +Read this in other languages: [English](README.md), [русский](READMEru.md), [Español](READMEes.md), [Nederlands](READMEnl.md), [Français](READMEfr.md), [日本語](READMEja.md), [Türkçe](READMEtr.md), [українська](READMEuk.md), [Deutsch](READMEde.md) + +# Return YouTube Dislike + +

+ Return YouTube Dislike to otwarte rozszerzenie, które przywraca licznik łapek w dół na YouTube.
+ Dostępne jako rozszerzenie dla Chrome i Firefox.
+ Dostępne także dla innych przeglądarek jako JS UserScript.

+ +

+ +## Historia + +Dnia 10 listopada 2021, Google [ogłosiło](https://blog.youtube/news-and-events/update-to-youtube/), że licznik łapek w dół na YouTube zostanie usunięty. + +Dodatkowo, pole `dislike` w API YouTube zostało [usunięte](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts) 13 grudnia 2021, usuwając przy tym jakąkolwiek możliwość oceny jakości filmu przed obejrzeniem. + +## Co to robi + +Wraz z usunięciem statystyk łapek w dół z YouTube API, nasz backend przełączył się na kombinację scrape-owanych statystyk łapek w dół i szacunków ekstrapolowanych z danych użytkowników rozszerzenia. + +[FAQ](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQ.md) + +## Dlaczego to ma znaczenie + +Można o tym przeczytać na naszej stronie: [returnyoutubedislike.com](https://www.returnyoutubedislike.com/) + +## Dokumentacja API + +Używanie tego otwartego API jest dozwolone z następującymi ograniczeniami: + +- **Przypisanie**: Ten projekt powinien być jawnie przypisany z linkiem do [returnyoutubedislike.com](https://returnyoutubedislike.com/). +- **Ograniczenie żądań**: Istnieją ograniczenia żądań do 100 na minutę i 10 000 na dzień. Przekroczenie zwróci kod _429_, mówiący aplikacji aby przyhamowała. + +API jest dostępne przez poniższe bazowe URL: +https://returnyoutubedislikeapi.com + +Lista dostępnych endpointów jest dostępna tutaj: +https://returnyoutubedislikeapi.com/swagger/index.html + +### Pobierz głosy + +Przykład otrzymywania głosów z danego ID filmu YouTube: +`/votes?videoId=kxOuG8jMIgI` + +```json +{ + "id": "kxOuG8jMIgI", + "dateCreated": "2021-12-20T12:25:54.418014Z", + "likes": 27326, + "dislikes": 498153, + "rating": 1.212014408444885, + "viewCount": 3149885, + "deleted": false +} +``` + +Nieistniejący ID filmu zwróci _404_ "Not Found". +Niepoprawnie sformatowany ID filmu zwróci _400_ "Bad Request". + + + +## Współtworzenie + +Prosimy przeczytać [przewodnik współtworzenia](https://github.com/Anarios/return-youtube-dislike/blob/main/CONTRIBUTING.md). + +## Wesprzyj ten projekt! + +Możesz wesprzeć ten projekt dotacjami poniżej: + +[Wesprzyj](https://returnyoutubedislike.com/donate) + +## Sponsorzy + +[Piepacker](https://piepacker.com) + +[Seed4.Me VPN](https://www.seed4.me/users/register?gift=ReturnYoutubeDislike) + +[PocketTube](https://yousub.info/?utm_source=returnyoutubedislike) + +[Become our sponsor](https://www.patreon.com/join/returnyoutubedislike/checkout?rid=8008601) diff --git a/READMEpt_BR.md b/READMEpt_BR.md new file mode 100644 index 00000000..b558ac0e --- /dev/null +++ b/READMEpt_BR.md @@ -0,0 +1,94 @@ +[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Rating&style=flat&logo=google)](https://chrome.google.com/webstore/detail/youtube-dislike-button/gebbhagfogifgggkldgodflihgfeippi/) +[![Chrome Web Store Users](https://img.shields.io/chrome-web-store/users/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Users&style=flat&logo=google)](https://chrome.google.com/webstore/detail/youtube-dislike-button/gebbhagfogifgggkldgodflihgfeippi/) +[![Mozilla rating](https://img.shields.io/amo/stars/return-youtube-dislikes?label=Firefox%20Rating&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) +[![Mozilla downloads](https://img.shields.io/amo/users/return-youtube-dislikes?label=Firefox%20Users&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) +[![Commit rate](https://img.shields.io/github/commit-activity/m/Anarios/return-youtube-dislike?label=Commits&style=flat)](https://github.com/Anarios/return-youtube-dislike/commits/main) +[![Issues](https://img.shields.io/github/issues/Anarios/return-youtube-dislike?style=flat&label=Issues)](https://github.com/Anarios/return-youtube-dislike/issues) +[![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) +[![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) + +Leia isso em outros idiomas: [русский](READMEru.md), [Español](READMEes.md), [Nederlands](READMEnl.md), [Français](READMEfr.md), [日本語](READMEja.md), [Türkçe](READMEtr.md), [українська](READMEuk.md), [Deutsch](READMEde.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md), [中文](READMEcn.md), [Polski](READMEpl.md) ou [English (Para Melhor precisão!)](README.md) + + +# Return YouTube Dislike + + +

+ Return YouTube Dislike é uma extensão de codigo aberto que retorna com o contador de Deslike do Youtube. Agora está disponivel apenas para os proprietarios dos Canais
+ Disponivel para Chrome e Firefox como uma extensão Web.
+ e também disponivel para outros navegadores como um JS UserScript.

+ +

+ +## Nossa Historia + +Em 10 de novembro de 2021 a Google [Anuciou](https://blog.youtube/news-and-events/update-to-youtube/) que o contador de Deslikes do Youtube seria removido. + +Additionally, the `dislike` field in the YouTube API was [removed](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts) on December 13th, 2021, removing any ability to judge the quality of content before watching. + +## Como isso funciona + +With the removal of dislike stats from the YouTube API, our backend switched to using a combination of scraped dislike stats, estimates extrapolated from extension user data. + +[FAQ](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQ.md) + +## Why it Matters + +Você pode aprender mais no nosso site Aqui: [returnyoutubedislike.com](https://www.returnyoutubedislike.com/) + +## Documentação da API + +Third-party use of this open API is allowed with the following restrictions: + +- **Attribution**: This project should be clearly attributed with a link to [returnyoutubedislike.com](https://returnyoutubedislike.com/). +- **Rate Limiting**: There are per client rate limits in place of 100 per minute and 10,000 per day. This will return a _429_ status code indicating that your application should back off. + +The API is accessible over the following base URL: +https://returnyoutubedislikeapi.com + +List of available endpoints is available here: +https://returnyoutubedislikeapi.com/swagger/index.html + +### Obtendo votos + +Exemplo para obter os votos pelo Youtube Video ID: +`/votes?videoId=kxOuG8jMIgI` + +```json +{ + "id": "kxOuG8jMIgI", + "dateCreated": "2021-12-20T12:25:54.418014Z", + "likes": 27326, + "dislikes": 498153, + "rating": 1.212014408444885, + "viewCount": 3149885, + "deleted": false +} +``` + +Nenhum youtube id exstente irá retornar o codigo de status _404_ "Nada encontrado". +Wrong formed YouTube ID will return _400_ "Bad Request". + + + +## Contribuindo + +Por favor leia o [Guia de contribuição](https://github.com/Anarios/return-youtube-dislike/blob/main/CONTRIBUTINGpt_BR.md). + +## Ajude nosso projeto! + +Você pode ajuda esse projeto doando para nos no link abaixo: + +[Doar](https://returnyoutubedislike.com/donate) + +## Patrocinados + +[Seed4.Me VPN](https://www.seed4.me/users/register?gift=ReturnYoutubeDislike) + +[Torne-se nosso Patrocinador](https://www.patreon.com/join/returnyoutubedislike/checkout?rid=8008601) + + \ No newline at end of file diff --git a/READMEru.md b/READMEru.md index 1609f37d..163e5986 100644 --- a/READMEru.md +++ b/READMEru.md @@ -7,14 +7,14 @@ [![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) [![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) -Прочитать на других языках: [English](README.md), [Español](READMEes.md), [Français](READMEfr.md), [日本語](READMEja.md), [Türkçe](READMEtr.md) +Прочитать на других языках: [English](README.md), [Español](READMEes.md), [Nederlands](READMEnl.md), [Français](READMEfr.md), [日本語](READMEja.md), [Türkçe](READMEtr.md), [українська](READMEuk.md), [Deutsch](READMEde.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md), [中文](READMEcn.md), [Polski](READMEpl.md) # Return YouTube Dislike

- Return YouTube Dislike - это расширение с открытым исходным кодом, которое возвращает счётчик отметок «Не нравится» на YouTube.
+ Return YouTube Dislike — это расширение с открытым исходным кодом, которое возвращает счётчик отметок «Не нравится» на YouTube.
Доступно для Chrome и Firefox в качестве веб-расширения.
- Также доступен для других браузеров в виде пользовательского скрипта JS.

+ Также доступен для других браузеров в виде пользовательского скрипта.

@@ -22,13 +22,13 @@ 10 ноября 2021 года Google [объявили](https://blog.youtube/news-and-events/update-to-youtube/), что счётчик «Не нравится» на YouTube будет удален. -Кроме того, поле отметок `dislike` в API YouTube было [удалено]](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts) 13 декабря 2021 года, удалив любую возможность судить о качестве контента перед просмотром. +Кроме того, поле отметок `dislike` в API YouTube было [удалено](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts) 13 декабря 2021 года, убрав любую возможность судить о качестве контента перед просмотром. ## Как оно работает -С удалением статистики отметок из API YouTube наш сервер переключился на использование комбинации собранной статистики отметок «Не нравится», оценок, экстраполированных из пользовательских данных расширения. +С удалением статистики отметок из API YouTube наш сервер переключился на использование комбинации собранной статистики отметок «Не нравится» и оценок, экстраполированных из пользовательских данных расширения. -[ЧаВО](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQru.md) +[FAQ](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQru.md) ## Почему это важно @@ -39,7 +39,7 @@ Стороннее использование этого открытого API разрешено со следующими ограничениями: - **Атрибуция**: Этот проект должен быть чётко описан со ссылкой на [returnyoutubedislike.com](https://returnyoutubedislike.com/). -- **Ограничение**: Существуют ограничения скорости для каждого клиента - 100 в минуту и 10 000 в день. Это выдаст код ошибки _429_, указывающий на то, что ваше приложение должно быть отключено. +- **Ограничение**: Существуют ограничения скорости для каждого клиента — 100 в минуту и 10 000 в день. Это выдаст код ошибки _429_, указывающий на то, что ваше приложение должно быть отключено. API доступен по следующему основному URL-адресу: https://returnyoutubedislikeapi.com @@ -49,7 +49,7 @@ https://returnyoutubedislikeapi.com/swagger/index.html ### Получить голоса -Пример получения голосов за заданный идентификатор видео на YouTube: +Пример получения голосов для заданного идентификатора видео на YouTube: `/votes?videoId=kxOuG8jMIgI` ```json @@ -64,8 +64,8 @@ https://returnyoutubedislikeapi.com/swagger/index.html } ``` -Неверный идентификатор YouTube выдаст код ошибки _404_ "Не найдено". -Неправильно отформатированный идентификатор YouTube выдаст код ошибки _400_ "Неверный запрос". +Неверный идентификатор YouTube выдаст код ошибки _404_ «Не найдено». +Неправильно отформатированный идентификатор YouTube выдаст код ошибки _400_ «Неверный запрос». + +Den 10 november 2021 [meddelade Google](https://blog.youtube/news-and-events/update-to-youtube/) att YouTubes dislikes skulle tas bort från plattformen. + +Dessutom blev `dislike`-fältet i YouTubes API [borttaget](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts) den 13 december 2021, vilket tog bort möjligheten att bedöma innehållets kvalitet innan visning. + +## Vad det gör + +Med borttagandet av dislike-statistiken från YouTubes API, bytte vår backend till att använda en kombination av skrapad dislike-statistik och uppskattningar utifrån data av tilläggsanvändare. + +[FAQ](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQ.md) + +## Varför det är viktigt + +Du kan läsa mer på vår webbplats: [returnyoutubedislike.com](https://www.returnyoutubedislike.com/) + +## API dokumentation + +Tredjepartsanvändning av detta öppna API är tillåtet med följande restriktioner: + +- **Attribution**: Detta projekt ska tydligt tillskrivas med en länk till [returnyoutubedislike.com](https://returnyoutubedislike.com/). +- **Frekvensbegränsning**: Det finns per klient hastighetsbegränsningar på 100 per minut och 10'000 per dag. Detta kommer att returnera en _429_ statuskod som indikerar att din applikation bör backa. + +API:et är tillgängligt på följande bas-URL: +https://returnyoutubedislikeapi.com + +En lista över tillgängliga ändpunkter finns här: +https://returnyoutubedislikeapi.com/swagger/index.html + +### Hämta röster + +Exempel för att hämta röster för en given YouTube-video-ID: +`/votes?videoId=kxOuG8jMIgI` + +```json +{ + "id": "kxOuG8jMIgI", + "dateCreated": "2021-12-20T12:25:54.418014Z", + "likes": 27326, + "dislikes": 498153, + "rating": 1.212014408444885, + "viewCount": 3149885, + "deleted": false +} +``` + +Inga existerande YouTube-ID returnerar statuskoden _404_ "Not Found". +Felaktigt formade YouTube-ID returnerar _400_ "Bad Request". + + + +## Bidra + +Läs gärna [bidragsguiden](https://github.com/Anarios/return-youtube-dislike/blob/main/CONTRIBUTING.md). + +## Stöd detta projekt! + +Du kan stödja detta projekt genom att donera till oss på länken nedan: + +[Donera](https://returnyoutubedislike.com/donate) + +## Sponsorer + +[Piepacker](https://piepacker.com) + +[Seed4.Me VPN](https://www.seed4.me/users/register?gift=ReturnYoutubeDislike) + +[PocketTube](https://yousub.info/?utm_source=returnyoutubedislike) + +[Stöd oss på Patreon](https://www.patreon.com/join/returnyoutubedislike/checkout?rid=8008601) diff --git a/READMEtr.md b/READMEtr.md index 6376d843..7efd24da 100644 --- a/READMEtr.md +++ b/READMEtr.md @@ -3,11 +3,11 @@ [![Mozilla oylaması](https://img.shields.io/amo/stars/return-youtube-dislikes?label=Firefox%20Rating&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) [![Mozilla indirmeleri](https://img.shields.io/amo/users/return-youtube-dislikes?label=Firefox%20Users&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) [![Commit sayısı](https://img.shields.io/github/commit-activity/m/Anarios/return-youtube-dislike?label=Commits&style=flat)](https://github.com/Anarios/return-youtube-dislike/commits/main) -[![Issue'ler](https://img.shields.io/github/issues/Anarios/return-youtube-dislike?style=flat&label=Issues)](https://github.com/Anarios/return-youtube-dislike/issues) +[![Issue'lar](https://img.shields.io/github/issues/Anarios/return-youtube-dislike?style=flat&label=Issues)](https://github.com/Anarios/return-youtube-dislike/issues) [![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) [![Lisans](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) -Bunu diğer dillerde okuyun: [English](README.md), [Español](READMEes.md), [Français](READMEfr.md), [русский](READMEru.md), [日本語](READMEja.md) +Bunu diğer dillerde okuyun: [English](README.md), [русский](READMEru.md), [Español](READMEes.md), [Français](READMEfr.md), [Nederlands](READMEnl.md), [日本語](READMEja.md), [українська](READMEuk.md), [Deutsch](READMEde.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md), [中文](READMEcn.md), [Polski](READMEpl.md) # YouTube Dislike Sayısını Geri Getir @@ -22,13 +22,13 @@ Bunu diğer dillerde okuyun: [English](README.md), [Español](READMEes.md), [Fra 10 Kasım 2021 tarihinde Google, YouTube dislike sayısının kaldırılacağını [duyurdu](https://blog.youtube/news-and-events/update-to-youtube/). -Ek olarak, YouTube API'sindeki "dislike" alanı 13 Aralık 2021 tarihinde [kaldırıldı](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts) ve içeriğin kalitesini izlemeden önce yargılayabilme olanağı ortadan kaldırıldı. +Ek olarak, YouTube API'sindeki `dislike` alanı 13 Aralık 2021 tarihinde [kaldırıldı](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts) ve içeriğin kalitesini izlemeden önce yargılayabilme olanağı ortadan kaldırıldı. ## Ne İşe Yarar YouTube API'sinden dislike istatistiklerinin kaldırılmasıyla, backend'imiz, uzantı kullanıcı verilerinden tahmin edilen, toplanmış dislike istatistiklerinin bir birleşimini kullanmaya başladı. -[SSS](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQ.md) +[SSS](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQtr.md) ## Neden Önemlidir @@ -39,12 +39,12 @@ Sitemizden daha fazla bilgi edinebilirsiniz: [returnyoutubedislike.com](https:// Bu açık API'nin üçüncü taraflarca kullanımına, aşağıdaki kısıtlamalarla izin verilir: - **Atfetme**: Bu proje, açık bir biçimde [returnyoutubedislike.com](https://returnyoutubedislike.com/) adresine yönlendirilmelidir. -- **Hız Sınırlaması**: Kullanıcı başına dakikada 100 ve günde 10.000 hız sınırlaması vardır. Bu, uygulamanızın geri çekilmesi gerektiğini belirten 429 durum kodunu döndürür +- **Hız Sınırlaması**: Kullanıcı başına dakikada 100 ve günde 10.000 hız sınırlaması vardır. Bu, uygulamanızın geri çekilmesi gerektiğini belirten _429_ durum kodunu döndürür. API'ye aşağıdaki temel URL üzerinden erişilebilir: https://returnyoutubedislikeapi.com -Kullanılabilir endpoint'lerin listesi burada mevcuttur: +Kullanılabilir endpoint'lerin bir listesi burada mevcuttur: https://returnyoutubedislikeapi.com/swagger/index.html ### Oylamaları Elde Etme @@ -75,13 +75,13 @@ Tüm belgelemeleri sitemizden inceleyebilirsiniz. ## Katkıda Bulunma -Lütfen [katkı kılavuzu](https://github.com/Anarios/return-youtube-dislike/blob/main/CONTRIBUTING.md)nu okuyun. +Lütfen [katkı kılavuzu](https://github.com/Anarios/return-youtube-dislike/blob/main/CONTRIBUTINGtr.md)nu okuyun. ## Bu Projeyi Destekle! Aşağıdaki bağlantıdan bize bağış yapabilir ve bu projeye destek olabilirsiniz: -[Bağış Yapın](https://returnyoutubedislike.com/donate) +[Bağış Yap](https://returnyoutubedislike.com/donate) ## Sponsorlar diff --git a/READMEuk.md b/READMEuk.md new file mode 100644 index 00000000..cefdd145 --- /dev/null +++ b/READMEuk.md @@ -0,0 +1,94 @@ +[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Rating&style=flat&logo=google)](https://chrome.google.com/webstore/detail/youtube-dislike-button/gebbhagfogifgggkldgodflihgfeippi/) +[![Chrome Web Store Users](https://img.shields.io/chrome-web-store/users/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Users&style=flat&logo=google)](https://chrome.google.com/webstore/detail/youtube-dislike-button/gebbhagfogifgggkldgodflihgfeippi/) +[![Mozilla rating](https://img.shields.io/amo/stars/return-youtube-dislikes?label=Firefox%20Rating&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) +[![Mozilla downloads](https://img.shields.io/amo/users/return-youtube-dislikes?label=Firefox%20Users&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) +[![Commit rate](https://img.shields.io/github/commit-activity/m/Anarios/return-youtube-dislike?label=Commits&style=flat)](https://github.com/Anarios/return-youtube-dislike/commits/main) +[![Issues](https://img.shields.io/github/issues/Anarios/return-youtube-dislike?style=flat&label=Issues)](https://github.com/Anarios/return-youtube-dislike/issues) +[![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) +[![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) + +Read this in other languages: [English](README.md), [Español](READMEes.md), [русский](READMEru.md), [Français](READMEfr.md), [日本語](READMEja.md), [Türkçe](READMEtr.md), [Deutsch](READMEde.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md), [中文](READMEcn.md), [Polski](READMEpl.md) + +# Return YouTube Dislike + +

+ Return YouTube Dislike - це розширення з відкритим вихідним кодом, яке повертає лічильник відміток «Не подобається» на YouTube.
+ Доступно для Chrome та Firefox як веброзширення.
+ Також доступно для інших браузерів як JS UserScript.

+ +

+ +## Історія + +10 листопада 2021 року Google [оголосили](https://blog.youtube/news-and-events/update-to-youtube/), що лічильник відміток «Не подобається» на YouTube буде видалено. + +Крім того, поле позначок `dislike` у YouTube API було [видалено](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts) 13 грудня 2021 року, прибравши єдину можливість оцінити якість вмісту перед переглядом. + +## Як це працює + +Після видаленням статистики відміток з API YouTube наш сервер перейшов на використання комбінації заархівованих статистичних даних відміток «Не подобається» екстрапольованих із даними користувачів розширення. + +[ЧаПи](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQuk.md) + +## Чому це важливо + +Ви можете дізнатися більше на нашому вебсайті: [returnyoutubedislike.com](https://www.returnyoutubedislike.com/) + +## Документація API + +Використання цього відкритого API сторонніми особами дозволено з наступними обмеженнями: + +- **Атрибуція**: Цей проєкт має бути чітко описано, використовуючи посилання на [returnyoutubedislike.com](https://returnyoutubedislike.com/). +- **Обмеження**: Існують обмеження на швидкісті для кожного клієнта - 100 за хвилину і 10 000 за день. Це видасть код помилки 429, який вказує на те, що вашому додатку слід завершити роботу. + +API доступно за наступною URL-адресою: +https://returnyoutubedislikeapi.com + +Перелік доступних «ендпоінтів» можна переглянути тут: +https://returnyoutubedislikeapi.com/swagger/index.html + +### Отримати оцінки + +Приклад отримання оцінок відео на YouTube за ID: +`/votes?videoId=kxOuG8jMIgI` + +```json +{ + "id": "kxOuG8jMIgI", + "dateCreated": "2021-12-20T12:25:54.418014Z", + "likes": 27326, + "dislikes": 498153, + "rating": 1.212014408444885, + "viewCount": 3149885, + "deleted": false +} +``` + +Недійсний YouTube ID видасть код помилки 404 "Not Found". +YouTube ID у невірному форматі видасть код помилки 400 "Bad Request". + + + +## Взяти участь у розробці + +Будь ласка, ознайомтеся із [посібником внеску в проєкт](https://github.com/Anarios/return-youtube-dislike/blob/main/CONTRIBUTINGuk.md). + +## Підтримайте цей проєкт! + +Ви можете підтримати цей проєкт пожертвою за посиланням нижче: + +[Підтримати](https://returnyoutubedislike.com/donate) + +## Спонсори + +[Piepacker](https://piepacker.com) + +[Seed4.Me VPN](https://www.seed4.me/users/register?gift=ReturnYoutubeDislike) + +[PocketTube](https://yousub.info/?utm_source=returnyoutubedislike) + +[Станьте нашим спонсором](https://www.patreon.com/join/returnyoutubedislike/checkout?rid=8008601) diff --git a/Website/README.md b/Website/README.md index 05e18612..9c8dd285 100644 --- a/Website/README.md +++ b/Website/README.md @@ -1,3 +1,5 @@ +Read this in other languages: [Nederlands](READMEnl.md), [Türkçe](READMEtr.md), [Deutsch](READMEde.md) + # return-youtube-dislike-site ## Build Setup diff --git a/Website/READMEde.md b/Website/READMEde.md new file mode 100644 index 00000000..bc7f5e8b --- /dev/null +++ b/Website/READMEde.md @@ -0,0 +1,89 @@ +Read this in other languages: [English](README.md), [Nederlands](READMEnl.md), [Türkçe](READMEtr.md) + +# return-youtube-dislike-site + +## Build Setup + +```bash +# Abhängigkeiten installieren +$ npm install + +# Mit Hot Reload unter localhost:3000 bereitstellen +$ npm run dev + +# Linten Ihrer Änderungen +$ npm run lint + +# Für die Produktion erstellen und Server starten +$ npm run build +$ npm run start + +# Statisches Projekt generieren +$ npm run generate +``` + +Für eine ausführliche Erklärung, wie die Dinge funktionieren, lesen Sie die [Dokumentation](https://nuxtjs.org). + +## Empfohlene VSCode-Einrichtung + +- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) `ext install dbaeumer.vscode-eslint` +- [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) `ext install esbenp.prettier-vscode` +- [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur) + +> `Strg(Cmd)` + `Shift` + `P` > Einstellungen öffnen (JSON) + +``` +"editor.formatOnSave": true, +"editor.codeActionsOnSave": { + "source.fixAll.eslint": true +} +"vetur.validation.template": false, +``` + +## Besondere Verzeichnisse + +Sie können die folgenden zusätzlichen Verzeichnisse erstellen, von denen einige spezielle Verhaltensweisen haben. Nur `pages` ist erforderlich; Sie können sie löschen, wenn Sie ihre Funktionalität nicht verwenden möchten. + +### `assets` + +Das Verzeichnis assets enthält Ihre nicht kompilierten Assets wie Stylus- oder Sass-Dateien, Bilder oder Schriftarten. + +Weitere Informationen zur Verwendung dieses Verzeichnisses finden Sie in [der Dokumentation](https://nuxtjs.org/docs/2.x/directory-structure/assets). + +### `components` + +Das Verzeichnis components enthält Ihre Vue.js-Komponenten. Komponenten bilden die verschiedenen Teile Ihrer Seite und können in Ihren Seiten, Layouts und sogar anderen Komponenten wiederverwendet und importiert werden. + +Weitere Informationen zur Verwendung dieses Verzeichnisses finden Sie in [der Dokumentation](https://nuxtjs.org/docs/2.x/directory-structure/components). + +### `layouts` + +Layouts sind eine große Hilfe, wenn Sie das Aussehen und Verhalten Ihrer Nuxt-App ändern möchten, ob Sie eine Seitenleiste einbeziehen oder unterschiedliche Layouts für mobile und Desktop haben möchten. + +Weitere Informationen zur Verwendung dieses Verzeichnisses finden Sie in [der Dokumentation](https://nuxtjs.org/docs/2.x/directory-structure/layouts). + +### `pages` + +Dieses Verzeichnis enthält Ihre Anwendungsansichten und Routen. Nuxt liest alle `*.vue`-Dateien in diesem Verzeichnis und richtet automatisch Vue Router ein. + +Weitere Informationen zur Verwendung dieses Verzeichnisses finden Sie in [der Dokumentation](https://nuxtjs.org/docs/2.x/get-started/routing). + +### `plugins` + +Das Verzeichnis plugins enthält JavaScript-Plugins, die Sie ausführen möchten, bevor Sie die Root-Vue.js-Anwendung instanziieren. Hier fügen Sie Vue-Plugins hinzu und injizieren Funktionen oder Konstanten. Jedes Mal, wenn Sie `Vue.use()` verwenden möchten, sollten Sie eine Datei in `plugins/` erstellen und ihren Pfad zu Plugins in `nuxt.config.js` hinzufügen. + +Weitere Informationen zur Verwendung dieses Verzeichnisses finden Sie in [der Dokumentation](https://nuxtjs.org/docs/2.x/directory-structure/plugins). + +### `static` + +Dieses Verzeichnis enthält Ihre statischen Dateien. Jede Datei in diesem Verzeichnis ist auf `/` abgebildet. + +Beispiel: `/static/robots.txt` ist als `/robots.txt` abgebildet. + +Weitere Informationen zur Verwendung dieses Verzeichnisses finden Sie in [der Dokumentation](https://nuxtjs.org/docs/2.x/directory-structure/static). + +### `store` + +Dieses Verzeichnis enthält Ihre Vuex-Store-Dateien. Das Erstellen einer Datei in diesem Verzeichnis aktiviert automatisch Vuex. + +Weitere Informationen zur Verwendung dieses Verzeichnisses finden Sie in [der Dokumentation](https://nuxtjs.org/docs/2.x/directory-structure/store). diff --git a/Website/READMEnl.md b/Website/READMEnl.md new file mode 100644 index 00000000..3fb53958 --- /dev/null +++ b/Website/READMEnl.md @@ -0,0 +1,89 @@ +Read this in other languages: [English](README.md), [Türkçe](READMEtr.md), [Deutsch](READMEde.md) + +# return-youtube-dislike-site + +## Opstelling bouwen + +```bash +# install dependencies +$ npm install + +# serve with hot reload at localhost:3000 +$ npm run dev + +# lint your changes +$ npm run lint + +# build for production and launch server +$ npm run build +$ npm run start + +# generate static project +$ npm run generate +``` + +Voor gedetailleerde uitleg over hoe dingen werken, bekijk de [documentatie](https://nuxtjs.org). + +## Aanbevolen VSCode-instellingen + +- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) `ext install dbaeumer.vscode-eslint` +- [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) `ext install esbenp.prettier-vscode` +- [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur) + +> `Ctrl(Cmd)` + `Shift` + `P` > Instellingen Openen (JSON) + +``` +"editor.formatOnSave": true, +"editor.codeActionsOnSave": { + "source.fixAll.eslint": true +} +"vetur.validation.template": false, +``` + +## Speciale mappen + +U kunt de volgende extra mappen maken, waarvan sommige speciaal gedrag vertonen. Alleen `pagina's` zijn vereist; u kunt ze verwijderen als u hun functionaliteit niet wilt gebruiken. + +### `assets` + +De assets-map bevat uw niet-gecompileerde activa zoals Stylus- of Sass-bestanden, afbeeldingen of lettertypen. + +Meer informatie over het gebruik van deze directory in [de documentatie](https://nuxtjs.org/docs/2.x/directory-structure/assets). + +### `componenten` + +De componentenmap bevat uw Vue.js-componenten. Componenten vormen de verschillende delen van uw pagina en kunnen opnieuw worden gebruikt en geïmporteerd in uw pagina's, lay-outs en zelfs andere componenten. + +Meer informatie over het gebruik van deze directory in [de documentatie](https://nuxtjs.org/docs/2.x/directory-structure/components). + +### `lay-outs` + +Lay-outs zijn een grote hulp wanneer je het uiterlijk van je Nuxt-app wilt veranderen, of je nu een zijbalk wilt opnemen of verschillende lay-outs voor mobiel en desktop wilt hebben. + +Meer informatie over het gebruik van deze directory in [de documentatie](https://nuxtjs.org/docs/2.x/directory-structure/layouts). + +### `pagina's` + +Deze map bevat uw toepassingsweergaven en routes. Nuxt zal alle `*.vue` bestanden in deze map lezen en Vue Router automatisch instellen. + +Meer informatie over het gebruik van deze directory in [de documentatie](https://nuxtjs.org/docs/2.x/get-started/routing). + +### `plugins` + +TDe directory met plug-ins bevat JavaScript-plug-ins die u wilt uitvoeren voordat u de roottoepassing Vue.js start. Dit is de plek om Vue-plug-ins toe te voegen en om functies of constanten te injecteren. Elke keer dat je `Vue.use()` moet gebruiken, moet je een bestand maken in `plugins/` en het pad toevoegen aan plug-ins in `nuxt.config.js`. + +Meer informatie over het gebruik van deze directory in [de documentatie](https://nuxtjs.org/docs/2.x/directory-structure/plugins). + +### `static` + +Tzijn directory bevat uw statische bestanden. Elk bestand in deze map is toegewezen aan `/`. + +Voorbeeld: `/static/robots.txt` wordt toegewezen als `/robots.txt`. + +Meer informatie over het gebruik van deze directory in [de documentatie](https://nuxtjs.org/docs/2.x/directory-structure/static). + +### `store` + +Deze map bevat uw Vuex-winkelbestanden. Door een bestand in deze map aan te maken, wordt Vuex automatisch geactiveerd. + +Meer informatie over het gebruik van deze directory in [de documentatie](https://nuxtjs.org/docs/2.x/directory-structure/store). diff --git a/Website/READMEtr.md b/Website/READMEtr.md new file mode 100644 index 00000000..9b108637 --- /dev/null +++ b/Website/READMEtr.md @@ -0,0 +1,89 @@ +Read this in other languages: [English](README.md), [Nederlands](READMEnl.md), [Deutsch](READMEde.md) + +# youtube-dislike-sayısını-geri-getir-site + +## Yapı Kurulumu + +```bash +# bağımlılıkları yükle +$ npm install + +# localhost:3000'de sıcak yeniden yükleme ile çalıştır +$ npm run dev + +# değişikliklerine lint'i uygula +$ npm run lint + +# üretim için yapıyı oluştur ve sunucuyu başlat +$ npm run build +$ npm run start + +# statik proje oluştur +$ npm run generate +``` + +İşlerin nasıl yürüdüğüyle ilgili daha fazla bilgi için [belgeleme](https://nuxtjs.org)ye göz atın. + +## Önerilen VSCode Kurulumu + +- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) `ext install dbaeumer.vscode-eslint` +- [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) `ext install esbenp.prettier-vscode` +- [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur) + +> `Ctrl(Cmd)` + `Shift` + `P` > Varsayılan Ayarları Aç (JSON) + +``` +"editor.formatOnSave": true, +"editor.codeActionsOnSave": { + "source.fixAll.eslint": true +} +"vetur.validation.template": false, +``` + +## Özel Dizinler + +You can create the following extra directories, some of which have special behaviors. Only `pages` is required; you can delete them if you don't want to use their functionality. + +### `assets` + +Assets dizini, Stylus veya Sass dosyaları, resimler veya yazı tipleri gibi derlenmemiş varlıklarınızı içerir. + +Bu dizinin kullanımı ile ilgili daha fazla bilgi için [belgeleme](https://nuxtjs.org/docs/2.x/directory-structure/assets)ye göz atın. + +### `components` + +Components dizini, Vue.js bileşenlerinizi içerir. Component'ler, sayfanızın farklı bölümlerini oluşturur ve yeniden kullanılabilir. Ayrıca sayfalarınıza, mizanpajlarınıza ve hatta diğer component'lerinize de aktarılabilir. + +Bu dizinin kullanımı ile ilgili daha fazla bilgi için [belgeleme](https://nuxtjs.org/docs/2.x/directory-structure/components)ye göz atın. + +### `layouts` + +Layouts dizini, Nuxt uygulamanızın görünümünü ve verdiği hissi değiştirmek istediğinizde, bir kenar çubuğu eklemek istediğinizde veya mobil ve masaüstü için farklı düzenlere sahip olmak istediğinizde çok yardımcı olabilir. + +Bu dizinin kullanımı ile ilgili daha fazla bilgi için [belgeleme](https://nuxtjs.org/docs/2.x/directory-structure/layouts)ye göz atın. + +### `pages` + +Bu dizin, uygulama görünümlerinizi ve rotalarınızı içerir. Nuxt, bu dizindeki tüm `*.vue` dosyalarını okuyacak ve Vue Router'ı otomatik olarak kuracaktır. + +Bu dizinin kullanımı ile ilgili daha fazla bilgi için [belgeleme](https://nuxtjs.org/docs/2.x/get-started/routing)ye göz atın. + +### `plugins` + +Plugins dizini, kök Vue.js Uygulamasını başlatmadan önce çalıştırmak istediğiniz JavaScript eklentilerini içerir. Burası Vue eklentileri eklemek ve işlevler veya sabitler enjekte etmek için kullanılan yerdir. `Vue.use()`u her kullanmanız gerektiğinde, `plugins/` içinde bir dosya oluşturmalı ve yolunu `nuxt.config.js` içinde eklentilere eklemelisiniz. + +Bu dizinin kullanımı ile ilgili daha fazla bilgi için [belgeleme](https://nuxtjs.org/docs/2.x/directory-structure/plugins)ye göz atın. + +### `static` + +Bu dizin statik dosyalarınızı içerir. Bu dizindeki her dosya `/` ile eşlenir. + +Örnek: `/static/robots.txt`, `/robots.txt` olarak eşlenir. + +Bu dizinin kullanımı ile ilgili daha fazla bilgi için [belgeleme](https://nuxtjs.org/docs/2.x/directory-structure/static)ye göz atın. + +### `store` + +Bu dizin, Vuex mağaza dosyalarınızı içerir. Bu dizinde bir dosya oluşturmak, Vuex'i otomatik olarak etkinleştirecektir. + +Bu dizinin kullanımı ile ilgili daha fazla bilgi için [belgeleme](https://nuxtjs.org/docs/2.x/directory-structure/store)ye göz atın. diff --git a/Website/_locales/de.ts b/Website/_locales/de.ts new file mode 100644 index 00000000..7a27b832 --- /dev/null +++ b/Website/_locales/de.ts @@ -0,0 +1,104 @@ +import { en } from "vuetify/src/locale"; + +export default { + ...en, + home: { + name: "Startseite", + title: "Rückgabe YouTube-Dislike", + subtitle: "Browser-Erweiterung und eine API, die Ihnen Dislikes auf YouTube zeigt", + ukraine: "Unterstützung für die Ukraine", + sponsors: "Sponsoren", + }, + install: { + name: "Installieren", + title: "Wählen Sie Ihre Plattform aus", + subtitle: "Verfügbar für Firefox und alle Chromium-Browser", + title2: "Andere Plattformen", + subtitle2: "Wenn Ihr Browser noch nicht unterstützt wird, versuchen Sie dieses Benutzerskript", + title3: "Implementierungen von Drittanbietern", + subtitle3: "Keine Haftung unsererseits, Nutzung auf eigene Gefahr", + }, + api: { + name: "API", + title: "Willkommen bei den offiziellen RYD-Dokumenten!", + subtitle: "Um loszulegen, wählen Sie einen Abschnitt aus dem Menü aus.", + rights: { + title: "Nutzungsrechte", + subtitle: "Die Nutzung dieser Open-API durch Dritte ist unter folgenden Einschränkungen gestattet:", + bullet1: "Zuschreibung: ", + bullet1text: "Dieses Projekt sollte deutlich mit einem Link zu diesem Repository oder einem Link zu returnyoutubedislike.com zugeschrieben werden.", + bullet2: "Rate-Begrenzung: ", + bullet2text: "Es gelten pro Client Rate-Limits von 100 pro Minute und 10.000 pro Tag. Dies gibt einen Statuscode 429 zurück, der anzeigt, dass Ihre Anwendung zurücktreten sollte.", + }, + url: { + title: "URL-Informationen", + subtitle: "Die API ist über die folgende Basis-URL erreichbar: ", + }, + endpoints: { + title: "Verfügbare Endpunkte", + subtitle: "Liste der verfügbaren Endpunkte ist hier verfügbar: ", + }, + fetching: { + title: "Grundlegendes Fetching-Tutorial", + subtitle: "Beispiel zum Abrufen von Stimmen anhand einer bestimmten YouTube-Video-ID: ", + title2: "Beispielanfrage: ", + url: "Anforderungs-URL: ", + method: "Anforderungsmethode: ", + headers: "Header: ", + response: "Antwort: ", + error1: 'Eine ungültige YouTube-ID liefert den Statuscode 404 "Not Found"', + error2: 'Eine falsch formatierte YouTube-ID liefert 400 "Bad Request"', + }, + }, + help: { + name: "Hilfe", + title: "Fehlerbehebung", + bullet1: "Stellen Sie sicher, dass Sie die neueste Version der Erweiterung installiert haben, ", + bullet11: "jetzt gerade", + bullet2: "Versuchen Sie, die Erweiterung zu entfernen und erneut zu installieren, und starten Sie dann den Browser neu (alle aktiven Fenster, nicht nur ein Tab)", + bullet3: "Stellen Sie sicher, dass dieser Link geöffnet wird: ", + bullet31: "Sie sollten einfachen Text sehen: ", + bullet4: "Wenn nichts davon hilft - melden Sie Ihr Problem in", + bullet41: "in unserem", + bullet4a: "Teilen Sie uns Ihr Betriebssystem, den Browsernamen und die Browserversion mit", + bullet4b: "Machen Sie einen Screenshot von der Seite mit dem Problem (z. B. Youtube-Videoseite) mit der geöffneten Konsole (drücken Sie ", + bullet4b1: ") - Beispiel-Screenshot unten.", + bullet4c: "Machen Sie einen Screenshot der Erweiterungsseite Ihres Browsers mit der installierten Erweiterung.", + bullet4c1: "Um Erweiterungen anzuzeigen, geben Sie dies in die Adressleiste ein: ", + firefox: "für Firefox", + chrome: "für Chrome, Edge, Brave, Opera und Vivaldi", + }, + faq: { + name: "FAQ", + title: "Häufig gestellte Fragen", + subtitle: "Haben Sie immer noch Fragen? Fühlen Sie sich frei, unserem Discord beizutreten!", + bullet1: "Woher bezieht die Erweiterung ihre Daten?", + bullet1text: "Eine Kombination aus archivierten Daten von vor der Abschaltung der offiziellen YouTube-Dislike-API und extrapoliertem Verhalten der Erweiterungsnutzer.", + bullet2: "Warum wird die Anzahl der Dislikes nicht aktualisiert?", + bullet2text: "Die Dislikes von Videos werden derzeit zwischengespeichert und nicht sehr häufig aktualisiert. Es variiert je nach Popularität eines Videos, kann aber zwischen wenigen Stunden und wenigen Tagen dauern, um aktualisiert zu werden.", + bullet3: "Wie funktioniert das?", + bullet3text: "Die Erweiterung sammelt die Video-ID des Videos, das Sie ansehen, und ruft die Anzahl der Dislikes (und andere Felder wie Aufrufe, Likes usw.) über unsere API ab. Die Erweiterung zeigt dann die Anzahl der Dislikes und das Verhältnis auf der Seite an. Wenn Sie ein Video mögen oder nicht mögen, wird dies erfasst und an die Datenbank gesendet, damit eine genaue Anzahl von Dislikes extrapoliert werden kann.", + bullet4: "Kann ich meine Dislike-Zählung mit Ihnen teilen?", + bullet4text: "Kommt bald. Wir prüfen die Verwendung von Oauth oder einer anderen schreibgeschützten API mit begrenztem Umfang, damit Ersteller ihre Dislike-Zählungen verifiziert teilen können.", + bullet5: "Welche Daten erfassen Sie und wie werden sie behandelt?", + bullet5text: 'Die Erweiterung sammelt nur Daten, die für ihre ordnungsgemäße Funktion unbedingt erforderlich sind, wie z. B. die IP-Adresse oder die ID des von Ihnen angesehenen Videos. Keine Ihrer Daten wird jemals an Dritte verkauft. Wenn Sie mehr darüber erfahren möchten, wie wir Sicherheit und Datenschutz behandeln, lesen Sie unsere
Sicherheits-FAQ.', + bullet6: "Wie funktioniert die API/das Backend?", + bullet6text: "Das Backend verwendet archivierte Daten aus der Zeit, als die YouTube-API noch die Dislike-Zahl zurückgab, die Like/Dislike-Zahl der Erweiterungsnutzer und Extrapolationen. In naher Zukunft werden wir es Content-Erstellern ermöglichen, ihre Dislike-Zahl einfach und sicher einzureichen, und wir werden die archivierten Daten von ArchiveTeam (4,56 Milliarden Videos) in unsere aktuelle Datenbank aufnehmen. Du kannst auch ein Video zum Thema ansehen.", + bullet7: "Warum zeigt die Dislike-Zahl 'DISLIKES DEAKTIVIERT' an?", + bullet7text: "Manchmal kann bei einem kürzlich hochgeladenen Video 'DISLIKES DEAKTIVIERT' angezeigt werden, auch wenn der Ersteller es nicht deaktiviert hat. Das liegt daran, wie wir feststellen, ob Dislikes deaktiviert sind. Es sollte in einigen Stunden verschwinden oder durch Liken oder Disliken des Videos und Aktualisieren der Seite (hoffentlich)." + }, + donate: { + name: "Spenden", + subtitle: "Du kannst unsere Bemühungen zur Aufrechterhaltung eines freien Internets mit einer Spende unterstützen!" + }, + links: { + name: "Links", + title: "Projektlinks", + subtitle: "Links zum Projekt und seinen Entwicklern", + contact: "Kontaktiere mich", + translators: "Übersetzer", + coolProjects: "Coole Projekte", + sponsorBlockDescription: "Überspringt in Videos integrierte Werbung", + filmotDescription: "Suche YouTube-Videos nach Untertiteln" + } +}; diff --git a/Website/_locales/en.ts b/Website/_locales/en.ts index 8cc26f66..31f8d183 100644 --- a/Website/_locales/en.ts +++ b/Website/_locales/en.ts @@ -67,13 +67,13 @@ export default { bullet41: "in our", bullet4a: "Tell us your Operating System, Browser Name and Browser Version", bullet4b: - "Take screenshot of page with problem (i.e. youtube video page) with console open (press ", + "Take a screenshot of the page with the problem (i.e. Youtube video page) with the console open (press ", bullet4b1: ") - example screenshot below.", bullet4c: - "Take screenshot of extensions page of your browser with extension installed.", + "Take a screenshot of the extensions page of your browser with the extension installed.", bullet4c1: "To see extensions put this into address bar: ", firefox: "for Firefox", - chrome: "for Chrome, Edge, Brave, Opera, Vivaldi", + chrome: "for Chrome, Edge, Brave, Opera, and Vivaldi", }, faq: { name: "FAQ", @@ -81,19 +81,19 @@ export default { subtitle: "Still have questions? Feel free to join our Discord!", bullet1: "Where does the extension get its data?", bullet1text: - "A combination of archived data from before the offical YouTube dislike API shut down, and extrapolated extension user behavior.", + "A combination of archived data from before the official YouTube dislike API shut down, and extrapolated extension user behavior.", bullet2: "Why isn't the dislike count updating?", bullet2text: "Right now video dislikes are cached and they aren't updated very frequently. It varies depending on a video's popularity but can take anywhere between a few hours and a few days to update.", bullet3: "How does this work?", bullet3text: - "The extension collects the video ID of the video you are watching, and fetches the dislike (and other fields like views, likes etc) using our API. The extension then displays the dislike count and ratio on the page. If you like or dislike a video, that is recorded and sent to the database so an accurate dislike count can be extrapolated.", + "The extension collects the video ID of the video you are watching, and fetches the number of dislikes (and other fields like views, likes etc) using our API. The extension then displays the dislike count and ratio on the page. If you like or dislike a video, that is recorded and sent to the database so an accurate dislike count can be extrapolated.", bullet4: "Can I share my dislike count with you?", bullet4text: "Coming soon. We are looking into using Oauth or a different read only API with a limited scope so creators can share their dislike counts verifiability.", bullet5: "What data do you collect and how is it treated?", bullet5text: - 'The extension only collects data that is strictly necessary for it to function properly, such as IP address or ID of the video you\'re watching. None of your data will ever be sold to 3rd parties. If you would like to know more about how we handle security and privacy check out our security FAQ.', + 'The extension only collects data that is strictly necessary for it to function properly, such as the IP address or ID of the video you\'re watching. None of your data will ever be sold to 3rd parties. If you would like to know more about how we handle security and privacy check out our security FAQ.', bullet6: "How does the API/Backend work?", bullet6text: "The backend is using archived data from when the youtube api was still returning the dislike count, extension users like/dislike count and extrapolation. In the near future we will be allowing content creators to submit their dislike count easily and safely and we will be adding ArchiveTeam's archived data (4.56 billion videos) into our current database. You can also view a video on the topic.", diff --git a/Website/_locales/fr.ts b/Website/_locales/fr.ts index bbaa533e..e1b44b72 100644 --- a/Website/_locales/fr.ts +++ b/Website/_locales/fr.ts @@ -54,8 +54,9 @@ export default { headers: "En-têtes (headers) : ", response: "Réponse : ", error1: - 'Si aucunne vidéo YouTube à cet ID, il sera retourner le code d\'erreur 404 "Not Found"', - error2: 'Un ID YouTube invilide renverra *400* "Bad Request"', + "Si aucune vidéo YouTube n'a cet ID, le code d'erreur 404 \"Not Found\" sera retourné", + error2: + 'Un ID YouTube invalide renverra le code d\'erreur *400* "Bad Request"', }, }, help: { @@ -123,7 +124,7 @@ export default { subtitle: "Liens vers le projet et ses développeurs", contact: "Contactez-moi", translators: "Traducteurs", - coolProjects: "Projets Cool", + coolProjects: "Projets Cools", sponsorBlockDescription: "Ignorer les publicités intégrées (sponso) dans la vidéo", filmotDescription: "Rechercher des vidéos YouTube par sous-titres", diff --git a/Website/_locales/ja.ts b/Website/_locales/ja.ts index d68c6065..45029660 100644 --- a/Website/_locales/ja.ts +++ b/Website/_locales/ja.ts @@ -1,101 +1,121 @@ -import { en } from 'vuetify/src/locale' +import { ja } from "vuetify/src/locale"; export default { - ...ja, - home: { - name: 'z[', - title: 'Return YouTube Dislike', - subtitle: 'YouTube̒]̕\𕜌uEUg@\API', - ukraine: 'ENCiT|[g', - sponsors: 'X|T[', + ...ja, + home: { + name: "ホーム", + title: "Return YouTube Dislike", + subtitle: "YouTubeの低評価数の表示を復元するブラウザ拡張機能とAPI", + ukraine: "ウクライナをサポート", + sponsors: "スポンサー", + }, + install: { + name: "インストール", + title: "プラットフォームの選択", + subtitle: "FirefoxとすべてのChromiumブラウザに対応しています。", + title2: "その他のプラットフォーム", + subtitle2: + "未対応のブラウザをお使いの場合は、以下のUserScriptをお試しください。", + title3: "サードパーティーによる実装", + subtitle3: + "開発者では責任を負いかねますので、ご自身の判断にてご利用ください。", + }, + api: { + name: "API", + title: "RYD公式ドキュメントへようこそ!", + subtitle: "まず、メニューからセクションを選択してください。", + rights: { + title: "使用権", + subtitle: + "このオープンAPIを第三者が使用することは、以下の制限付きで許可されています:", + bullet1: "属性:", + bullet1text: + "このレポ、もしくは returnyoutubedislike.com へのリンクのどちらかによって、明確に帰属させる必要があります。", + bullet2: "通信量制限:", + bullet2text: + "クライアントごとに、1分あたり100・1日あたり10,000という通信量制限が設けられています。これを超えた場合には、アプリケーションに通信を控えるよう促すステータスコード 429 を返します。", }, - install: { - name: 'CXg[', - title: 'vbgtH[̑I', - subtitle: 'FirefoxƂׂĂChromiumuEUɑΉĂ܂B', - title2: '̑̃vbgtH[', - subtitle2: 'Ή̃uEUg̏ꍇ́AȉUserScriptB', - title3: 'T[hp[eB[ɂ', - subtitle3: 'J҂ł͐ӔC𕉂˂܂̂ŁAg̔fɂĂpB', + url: { + title: "URL情報", + subtitle: "APIへのアクセスは、以下のベースURLから可能です:", }, - api: { - name: 'API', - title: 'RYDhLgւ悤!', - subtitle: '܂Aj[ZNVIĂB, - rights: { - title: 'gp', - subtitle: '̃I[vAPIO҂gp邱Ƃ́Aȉ̐tŋ‚Ă܂F', - bullet1: 'F', - bullet1text: '̃|A returnyoutubedislike.com ւ̃N̂ǂ炩ɂāAmɋAKv܂B', - bullet2: 'ʐMʐF', - bullet2text: 'NCAgƂɁA1100E110,000ƂʐMʐ݂Ă܂B𒴂ꍇɂ́AAvP[VɒʐMT悤Xe[^XR[h 429 Ԃ܂B', - }, - url: { - title: 'URL', - subtitle: 'APIւ̃ANZX́Aȉ̃x[XURL”\łF', - }, - endpoints: { - title: 'p”\ȃGh|Cg', - subtitle: 'p”\ȃGh|Cg̈ꗗ͂ł܂F', - }, - fetching: { - title: '{IȃtFb`̃`[gA', - subtitle: 'ȉYouTube ID]oꍇ̗łF', - title2: 'NGXgF', - url: 'NGXgURLF', - method: 'NGXg@F', - headers: 'wb_[F', - response: 'X|XF', - error1: 'YouTube IDȏꍇAXe[^XR[h 404 "Not Found" Ԃ܂B', - error2: 'YouTube ID̃tH[}bgȂꍇAXe[^XR[h 400 "Bad Request" Ԃ܂B' - }, + endpoints: { + title: "利用可能なエンドポイント", + subtitle: "利用可能なエンドポイントの一覧はこちらでご覧いただけます:", }, - help: { - name: 'wv', - title: 'guV[eBO', - bullet1: 'ŐVo[W̊g@\', - bullet11: 'CXg[Ă邱ƂmFĂB', - bullet2: 'g@\폜čăCXg[AׂẴEBhE‚ŃuEUċNĂB', - bullet3: 'ȉ̃NJƂmFĂF', - bullet31: 'ȉ̃v[eLXg\܂F', - bullet4: 'LŖ肪ȂꍇAȉ̃`lɂĖ񍐂ĂB', - bullet41: 'QƁF', - bullet4a: 'gOSAuEUƃo[WĂB', - bullet4b: 'R\[Ji', - bullet4b1: 'L[jÂy[WiFYouTube̓y[Wj̃XN[VbgBe܂B', - bullet4c: 'g@\CXg[ĂuEŮg@\y[W̃XN[VbgBe܂B', - bullet4c1: 'g@\y[W\ɂ́Aȉ̂悤ɓ͂ĂF', - firefox: 'FFirefox', - chrome: 'FChrome, Edge, Brave, Opera, Vivaldi', + fetching: { + title: "基本的なフェッチ操作のチュートリアル", + subtitle: "以下のYouTube IDから評価数を取り出した場合の例です:", + title2: "リクエスト例:", + url: "リクエストURL:", + method: "リクエスト方法:", + headers: "ヘッダー:", + response: "レスポンス:", + error1: + 'YouTube IDが無効な場合、ステータスコード 404 "Not Found" が返されます。', + error2: + 'YouTube IDのフォーマットが正しくない場合、ステータスコード 400 "Bad Request" が返されます。', }, - faq: { - name: 'Q&A', - title: '悭鎿', - subtitle: 'ɂ₪܂HXDiscordɂCyɂQB', - bullet1: 'g@\̃f[^͂ǂ擾Ă̂łH', - bullet1text: 'YouTube̒]API~Oɕۑf[^ƁAg@\[U[̍]/]ɂlgݍ킹Ď擾Ă܂B', - bullet2: ']XVȂ̂͂ȂłH', - bullet2text: '݁A]̓f[^x[XĂ邽߁A܂pɂɍXV܂B̍ĐɂĈقȂ܂AXVɂ͐Ԃ琔邱Ƃ܂B', - bullet3: 'ǂ̂悤Ȏdg݂œ삵Ă܂H', - bullet3text: '܂A̓ID WAAPI gpĒ]AĐA]Ȃǂ̍ڂ擾܂BɁAy[Wɒ]Ɣ䗦\܂Bɍ]]ƁAꂪL^ăf[^x[Xɒ~ς邽߁AmȒ]𐄒肷邱Ƃł܂B', - bullet4: ']L邱Ƃ͂ł܂H', - bullet4text: 'ߓɌJ\łB@\̎̂߂ɁAOauth ܂͔͈͂肵ʂ̓ǂݎpAPIgp邱ƂĂ܂B', - bullet5: 'ǂ̂悤ȃf[^WAǂ̂悤Ɏ舵Ă܂H', - bullet5text: '{g@\ł́AIPAhX⎋Ă铮IDȂǁA@\邽߂ɕKvȃf[^݂̂WĂ܂BȂ̃f[^́AO҂ɔ̔邱Ƃ͌Ă܂BZLeBƃvCoV[̎舵ɂ‚Ăƒm肽ꍇɂ́A ZLeBFAQ QƂB ', - bullet6: 'API/obNGh͂ǂ̂悤Ȏdg݂œ삵Ă܂H', - bullet6text: 'obNGh́AYouTube̒]API~Oɕۑf[^Ɗg@\[U[̍]/]ɂlgݍ킹Ď擾Ă܂B߂ARec҂ȒPˆSɒ]񋟂ł悤ɂAArchive Team ̃A[JCuf[^i456000j݂̃f[^x[Xɒlj\łB܂ÃgsbNɊւrfI܂B', - bullet7: ']Ɂue҂ɂ薳vƕ\̂͂ȂłH', - bullet7text: 'ŋߓeꂽł́Ae҂ɂĖɂĂȂĂue҂ɂ薳vƕ\邱Ƃ܂B́A]̕\ɂȂĂ邩ǂoVXeɂ镛pŁAԌA܂͓ɍ]Ȃ]ăy[WXVƏ̂Ǝv܂B', - }, - donate: { - name: 't', - subtitle: 'C^[lbg̎R邽߂̉X̊AtɂĉĂI', - }, - links: { - name: 'N', - title: 'vWFNgNW', - subtitle: 'vWFNgъJ҂ւ̃N', - contact: '₢킹', - translators: '|', - }, -} \ No newline at end of file + }, + help: { + name: "ヘルプ", + title: "トラブルシューティング", + bullet1: "最新バージョンの拡張機能", + bullet11: "がインストールされていることを確認してください。", + bullet2: + "拡張機能を削除して再インストールし、すべてのウィンドウを閉じた上でブラウザを再起動してください。", + bullet3: "以下のリンクが開くことを確認してください:", + bullet31: "以下のプレーンテキストが表示されます:", + bullet4: + "上記で問題が解決しない場合、以下のチャンネルにて問題を報告してください。", + bullet41: "参照:", + bullet4a: "お使いのOS、ブラウザ名とバージョンを教えてください。", + bullet4b: "コンソールを開き(", + bullet4b1: + "キー)、問題のあるページ(例:YouTubeの動画ページ)のスクリーンショットを撮影します。", + bullet4c: + "拡張機能がインストールされているブラウザの拡張機能ページのスクリーンショットを撮影します。", + bullet4c1: "拡張機能ページを表示するには、以下のように入力してください:", + firefox: ":Firefox", + chrome: ":Chrome, Edge, Brave, Opera, Vivaldi", + }, + faq: { + name: "Q&A", + title: "よくある質問", + subtitle: + "他にも何か質問がありますか?我々のDiscordにお気軽にご参加ください。", + bullet1: "拡張機能のデータはどこから取得しているのですか?", + bullet1text: + "YouTube公式の低評価APIが停止する前に保存したデータと、拡張機能ユーザーの高評価/低評価数を元にした推定値を組み合わせて取得しています。", + bullet2: "低評価数が更新されないのはなぜですか?", + bullet2text: + "現在、低評価数はデータベース化されているため、あまり頻繁に更新されません。動画の再生数によって異なりますが、更新には数時間から数日かかることがあります。", + bullet3: "どのような仕組みで動作していますか?", + bullet3text: + "まず、視聴中の動画のID を収集し、API を使用して低評価数、再生数、高評価などの項目を取得します。次に、ページ上に低評価数と比率を表示します。動画に高評価や低評価があると、それが記録されてデータベースに蓄積されるため、正確な低評価数を推定することができます。", + bullet4: "低評価数を共有することはできますか?", + bullet4text: + "近日中に公開予定です。機能の実装のために、Oauth または範囲を限定した別の読み取り専用APIを使用することを検討しています。", + bullet5: "どのようなデータを収集し、どのように取り扱っていますか?", + bullet5text: + '本拡張機能では、IPアドレスや視聴している動画のIDなど、正しく機能するために必要なデータのみを収集しています。あなたのデータは、第三者に販売されることは決してありません。セキュリティとプライバシーの取り扱いについてもっと知りたい場合には、 セキュリティFAQ をご参照ください。 ', + bullet6: "API/バックエンドはどのような仕組みで動作していますか?", + bullet6text: + "バックエンドは、YouTube公式の低評価APIが停止する前に保存したデータと拡張機能ユーザーの高評価/低評価数を元にした推定値を組み合わせて取得しています。近い将来、コンテンツ制作者が簡単かつ安全に低評価数を提供できるようにし、Archive Team のアーカイブデータ(45億6000万動画)も現在のデータベースに追加する予定です。また、このトピックに関するビデオもご覧いただけます。", + bullet7: "低評価数に「投稿者により無効化」と表示されるのはなぜですか?", + bullet7text: + "最近投稿された動画では、投稿者によって無効にされていなくても「投稿者により無効化」と表示されることがあります。これは、評価数の表示が無効になっているかどうかを検出するシステムによる副作用で、数時間後、または動画に高評価ないし低評価をしてページを更新すると消えるものだと思われます。", + }, + donate: { + name: "寄付", + subtitle: + "インターネットの自由を守るための我々の活動を、寄付によって応援してください!", + }, + links: { + name: "リンク", + title: "プロジェクトリンク集", + subtitle: "プロジェクトおよび開発者へのリンク", + contact: "お問い合わせ先", + translators: "翻訳者", + }, +}; diff --git a/Website/_locales/ko.ts b/Website/_locales/ko.ts new file mode 100644 index 00000000..adf6344c --- /dev/null +++ b/Website/_locales/ko.ts @@ -0,0 +1,122 @@ +import { ko } from "vuetify/src/locale"; + +export default { + ...ko, + home: { + name: "홈", + title: "Return YouTube Dislike", + subtitle: "유튜브에서 싫어요를 표시해주는 브라우저 확장 프로그램 및 API", + ukraine: "우크라이나 지원", + sponsors: "스폰서", + }, + install: { + name: "설치", + title: "플랫폼 선택", + subtitle: "파이어폭스와 모든 크로미엄 기반 브라우저에서 사용 가능", + title2: "다른 플랫폼", + subtitle2: + "당신의 브라우저가 아직 지원하지 않는 경우, 이 유저스크립트를 시도할 수 있습니다", + title3: "서드파티 구현", + subtitle3: "우리 측의 책임이 없으며, 사용자의 책임하에 사용하십시오", + }, + api: { + name: "API", + title: "공식 RYD 문서에 오신 것을 환영합니다!", + subtitle: "시작하려면 메뉴에서 섹션을 선택하세요.", + rights: { + title: "사용 권한", + subtitle: + "이 오픈 API의 제 3자 사용은 다음 제한 사항들과 함꼐 허용됩니다:", + bullet1: "저작자 표시: ", + bullet1text: + "이 프로젝트의 사용자는 저장소 또는 returnyoutubedislike.com에 대한 링크와 함께 명확하게 저자를 표기해야 합니다.", + bullet2: "속도 제한: ", + bullet2text: + "하나의 클라이언트당 분당 100개와 하루당 10,000개의 요청 제한이 있습니다. 당신의 애플리케이션이 이를 초과할 경우 429 상태 코드를 반환할 것입니다.", + }, + url: { + title: "URL 정보", + subtitle: "API는 다음 베이스 URL을 통해 액세스할 수 있습니다.: ", + }, + endpoints: { + title: "사용 가능한 엔드포인트", + subtitle: "사용 가능한 엔드포인트 리스트는 여기에서 사용 가능합니다: ", + }, + fetching: { + title: "기본 Fetching 튜토리얼", + subtitle: "주어진 유튜브 영상 ID에 대한 투표 수를 가져오는 예시: ", + title2: "요청 예시: ", + url: "요청 URL: ", + method: "요청 메소드: ", + headers: "헤더: ", + response: "응답: ", + error1: + '유효하지 않은 유튜브 ID는 상태 코드 404 "Not Found"를 리턴합니다', + error2: '잘못된 포멧의 유튜브 ID는 400 "Bad Request"를 리턴합니다', + }, + }, + help: { + name: "도움말", + title: "트러블슈팅", + bullet1: "지금 최신 버전이 설치되어 있는지 확인하세요. ", + bullet11: "버전이 현재 최신 버전입니다.", + bullet2: + "확장 프로그램을 제거하고 재설치한 다음, 브라우저를 재시작 하세요(모든 활성 창을 말하며, 단지 하나의 탭을 말하는 것이 아닙니다)", + bullet3: "이 링크가 열리는지 확인하세요: ", + bullet31: "평문이 표시되어야 합니다: ", + bullet4: + "위의 내용이 도움이 되지 않는 경우, 우리의 디스코드에서 다음과 같은 채널에서 당신의 문제를 보고하세요.", + bullet41: "디스코드: ", + bullet4a: "운영체제, 브라우저 이름과 브라우저 버전을 우리한테 말해주세요", + bullet4b: + "콘솔창과 함께 문제가 된 페이지(예시: 유튜브 영상 페이지)의 스크린샷을 찍으세요.(", + bullet4b1: "키를 누르세요) 아래는 스크린샷의 예시입니다.", + bullet4c: + "확장 브로그램이 설치된 당신의 브라우저의 확장 프로그램 페이지의 스크린샷을 촬영하세요.", + bullet4c1: "확장 프로그램들을 보려면 이것을 주소창에 입력하세요", + firefox: ": 파이어폭스의 경우", + chrome: ": 크롬, 엣지, 브레이브, 오페라, 그리고 비발디의 경우", + }, + faq: { + name: "FAQ", + title: "자주 묻는 질문", + subtitle: + "여전히 의문점이 있으신가요? 우리의 디스코드에 무료로 가입하세요!", + bullet1: "확장 프로그램은 어디에서 데이터를 가져옵니까?", + bullet1text: + "공식 유튜브 싫어요 API가 닫히기 전에 보환된 데이터와 확장 프로그램 사용자 행동을 추정한 값의 조합입니다", + bullet2: "왜 싫어요 수가 업데이트 되지 않는거죠?", + bullet2text: + "현재 동영상 싫어요는 캐시되며 자주 업데이트 되지는 않습니다. 동영상의 인기도에 따라 다르지만, 업데이트되는 데 몇 시간에서 며칠이 걸릴 수 있습니다.", + bullet3: "어떻게 작동합니까?", + bullet3text: + "확장 프로그램은 시청 중인 동영상의 동영상 ID를 수집하며, 우리의 API를 사용하여 싫어요 수(및 조회수, 좋아요 등과 같은 기타 필드)를 가져옵니다. 그런 다음 확장 프로그램은 싫어요 수와 비율을 페이지에 표시합니다. 당신이 비디오에 좋아요나 싫어요를 할 경우, 그것은 기록되고 데이터베이스로 전송되어 정확한 싫어요 수를 추정할 수 있습니다.", + bullet4: "저의 싫어요 수를 공유할 수 있나요?", + bullet4text: + "곧 출시됩니다. 우리는 크리에이터가 검증이 된 싫어요 수를 공유할 수 있도록 Oauth 또는 제한된 범위의 다른 읽기 전용 API를 사용하는 방법을 검토하고 있습니다", + bullet5: "어떤 데이터를 수집하고 어떻게 처리합니까?", + bullet5text: + '확장 프로그램은 제대로 작동하기 위해서 IP 주소 또는 당신이 본 영상의 ID 같은 순전히 필수적인 데이터만 수집합니다. 귀하의 데이터는 3자한테 판매되지 않습니다. 귀하가 우리가 어떻게 개인정보와 보안을 처리하는지 알고 싶다면 우리의 보안 FAQ를 확인하세요.', + bullet6: "API/백엔드는 어떻게 작동하나요?", + bullet6text: + "백엔드는 유튜브 api가 여전히 싫어요 수를 반환할 때의 싫어요 수, 확장기능 사용자들의 좋아요/싫어요 수와 추정치로부터 보관된 데이터를 사용합니다. 가까운 미래에는 콘텐츠 제작자가 쉽고 안전하게 싫어요 수를 제출할 수 있게 될 것이며 우리는 ArchiveTeam의 보관 데이터(45억 6천만 동영상)를 현재 데이터베이스에 추가할 것입니다. 주제에 대한 비디오를 볼 수도 있습니다.", + bullet7: "싫어요 수에 '싫어요 비활성화됨'이 왜 표시됩니까?", + bullet7text: + "때때로 최근에 업로드한 동영상은 제작자가 비활성화하지 않았더라도 '싫어요 비활성화됨'으로 표시될 수 있습니다. 이는 싫어요가 비활성화되어 있는지 감지하는 방법 때문입니다. 몇 시간 내에 동영상에 좋아요 또는 싫어요 표시를 하거나 페이지를 새로고침을 하면(희망 사항) 사라집니다.", + }, + donate: { + name: "기부", + subtitle: + "기부를 통해 인터넷의 자유를 유지하려는 우리의 노력을 지원할 수 있습니다!", + }, + links: { + name: "링크", + title: "프로젝트 링크", + subtitle: "프로젝트와 개발자들로 향하는 링크", + contact: "문의하기", + translators: "번역가들", + coolProjects: "Cool Projects", + sponsorBlockDescription: "동영상에 포함된 광고 건너뛰기", + filmotDescription: "자막으로 유튜브 동영상 검색", + }, +}; diff --git a/Website/_locales/nl.ts b/Website/_locales/nl.ts new file mode 100644 index 00000000..427dcce7 --- /dev/null +++ b/Website/_locales/nl.ts @@ -0,0 +1,126 @@ +import { nl } from "vuetify/src/locale"; + +export default { + ...nl, + home: { + name: "Home", + title: "Return YouTube Dislike", + subtitle: + "Browser-extensie en een API die je antipathieën op YouTube laat zien", + ukraine: "Support Ukraine", + sponsors: "Sponsors", + }, + install: { + name: "Installeren", + title: "Kies je platform", + subtitle: "Beschikbaar voor Firefox en alle Chromium-browsers", + title2: "Andere Platformen", + subtitle2: + "Als uw browser nog niet wordt ondersteund, probeer dan dit UserScript", + title3: "Implementaties van derden", + subtitle3: "Geen aansprakelijkheid aan onze kant, gebruik op eigen risico", + }, + api: { + name: "API", + title: "Welkom bij de officiële RYD-documenten!", + subtitle: "Selecteer een sectie in het menu om aan de slag te gaan.", + rights: { + title: "Gebruiksrechten", + subtitle: + "Gebruik door derden van deze open API is toegestaan met de volgende beperkingen:", + bullet1: "Attributie: ", + bullet1text: + "Dit project moet duidelijk worden toegeschreven met een link naar deze repo of een link om terug te keren naar youtubedislike.com", + bullet2: "Snelheidsbeperking: ", + bullet2text: + "Er zijn per klant tarieflimieten in plaats van 100 per minuut en 10.000 per dag. Dit geeft een 429-statuscode terug die aangeeft dat uw toepassing moet worden uitgeschakeld", + }, + url: { + title: "URL Informatie", + subtitle: "De API is toegankelijk via de volgende basis-URL: ", + }, + endpoints: { + title: "Beschikbare eindpunten", + subtitle: "Lijst met beschikbare eindpunten is hier beschikbaar: ", + }, + fetching: { + title: "Basiscursus ophalen", + subtitle: + "Voorbeeld om stemmen te krijgen voor een bepaalde YouTube-video-ID: ", + title2: "Voorbeeld aanvraag: ", + url: "Verzoek-URL: ", + method: "Verzoekmethode:: ", + headers: "Koppen: ", + response: "Antwoord: ", + error1: + 'Een ongeldige YouTube-ID retourneert statuscode 404 "Niet gevonden"', + error2: + 'Een onjuist opgemaakte YouTube-ID retourneert 400 "Slecht verzoek"', + }, + }, + help: { + name: "Help", + title: "Probleemoplossen", + bullet1: + "Zorg ervoor dat u de nieuwste versie van de extensie hebt geïnstalleerd, ", + bullet11: "direct", + bullet2: + "Probeer de extensie te verwijderen en opnieuw te installeren, en start vervolgens de browser opnieuw (alle actieve vensters, niet slechts één tabblad)", + bullet3: "Zorg ervoor dat deze link opent: ", + bullet31: "je zou platte tekst moeten zien: ", + bullet4: "Als niets van het bovenstaande helpt - meld uw probleem dan in", + bullet41: "in onze", + bullet4a: "Vertel ons uw besturingssysteem, browsernaam en browserversie", + bullet4b: + "Maak een screenshot van de pagina met het probleem (d.w.z. de YouTube-videopagina) met de console open (druk op ", + bullet4b1: ") - voorbeeld screenshot hieronder.", + bullet4c: + "Maak een screenshot van de extensiepagina van uw browser waarop de extensie is geïnstalleerd.", + bullet4c1: "Om extensies te zien, plaats dit in de adresbalk: ", + firefox: "voor Firefox", + chrome: "voor Chrome, Edge, Brave, Opera, Vivaldi", + }, + faq: { + name: "FAQ", + title: "Veel Gestelde Vragen", + subtitle: + "Heeft u nog vragen? Voel je vrij om lid te worden van onze Discord!", + bullet1: "Waar haalt de extensie zijn gegevens vandaan?", + bullet1text: + "Een combinatie van gearchiveerde gegevens van voordat de officiële YouTube-dislike-API werd afgesloten, en geëxtrapoleerd gebruikersgedrag van extensies.", + bullet2: "Waarom wordt het aantal dislikes niet bijgewerkt?", + bullet2text: + "Op dit moment worden video's die niet leuk zijn in de cache opgeslagen en worden ze niet vaak bijgewerkt. Het varieert afhankelijk van de populariteit van een video, maar het kan een paar uur tot een paar dagen duren om te updaten.", + bullet3: "Hoe werkt dit?", + bullet3text: + "De extensie verzamelt de video-ID van de video die je aan het bekijken bent en haalt de afkeer (en andere velden zoals weergaven, vind-ik-leuks enz.) op met behulp van onze API. De extensie geeft vervolgens het aantal dislikes en de verhouding weer op de pagina. Als je een video leuk of niet leuk vindt, wordt deze opgenomen en naar de database gestuurd, zodat een nauwkeurige telling van de dislikes kan worden geëxtrapoleerd.", + bullet4: "Kan ik mijn niet leuk-teller met je delen?", + bullet4text: + "Binnenkort beschikbaar. We onderzoeken het gebruik van Oauth of een andere alleen-lezen API met een beperkte reikwijdte, zodat makers hun afkeer-aantallen verifieerbaarheid kunnen delen.", + bullet5: "Welke gegevens verzamelt u en hoe worden deze verwerkt?", + bullet5text: + 'De extensie verzamelt alleen gegevens die strikt noodzakelijk zijn om goed te kunnen functioneren, zoals het IP-adres of de ID van de video die u bekijkt. Geen van uw gegevens zal ooit worden verkocht aan derden. Als u meer wilt weten over hoe wij omgaan met beveiliging en privacy, bekijk dan onze beveilings FAQ.', + bullet6: "Hoe werkt de API/Backend?", + bullet6text: + "De backend gebruikt gearchiveerde gegevens van toen de youtube-api nog steeds het aantal dislikes retourneerde, extensiegebruikers zoals het aantal likes/dislikes en extrapolatie. In de nabije toekomst zullen we het voor makers van inhoud mogelijk maken om eenvoudig en veilig hun afkeuren-aantal in te dienen en we zullen de gearchiveerde gegevens van ArchiveTeam (4,56 miljard video's) toevoegen aan onze huidige database. U kunt ook een video over het onderwerp bekijken.", + bullet7: + "Waarom wordt bij het aantal dislikes 'DISLIKES DISABLED' weergegeven?", + bullet7text: + "Soms kan een recent geüploade video 'DISLIKES UITGESCHAKELD' weergeven, zelfs als de maker dit niet heeft uitgeschakeld. Dit komt door de manier waarop we detecteren of dislikes zijn uitgeschakeld, het zou binnen een paar uur moeten verdwijnen of door de video leuk of niet leuk te vinden en de pagina vernieuwen (hopelijk).", + }, + donate: { + name: "Doneer", + subtitle: + "Met een donatie kunt u onze inspanningen om het internet gratis te houden steunen!", + }, + links: { + name: "Linken", + title: "Project Linken", + subtitle: "Linken naar het project en zijn ontwikkelaars", + contact: "Neem contact op met me", + translators: "Vertalers", + coolProjects: "Coole Projecten", + sponsorBlockDescription: "In video geïntegreerde advertenties overslaan", + filmotDescription: "Zoek YouTube-video's op ondertiteling", + }, +}; diff --git a/Website/_locales/pl.ts b/Website/_locales/pl.ts new file mode 100644 index 00000000..954c3a58 --- /dev/null +++ b/Website/_locales/pl.ts @@ -0,0 +1,125 @@ +import { pl } from "vuetify/src/locale"; +// by itsbudyn#6502 +export default { + ...pl, + home: { + name: "Strona główna", + title: "Return YouTube Dislike", + subtitle: + "Rozszerzenie do przeglądarki i API pokazujące ilość łapek w dół na YouTube", + ukraine: "Wesprzyj Ukrainę", + sponsors: "Sponsorzy", + }, + install: { + name: "Instalacja", + title: "Wybierz swoją platformę", + subtitle: "Dostępne dla Firefox i wszystkich przeglądarek Chromium", + title2: "Inne platformy", + subtitle2: + "Jeżeli twoja przeglądarka nie jest wspierana, wypróbuj ten UserScript", + title3: "Implementacje od stron trzecich", + subtitle3: + "Nie ponosimy za nie odpowiedzialności, używasz na własne ryzyko", + }, + api: { + name: "API", + title: "Witamy w oficjalnej dokumentacji RYD!", + subtitle: "Aby rozpocząć, wybierz sekcję z menu.", + rights: { + title: "Prawa do użytku", + subtitle: + "Używanie tego otwartego API jest dozwolone z następującymi ograniczeniami:", + bullet1: "Przypisanie: ", + bullet1text: + "Ten projekt powinien być widocznie przypisany autorom za pomocą linku do tego repozytorium, albo do returnyoutubedislike.com", + bullet2: "Ograniczenia: ", + bullet2text: + "Istnieją ograniczenia żądań dla klientów - 100 na minutę, oraz 10 000 na dzień. Przekroczenie będzie sygnowane zwrotem kodu 429 wskazujący, że Twoja aplikacja powinna przyhamować. ", + }, + url: { + title: "Informacje o URL", + subtitle: "API jest dostępne przez następujące bazowe URL: ", + }, + endpoints: { + title: "Dostępne endpointy", + subtitle: "Lista dostępnych endpointów znajduje się tutaj: ", + }, + fetching: { + title: "Poradnik - Podstawowe pobieranie", + subtitle: + "Przykład pozwalający otrzymać głosy z danego ID filmu na YouTube: ", + title2: "Przykładowe żądanie: ", + url: "URL żądania: ", + method: "Metoda żądania: ", + headers: "Nagłówki: ", + response: "Odpowiedź: ", + error1: 'Nieprawidłowy ID filmu zwróci kod 404 "Not Found"', + error2: + 'Nieprawidłowo sformatowany ID filmu zwróci kod 400 "Bad Request"', + }, + }, + help: { + name: "Pomoc", + title: "Rozwiązywanie problemów", + bullet1: + "Upewnij się, że masz zainstalowaną najnowszą wersję rozszerzenia, ", + bullet11: "obecnie.", + bullet2: + "Spróbuj usunąć rozszerzenie i zainstalować je ponownie, a następnie zrestartować przeglądarkę (wszystkie aktywne okna, nie tylko jedną kartę)", + bullet3: "Upewnij się, że ten link się otwiera: ", + bullet31: "powinno się wyświetlić w czystym tekście: ", + bullet4: "Jeśli nic powyżej nie pomoże - zgłoś problem na", + bullet41: "na naszym", + bullet4a: + "Powiedz z jakiego systemu operacyjnego korzystasz, oraz podaj nazwę i wersję przeglądarki", + bullet4b: + "Wykonaj zrzut ekranu problematycznej strony (tj. strony filmu na YouTube) z otwartą konsolą (naciśnij ", + bullet4b1: ") - przykładowy zrzut poniżej.", + bullet4c: + "Wykonaj zrzut ekranu strony z rozszerzeniami Twojej przeglądarki, wraz z zainstalowanym rozszerzeniem.", + bullet4c1: "Aby zobaczyć rozszerzenia, wklej do paska adresowego: ", + firefox: "dla Firefox", + chrome: "dla Chrome, Edge, Brave, Opera oraz Vivaldi", + }, + faq: { + name: "FAQ", + title: "Często zadawane pytania", + subtitle: "Wciąż masz pytania? Zapraszamy na naszego Discorda!", + bullet1: "Skąd rozszerzenie otrzymuje swoje dane?", + bullet1text: + "Kombinacja danych zarchiwizowanych przed wyłączeniem oficjalnego API do łapek w dół, oraz ekstrapolowane zachowania użytkowników rozszerzenia.", + bullet2: "Dlaczego licznik łapek w dół się nie aktualizuje?", + bullet2text: + "Na chwilę obecną łapki w dół są buforowane i nie są często aktualizowane. Zależy to od popularności filmu, jednak może to zająć klika godzin lub kilka dni żeby licznik został zaktualizowany. ", + bullet3: "Jak to działa?", + bullet3text: + "Rozszerzenie pobiera ID filmu, który oglądasz, a następnie używając naszego API pobiera liczbę łapek w dół (oraz inne pola, takie jak wyświetlenia, łapki w górę itd.). Rozszerzenie potem wyświetla liczbę łapek w dół oraz proporcje łapek na stronie. Jeżeli dasz filmowi łapkę w górę bądź w dół, ta akcja zostanie zarejestrowana i wysłana do bazy danych, aby dokonać ekstrapolacji dokładnej liczby łapek w dół.", + bullet4: "Czy mogę Wam udostępnić liczbę łapek w dół na moich filmach?", + bullet4text: + "Wkrótce. Przyglądamy się możliwościom użycia OAuth lub innego klucza API tylko do odczytu z ograniczonym zakresem, aby twórcy mogli udostępniać zweryfikowaną liczbę swoich łapek w dół.", + bullet5: "Jakie dane zbieracie i co z nimi robicie?", + bullet5text: + 'Rozszerzenie zbiera tylko dane wymagane do poprawnego działania, takie jak adres IP lub ID oglądanego filmu. Dane te nigdy nie będą sprzedane osobom trzecim. Jeżeli chcesz przeczytać więcej o tym, jak radzimy sobie z bezpieczeństwem i prywatnością, sprawdź nasze FAQ bezpieczeństwa.', + bullet6: "Jak działa API/Backend?", + bullet6text: + "Backend używa danych zarchiwizowanych w momencie, gdy API YouTube wciąż zwracało liczby łapek w dół, oraz danych zebranych i ekstrapolowanych od użytkowników rozszerzenia. W niedalekiej przyszłości pozwolimy twórcom łatwo i bezpieczne udostępniać swoje liczniki łapek w dół oraz będziemy dodawać dane zarchiwizowane przez ArchiveTeam (4,56 miliardów filmów) do naszej bazy danych. Można też obejrzeć film na ten temat. ", + bullet7: "Dlaczego licznik łapek w dół pokazuje 'WYŁĄCZONE PRZEZ TWÓRCĘ'?", + bullet7text: + "Czasami świeżo wrzucony film pokazuje 'WYŁĄCZONE PRZEZ TWÓRCĘ' nawet wtedy, gdy twórca nie wyłączył łapek. Jest to spowodowane naszym sposobem wykrywania wyłączonych łapek, powinno zniknąć za parę godzin, albo po oddaniu łapki i odświeżeniu strony (oby).", + }, + donate: { + name: "Wesprzyj", + subtitle: + "Możesz wesprzeć pieniężnie nasze starania w utrzymaniu wolnego internetu!", + }, + links: { + name: "Linki", + title: "Linki projektu", + subtitle: "Linki do projektu i ich developerów", + contact: "Skontaktuj się ze mną", + translators: "Tłumacze", + coolProjects: "Fajne projekty", + sponsorBlockDescription: "Pomiń reklamy zintegrowane z filmem", + filmotDescription: "Wyszukaj filmy na YouTube po napisach", + }, +}; diff --git a/Website/_locales/pt_BR.ts b/Website/_locales/pt_BR.ts new file mode 100644 index 00000000..fbf0f2e7 --- /dev/null +++ b/Website/_locales/pt_BR.ts @@ -0,0 +1,117 @@ +import { pt_BR } from "vuetify/src/locale"; +// by Unnamed-orbert +export default { + ...pt_BR, + home: { + name: "Inicio", + title: "Return YouTube Dislike", + subtitle: "Esta extensão de navegador usando a nossa APU irá mostra seus Deslikes no Youtube", + ukraine: "Ajuda a Ucrania", + sponsors: "Patrocinaores", + }, + install: { + name: "Instalação", + title: "Selecione sua plataforma", + subtitle: "Disponivel para Firefox e tidos navegadores Chromium", + title2: "Outras Plataformas", + subtitle2: "Se seu navegador não suportar isso, tente usa um UserScript", + title3: "Implementação de terceiro", + subtitle3: "Não nós garantimos com isso, use por sua conta e risco!", + }, + api: { + name: "API", + title: "Bem-vindo aos documentos oficiais de RYD!", + subtitle: "Para começar, selecione um seletor o menu.", + rights: { + title: "Direitos de uso", + subtitle: + "Third party use of this open API is allowed with the following restrictions:", + bullet1: "Attribution: ", + bullet1text: + "This project should be clearly attributed with either a link to this repo or a link to returnyoutubedislike.com", + bullet2: "Rate Limiting: ", + bullet2text: + "There are per client rate limits in place of 100 per minute and 10,000 per day. This will return a 429 status code indicating that your application should back off", + }, + url: { + title: "Informação da URL", + subtitle: "A API é acessivel seguindo o URL base: ", + }, + endpoints: { + title: "Available Endpoints", + subtitle: "List of available endpoints is available here: ", + }, + fetching: { + title: "Basic Fetching Tutorial", + subtitle: "Example to get votes of a given YouTube video ID: ", + title2: "Examplo de Requesitação : ", + url: "URL de requisitação: ", + method: "Metodo de solicitação: ", + headers: "Cabeçalhos: ", + response: "Resposta: ", + error1: 'Isso é um ID do youtube invalido retornando o codigo 404 "não encontrado"', + error2: 'Isso é um ID do youtube mal formatada retornando o codigo 400 "Solicitação ruim"', + }, + }, + help: { + name: "Ajuda", + title: "Troubleshooting", + bullet1: "Make sure you have latest version of extension installed, ", + bullet11: "right now", + bullet2: "Tente remover a extensão e instalar novamente, ou tente reiniciar o navegador", + bullet3: "Faça isso abrindo este link:", + bullet31: "you should see plain text: ", + bullet4: "Se não encontrou um ajuda - reporte seu problema no ", + bullet41: "na nossa", + bullet4a: "Diga-nós o seu sistema operacional, navegador e Versão do navegador", + bullet4b: + "Take a screenshot of the page with the problem (i.e. Youtube video page) with the console open (press ", + bullet4b1: ") - example screenshot below.", + bullet4c: + "Take a screenshot of the extensions page of your browser with the extension installed.", + bullet4c1: "Veja as extensões put essa into barra de endereço: ", + firefox: "para Firefox", + chrome: "para Chrome, Edge, Brave, Opera e Vivaldi", + }, + faq: { + name: "FAQ", + title: "Pergunta feitas com Frequencia", + subtitle: "Ainda tem perguntas? Sinta-se livre para nós acompanhar no Discord!", + bullet1: "Quais dados a extensão obtem Where does the extension get its data?", + bullet1text: + "A combination of archived data from before the official YouTube dislike API shut down, and extrapolated extension user behavior.", + bullet2: "Por que a contagem de deslike não está atualizando?", + bullet2text: + "Right now video dislikes are cached and they aren't updated very frequently. It varies depending on a video's popularity but can take anywhere between a few hours and a few days to update.", + bullet3: "Como isso funciona?", + bullet3text: + "The extension collects the video ID of the video you are watching, and fetches the number of dislikes (and other fields like views, likes etc) using our API. The extension then displays the dislike count and ratio on the page. If you like or dislike a video, that is recorded and sent to the database so an accurate dislike count can be extrapolated.", + bullet4: "Eu posso compartilha a contador de deslike com você?", + bullet4text: + "Coming soon. We are looking into using Oauth or a different read only API with a limited scope so creators can share their dislike counts verifiability.", + bullet5: "Quais os dados que vocs coletam para fazer isso funcionar?", + bullet5text: + 'A extensão apenas coleta os dados extritamente necessaria para o funcionamento proprietario, como o seu endereço de IP e ID do video que vocês atualmente assistindo. None of your data will ever be sold to 3rd parties. If you would like to know more about how we handle security and privacy check out our security FAQ.', + bullet6: "How does the API/Backend work?", + bullet6text: + "The backend is using archived data from when the youtube api was still returning the dislike count, extension users like/dislike count and extrapolation. In the near future we will be allowing content creators to submit their dislike count easily and safely and we will be adding ArchiveTeam's archived data (4.56 billion videos) into our current database. You can also view a video on the topic.", + bullet7: "Why does the dislike count show 'DISLIKES DISABLED'?", + bullet7text: + "Sometimes a recently uploaded video might show 'DISLIKES DISABLED' even if the creator hasn't disabled it, this is due to how we are detecting if dislikes are disabled, it should go away in a few hours or by liking or disliking the video and refreshing the page (hopefully).", + }, + donate: { + name: "Doe", + subtitle: + "Você pode nós ajuda a melhora sua experiencia na internet com uma doação!", + }, + links: { + name: "Links", + title: "Links de Projetos", + subtitle: "Links para o projeto e outros desenvolvedores", + contact: "Entre em Contato comigo (Only English, please!)", + translators: "Tradutores", + coolProjects: "Projetos de Qualidade", + sponsorBlockDescription: "Pule propagangas integradas nos videos", + filmotDescription: "Pesquise videos do YouTube pelas Legandas", + }, +}; diff --git a/Website/_locales/sv.ts b/Website/_locales/sv.ts new file mode 100644 index 00000000..31edfc3b --- /dev/null +++ b/Website/_locales/sv.ts @@ -0,0 +1,123 @@ +import { sv } from "vuetify/src/locale"; + +export default { + ...sv, + home: { + name: "Hem", + title: "Return YouTube Dislike", + subtitle: + "Webbläsartillägg och ett API som visar antalet ogilla på Youtube", + ukraine: "Stöd Ukraina", + sponsors: "Sponsorer", + }, + install: { + name: "Installera", + title: "Välj din webbläsare", + subtitle: "Tillgängligt för Firefox och alla Chromium-webbläsare", + title2: "Andra webbläsare", + subtitle2: "Om din webbläsare ännu inte stöds, prova detta UserScript", + title3: "Tredjepartsimplementeringar", + subtitle3: "Inget ansvar från vår sida, använd på egen risk", + }, + api: { + name: "API", + title: "Välkommen till de officiella RYD-dokumenten!", + subtitle: "För att komma igång, välj ett avsnitt från menyn.", + rights: { + title: "Användningsrättigheter", + subtitle: + "Tredjepartsanvändning av detta öppna API är tillåtet med följande begränsningar:", + bullet1: "Tillskrivning: ", + bullet1text: + "Detta projekt bör tydligt tillskrivas med antingen en länk till denna repo eller en länk till returnyoutubedislike.com", + bullet2: "Satsbegränsning: ", + bullet2text: + "Det finns satsbegränsningar per användare med 100 per minut och 10000 per dag. Detta kommer att returnera en statushod 429 som indikerar att din applikation ska hålla sig borta", + }, + url: { + title: "Webbadressinformation", + subtitle: "API:et är tillgängligt via följande baswebbadress: ", + }, + endpoints: { + title: "Tillgängliga slutpunkter", + subtitle: "Lista över tillgängliga slutpunkter finns här: ", + }, + fetching: { + title: "Grundläggande handledning för hämtning", + subtitle: + "Exempel för att hämta röster för ett bestämt YouTubevideo-ID: ", + title2: "Example Request: ", + url: "Request URL: ", + method: "Request Method: ", + headers: "Headers: ", + response: "Response: ", + error1: 'Ett ogiltigt YouTube-ID returnerar statuskoden 404 "Not Found"', + error2: + 'Ett felaktigt formaterat YouTube-ID returnerar 400 "Bad Request"', + }, + }, + help: { + name: "Hjälp", + title: "Felsökning", + bullet1: + "Se till att du har den senaste versionen av tillägget installerat, ", + bullet11: "just nu", + bullet2: + "Försök att avinstallera tillägget och installera det igen, starta sedan om webbläsaren (alla aktiva fönster, inte bara en flik)", + bullet3: "Se till att den här länken öppnas: ", + bullet31: "du bör se vanlig text: ", + bullet4: "Om inget av ovanstående hjälper - rapportera ditt problem i", + bullet41: "i vår", + bullet4a: + "Tala om för oss ditt operativsystem, webbläsarnamn och webbläsarversion", + bullet4b: + "Ta en skärmdump av sidan du har problem med (t.ex en youtube-videosida) med konsolfönstret öppet (tryck ", + bullet4b1: ") - exempel på skärmdump nedan.", + bullet4c: + "Ta en skärmdump av tilläggssidan i din webbläsare med tillägg installerat.", + bullet4c1: "För att se tilläggen skriv in detta i adressfältet: ", + firefox: "för Firefox", + chrome: "för Chrome, Edge, Brave, Opera och Vivaldi", + }, + faq: { + name: "FAQ", + title: "Vanliga frågor", + subtitle: "Har du fortfarande frågor? Gå gärna med i vår Discord!", + bullet1: "Var får tillägget sina data?", + bullet1text: + "En kombination av arkiverad data från innan det officiella YouTube ogilla-API:et stängdes av och och extrapolerat tilläggsanvändarbeteende.", + bullet2: "Varför uppdateras inte antalet ogilla?", + bullet2text: + "Just nu cachelagras ogilla för videoklipp och de uppdateras inte särskilt ofta. Det varierar beroende på en videos popularitet, men det kan ta allt från några timmar till några dagar att uppdatera.", + bullet3: "Hur fungerar detta?", + bullet3text: + "Tillägget samlar in video-ID:t för videon du tittar på och hämtar ogilla (and other fields like views, likes etc) med hjälp av vårt API. Tillägget visar sedan antalet ogilla och förhållandet på sidan. Om du gillar eller ogillar en video, spelas det in och skickas till databasen så att ett korrekt antal ogilla kan extrapoleras.", + bullet4: "Kan jag dela mina antalet ogilla med dig?", + bullet4text: + "Kommer snart. Vi tittar på att använda Oauth eller ett annat skrivskyddat API med ett begränsat omfång så att kreatörer kan dela med sig av verifierbarheten av sina antal ogilla.", + bullet5: "Vilken data samlar du in och hur behandlas den?", + bullet5text: + 'Tillägget samlar bara in data som är absolut nödvändig för att den ska fungera korrekt, som IP-adressen eller ID:t på videon du tittar på. Inga uppgifter kommer någonsin att säljas till tredjepart. Om du vill veta mer om hur vi hanterar säkerhet och integritet läs då vår vanliga frågor om säkerhet.', + bullet6: "Hur fungerar API/Backend?", + bullet6text: + "Backend använder arkiverad data från när YouTubes API fortfarande returnerade antalet ogilla. Inom en snar framtid kommer vi att tillåta innehållsskapare att enkelt och säkert skicka in sina ogilla och vi kommer att lägga till ArchiveTeams arkiverade data (4,56 miljarder videor) i vår nuvarande databas. Du kan också se en video om ämnet.", + bullet7: "Varför visar antalet ogilla 'OGILLA ÄR INAKTIVERAT'?", + bullet7text: + "I bland kan en nyligen uppladdad video visa 'OGILLA ÄR INAKTIVERAT' även om ägaren inte har inaktiverat den. Detta beror på hur informationen om ogilla är inaktiverat hämtas ut. Det bör försvinna inom några timmar eller genom att gilla eller ogilla videon och uppdatera sidan (förhoppningsvis).", + }, + donate: { + name: "Donera", + subtitle: + "Du kan stöda våra ansträngningar att hålla internet fritt med en donation!", + }, + links: { + name: "Länkar", + title: "Projektlänkar", + subtitle: "Länkar till projektet och dess utvecklare", + contact: "Kontakta mig", + translators: "Översättare", + coolProjects: "Häftiga projekt", + sponsorBlockDescription: "Hoppar över annonser integrerade i videon", + filmotDescription: "Sök efter YouTube-videor i undertexterna", + }, +}; diff --git a/Website/_locales/tr.ts b/Website/_locales/tr.ts index 25f695ba..12298b22 100644 --- a/Website/_locales/tr.ts +++ b/Website/_locales/tr.ts @@ -6,7 +6,7 @@ export default { name: "Ana Sayfa", title: "YouTube Dislike Sayısını Geri Getir", subtitle: - "Tarayıcı uzantısı ve bir API, YouTube'daki dislike sayınızı geri getirir", + "YouTube'daki dislike sayılarınızı geri getiren bir tarayıcı uzantısı ve API", ukraine: "Ukrayna'ya Destek Ol", sponsors: "Sponsorlar", }, @@ -31,10 +31,10 @@ export default { "Herkese açık API'nin üçüncü parti kişilerin kullanımında aşağıdaki kısıtlamalara izin verir:", bullet1: "Atıf: ", bullet1text: - "Bu proje, bu depoya ya da returnyoutubedislike.com sitesine bir bağlantı ile açıkça atfedilmelidir", + "Bu proje, bu depoya ya da returnyoutubedislike.com sitesine bir bağlantı ile açıkça atfedilmelidir.", bullet2: "Hız Sınırlaması: ", bullet2text: - "Kullanıcı başına dakikada 100 ve günde 10.000 hız sınırlaması vardır. Bu, uygulamanızın geri çekilmesi gerektiğini belirten 429 durum kodunu döndürür", + "Kullanıcı başına dakikada 100 ve günde 10.000 hız sınırlaması vardır. Bu, uygulamanızın geri çekilmesi gerektiğini belirten 429 durum kodunu döndürür.", }, url: { title: "URL Bilgisi", @@ -53,9 +53,9 @@ export default { method: "İstek Yöntemi: ", headers: "Header'lar: ", response: "Sonuç: ", - error1: 'Geçersiz bir YouTube ID\'si, 404 "Not Found" olarak döndürülür', + error1: 'Geçersiz bir YouTube ID\'si, 404 "Not Found" olarak döndürülür.', error2: - 'Yanlış biçimlendirilmiş bir YouTube ID\'si, 400 "Bad Request" olarak döndürülür', + 'Yanlış biçimlendirilmiş bir YouTube ID\'si, 400 "Bad Request" olarak döndürülür.', }, }, help: { @@ -101,13 +101,12 @@ export default { bullet5: "Hangi verileri topluyorsunuz ve bunlar nasıl işleniyor?", bullet5text: "Uzantı, yalnızca izlediğiniz videonun IP adresi veya videonun ID'si gibi düzgün çalışması için kesinlikle gerekli olan verileri toplar. Verileriniz asla 3. taraflara satılmayacaktır. Güvenliği ve gizliliği nasıl ele aldığımız hakkında daha fazla bilgi için security FAQ'ya gidin.", - bullet6: "API/Yazılım(Backend) nasıl çalışıyor?", + bullet6: "API/Backend nasıl çalışıyor?", bullet6text: "Yazılım, YouTube API'sinin dislike sayısını ve uzantı kullanıcılarının like/dislike sayısı sonuçların genişletilmesinin döndürmeye devam ettiği zamana ait arşivlenmiş verileri kullanır. Yakın zamanda içerik üreticilerin dislike sayısını kolay ve güvenli bir şekilde göndermelerine izin vereceğiz ve ArchiveTeam'in arşivlenmiş verilerini (4,56 milyar video) veri tabanımıza ekleyeceğiz. Ayrıca konu ile ilgili videoyu da izleyebilirsiniz.", - bullet7: - "Dislike sayısı neden 'DISLIKES DISABLED'(DISLIKE'LAR AKTİF DEĞİL) olarak gözüküyor?", + bullet7: "Dislike sayısı neden 'DISLIKE'LAR KAPALI' olarak gözüküyor?", bullet7text: - "Yazma sırasında like ve dislike sayısını devre dışı bırakan videoların dislike sayılarını göstermiyoruz. Uzantı, bu videolar için 'DISLIKES DISABLED'(DISLIKE'LAR AKTİF DEĞİL) mesajını görüntüler. Yakında tüm videolarda dislike sayısını göstereceğiz. Bu, yalnızca geçici bir çözümdür. Bu nedenle insanlar uzantının bozuk olduğunu düşünmez (zaten iyi çalışmıyor). Bazen yakın zamanda yüklenen bir videoda, içerik üreticisi onu devre dışı bırakmamış olsa bile 'DISLIKES DISABLED' olarak gözükebilir. Bunun nedeni, dislike sayısını devre dışı bırakıp bırakmadığını tespit etmemizdir. Birkaç saat içinde videoyu like ya da dislike atarsanız veya sayfayı yenilerseniz kaybolması gerekir (umarız).", + "Yazma sırasında like ve dislike sayısını devre dışı bırakan videoların dislike sayılarını göstermiyoruz. Uzantı, bu videolar için 'DISLIKE'LAR KAPALI' mesajını görüntüler. Yakında tüm videolarda dislike sayısını göstereceğiz. Bu, yalnızca geçici bir çözümdür. Bu nedenle insanlar uzantının bozuk olduğunu düşünmez (zaten iyi çalışmıyor). Bazen yakın zamanda yüklenen bir videoda, içerik üreticisi onu devre dışı bırakmamış olsa bile 'DISLIKE'LAR KAPALI' olarak gözükebilir. Bunun nedeni, dislike sayısını devre dışı bırakıp bırakmadığını tespit etmemizdir. Birkaç saat içinde videoyu like ya da dislike atarsanız veya sayfayı yenilerseniz kaybolması gerekir (umarız).", }, donate: { name: "Bağış Yap", @@ -120,7 +119,7 @@ export default { subtitle: "Projeye ve geliştiricilerine bağlantılar", contact: "Bana Ulaşın", translators: "Çevirmenler", - coolProjects: "Hoş Projeler", + coolProjects: "Havalı Projeler", sponsorBlockDescription: "Videolara gömülü reklamları pas geçer", filmotDescription: "YouTube videolarını alt yazılara göre aramanızı sağlar", }, diff --git a/Website/_locales/uk.ts b/Website/_locales/uk.ts new file mode 100644 index 00000000..da1a5b95 --- /dev/null +++ b/Website/_locales/uk.ts @@ -0,0 +1,125 @@ +import { uk } from "vuetify/src/locale"; +// By dsty#1614 +export default { + ...uk, + home: { + name: "Головна", + title: "Return YouTube Dislike", + subtitle: + "Браузерне розширення та API, що дозволяє вам бачити відмітки «Не подобається» на YouTube", + ukraine: "Підтримати Україну", + sponsors: "Спонсори", + }, + install: { + name: "Завантажити", + title: "Оберіть вашу платформу", + subtitle: "Доступно на Firefox та усіх Chromium браузерах", + title2: "Інші платформи", + subtitle2: "Якщо ваш браузер не підтримується, спробуйте цей UserScript", + title3: "Стороннє ПЗ", + subtitle3: + "Ми не маємо відношення до цього, використовуйте на свій страх і ризик", + }, + api: { + name: "API", + title: "Вітаємо у офіційній документації RYD!", + subtitle: "Щоб почати, виберіть розділ у меню.", + rights: { + title: "Права використання", + subtitle: + "Використання цього відкритого API сторонніми особами дозволено з наступними обмеженнями:", + bullet1: "Атрибуція: ", + bullet1text: + "Цей проєкт має бути чітко описано, використовуючи посилання, або ж на цей репозиторій, або ж на returnyoutubedislike.com", + bullet2: "Обмеження: ", + bullet2text: + "Існують обмеження на швидкісті для кожного клієнта - 100 за хвилину і 10 000 за день. Це видасть код помилки 429, який вказує на те, що вашому додатку слід завершити роботу", + }, + url: { + title: "Інформація про посилання", + subtitle: "API доступний за наступним посиланням: ", + }, + endpoints: { + title: "Достпупні «ендпоінти»", + subtitle: "Перелік доступних «ендпоінтів» можна переглянути тут: ", + }, + fetching: { + title: "Базовий посібник по отриманню", + subtitle: "Приклад отримання оцінок відео на YouTube за ID ", + title2: "Приклад запиту: ", + url: "Посилання запиту: ", + method: "Метод запиту: ", + headers: "Заголовок: ", + response: "Відповідь: ", + error1: 'Недійсний YouTube ID видасть код помилки 404 "Not Found"', + error2: + 'YouTube ID у невірному форматі видасть код помилки 400 "Bad Request"', + }, + }, + help: { + name: "Допомога", + title: "Усунення несправностей", + bullet1: + "Переконайтеся, що у вас встановлена остання версія розширення, наразі це - ", + bullet11: "", + bullet2: + "Спробуйте видалити розширення і встановити його знову, а потім перезавантажте браузер (усі активні вікна, а не лише одну вкладку).", + bullet3: "Переконайтеся, що наступне посилання відкривається: ", + bullet31: "і ви бачите там цей текст: ", + bullet4: + "Якщо нічого з перерахованого вище не допомогло - повідомте про проблему в каналі", + bullet41: "у нашому", + bullet4a: "Повідомте нам вашу операційну систему, назву та версію браузера", + bullet4b: + "Зробіть знімок екрана сторінки з проблемою (тобто сторінки відео на YouTube) із відкритою консоллю (натисніть ", + bullet4b1: ") - приклад знімка екрана нижче.", + bullet4c: + "Зробіть знімок екрана сторінки з встановленими розширеннями вашого браузера.", + bullet4c1: "Щоб побачити розширення, напишіть це в адресний рядок: ", + firefox: "для Firefox", + chrome: "для Chrome, Edge, Brave, Opera, Vivaldi", + }, + faq: { + name: "ЧаПи", + title: "Часті питання", + subtitle: + "Залишилися питання? Не соромтеся приєднуватися до нашого Discord!", + bullet1: "Звідки розширення отримує дані?", + bullet1text: + "Комбінація архівних даних, отриманих до закриття офіційного API відміток «Не подобається» на YouTube та екстрапольованої поведінки користувачів розширення.", + bullet2: "Чому кількість відміток «Не подобається» не оновлюється?", + bullet2text: + "Наразі відмітки «Не подобається» кешуються й не оновлюються надто часто. Це залежить від популярності відео, але для оновлення може знадобитися від кількох годин до кількох днів.", + bullet3: "Як це працює?", + bullet3text: + "Розширення отримує ID відео, яке ви переглядаєте, та дізнається кількість відміток «Не подобається» (та інші дані: перегляди, відмітки «Подобається» тощо) за допомогою нашого API. Потім розширення відображає кількість відміток «Не подобається» та їх коефіцієнт на сторінці. Якщо ви ставите відмітки «Подобається» чи «Не подобається», це записується та надсилається до бази даних, щоб можна було екстраполювати точну їх кількість нелайків.", + bullet4: "Чи можу я поділитися з вами своїми відмітками «Не подобається»?", + bullet4text: + "Незабаром. Ми розглядаємо можливість використання Oauth або іншого API, доступного тільки для читання, з обмеженою областю дій, щоб творці могли ділитися своїми відмітками «Не подобається»", + bullet5: "Які дані ви збираєте та як вони обробляються?", + bullet5text: + 'Розширення збирає лише ті дані, які необхідні для правильної його роботи, такі як IP-адреси або ID відео, яке ви дивитеся. Ваші дані ніколи не будуть продані третім особам. Якщо ви хочете дізнатися більше про те, як ми забезпечуємо безпеку та конфіденційність, ознайомтесь з нашими ЧаПи по безпеці.', + bullet6: "Як працює API/серверна сторона?", + bullet6text: + "Серверна частина використовує архівні дані з тих пір, доки YouTube API все ще видавав кількість відміток «Не подобається», а також відмітки «Подобається»/«Не подобається» користувачів розширення та екстраполяцію. В найближчому майбутньому ми дозволимо творцям контенту легко та безпечно надсилати свої відмітки «Не подобається», а також ми додамо архівні дані ArchiveTeam (4,56 мільярди відео) до нашої поточної бази даних. Ви можете переглянути відео на цю тему.", + bullet7: + "Чому лічильник відміток «Не подобається» пише 'DISLIKES DISABLED'?", + bullet7text: + "Іноді на нещодавно завантаженому відео може з'являтися повідомлення 'DISLIKES DISABLED', навіть попри те, що автор не вимикав відмітки «Не подобається». Це пов’язано з тим, як ми визначаємо, чи вимкнені оцінки «Не подобається». Це повідомлення має зникнути через кілька годин або після отримання відмітки «Подобається»/«Не подобається» і оновлення сторінки (сподіваюся).", + }, + donate: { + name: "Підтримати", + subtitle: + "Ви можете підтримати пожертвою наші зусилля зробити Інтернет вільнішим!", + }, + links: { + name: "Посилання", + title: "Посилання проєкту", + subtitle: "Посилання на проєкт і його розробників", + contact: "Зв'язок зі мною", + translators: "Перекладачі", + coolProjects: "Круті проєкти", + sponsorBlockDescription: "пропускає вбудовану у відео рекламу", + filmotDescription: "пошук відео на YouTube по субтитрах", + }, +}; diff --git a/Website/layouts/default.vue b/Website/layouts/default.vue index 4d5e195d..49053dfd 100644 --- a/Website/layouts/default.vue +++ b/Website/layouts/default.vue @@ -102,12 +102,15 @@ export default { { name: "English", locale: "en" }, { name: "Español", locale: "es" }, { name: "Türkçe", locale: "tr" }, + { name: "Português (Brasil)", locale: "pt_BR" }, { name: "Русский", locale: "ru" }, { name: "Čeština", locale: "cs" }, { name: "日本語", locale: "ja" }, { name: "Français", locale: "fr" }, - // { name: "Deutsch", locale: "de" }, - // ... + { name: "Deutsch", locale: "de" }, + { name: "Українська", locale: "uk" }, + { name: "한국어", locale: "ko" }, + { name: "Polski", locale: "pl" }, ], alert: { show: false, diff --git a/Website/nuxt.config.js b/Website/nuxt.config.js index bf5bbbc7..d45867b9 100644 --- a/Website/nuxt.config.js +++ b/Website/nuxt.config.js @@ -5,7 +5,10 @@ import ru from "./_locales/ru"; import cs from "./_locales/cs"; import ja from "./_locales/ja"; import fr from "./_locales/fr"; -// import de from "./_locales/de"; +import uk from "./_locales/uk"; +import ko from "./_locales/ko"; +import pl from "./_locales/pl"; +import de from "./_locales/de"; // ... export default { // Global page headers: https://go.nuxtjs.dev/config-head @@ -50,7 +53,7 @@ export default { // Vuetify module configuration: https://go.nuxtjs.dev/config-vuetify vuetify: { lang: { - locales: { en, es, tr, ru, cs, ja, fr /* de, ...*/ }, + locales: { en, es, tr, ru, cs, ja, fr, uk, ko, pl, de, /*...*/ }, current: "en", }, theme: { diff --git a/Website/package.json b/Website/package.json index 10a61155..ac7c0074 100644 --- a/Website/package.json +++ b/Website/package.json @@ -3,10 +3,10 @@ "version": "1.1.0", "private": true, "scripts": { - "dev": "nuxt", + "dev": "set NODE_OPTIONS=--openssl-legacy-provider && nuxt", "build": "nuxt build", "start": "nuxt start", - "generate": "nuxt generate", + "generate": "set NODE_OPTIONS=--openssl-legacy-provider && nuxt generate", "lint": "eslint --fix --ext .js,.vue --ignore-path .eslintignore ." }, "dependencies": { diff --git a/Website/pages/debug.vue b/Website/pages/debug.vue index fa1e8633..928b8b2d 100644 --- a/Website/pages/debug.vue +++ b/Website/pages/debug.vue @@ -177,7 +177,7 @@ export default { setTimeout(() => { this.$axios .$get( - "https://raw.githubusercontent.com/Anarios/return-youtube-dislike/main/Extensions/combined/manifest-chrome.json" + "https://raw.githubusercontent.com/Anarios/return-youtube-dislike/main/Extensions/combined/manifest-chrome.json", ) .then((res) => { this.userInformation.extension.latestExtensionVersion = res.version; diff --git a/Website/pages/donate.vue b/Website/pages/donate.vue index ec63e14b..1a24d476 100644 --- a/Website/pages/donate.vue +++ b/Website/pages/donate.vue @@ -10,10 +10,6 @@ mdi-patreon Patreon - - mdi-cash-multiple - Yoomoney - mdi-bitcoin Crypto @@ -34,7 +30,6 @@ export default { }, data: () => ({ patreonLink: "https://www.patreon.com/returnyoutubedislike", - yoomoneyLink: "/pay/yoomoney", cryptoLink: "/pay/crypto", }), }; diff --git a/Website/pages/help.vue b/Website/pages/help.vue index 4bfc7a53..c364e675 100644 --- a/Website/pages/help.vue +++ b/Website/pages/help.vue @@ -133,7 +133,7 @@ export default { }, mounted() { fetch( - "https://raw.githubusercontent.com/Anarios/return-youtube-dislike/main/Extensions/combined/manifest-chrome.json" + "https://raw.githubusercontent.com/Anarios/return-youtube-dislike/main/Extensions/combined/manifest-chrome.json", ) .then((response) => response.json()) .then((json) => { diff --git a/Website/pages/index.vue b/Website/pages/index.vue index 3b21ceef..0819de3c 100644 --- a/Website/pages/index.vue +++ b/Website/pages/index.vue @@ -63,13 +63,13 @@ -
+

mdi-heart {{ $vuetify.lang.t("$vuetify.home.sponsors") }} @@ -108,17 +108,8 @@ export default { githubLink: "https://github.com/Anarios/return-youtube-dislike", discordLink: "https://discord.gg/mYnESY4Md5", sponsors: [ - { name: "Piepacker", link: "https://piepacker.com/" }, { - name: "Seed4.Me VPN", - link: "https://www.seed4.me/users/register?gift=ReturnYoutubeDislike", - }, - { - name: "PocketTube", - link: "https://yousub.info/?utm_source=returnyoutubedislike", - }, - { - name: "Become our sponsor", + name: "Become our sponsor and be listed here", link: "https://www.patreon.com/join/returnyoutubedislike/checkout?rid=8008601", }, ], @@ -134,13 +125,13 @@ export default { if (videoId !== lastVideoId && videoId.length === 11) { fetch( "https://returnyoutubedislikeapi.com/votes?videoId=" + - (lastVideoId = videoId) + (lastVideoId = videoId), ) .then((resp) => resp.json()) .then( (data) => (document.getElementById("output").innerText = - "Likes=" + data.likes + " Dislikes=" + data.dislikes) + "Likes=" + data.likes + " Dislikes=" + data.dislikes), ); } }; @@ -171,7 +162,8 @@ input { stroke: #f44; transition-property: opacity, transform; transform: scale(0) rotate(180deg); - animation: popin 1s 0.3s ease-in-out 1 forwards, + animation: + popin 1s 0.3s ease-in-out 1 forwards, tap 0.3s 1.7s ease-in-out 1 forwards; } diff --git a/Website/pages/install.vue b/Website/pages/install.vue index 5b7b9b61..122a2afa 100644 --- a/Website/pages/install.vue +++ b/Website/pages/install.vue @@ -66,23 +66,7 @@

mdi-android - Android   (NewPipe fork) - - - mdi-android - mdi-apple - mdi-linux - mdi-microsoft-windows -
- VueTube (WIP)
- pre-alpha -
- mdi-hammer-wrench + Android   (Tubular - a Newpipe Fork)
mdi-apple @@ -112,8 +96,7 @@ export default { "https://github.com/Anarios/return-youtube-dislike/raw/main/Extensions/UserScript/Return%20Youtube%20Dislike.user.js", iosJailbreakLink: "https://chariz.com/get/return-youtube-dislike/", - androidNewPipe: "https://github.com/polymorphicshade/NewPipe", - androidVueTube: "https://vuetube.app", + androidNewPipe: "https://github.com/polymorphicshade/Tubular", }; }, }; diff --git a/Website/pages/links.vue b/Website/pages/links.vue index cd6c4469..db12da5f 100644 --- a/Website/pages/links.vue +++ b/Website/pages/links.vue @@ -113,6 +113,18 @@ export default { tag: "NiniKo", lang: "Français", }, + { + tag: "dsty#1614", + lang: "Українська", + }, + { + tag: "itsbudyn#6502", + lang: "Polski", + }, + { + tag: "ArtisGraphics", + lang: "Deutsch" + } ], coolProjects: [ { diff --git a/Website/pages/pay/yoomoney.vue b/Website/pages/pay/yoomoney.vue deleted file mode 100644 index 95fccc01..00000000 --- a/Website/pages/pay/yoomoney.vue +++ /dev/null @@ -1,20 +0,0 @@ -