From 07cd1fd1efe0c47e4738189297a484cc2662aebf Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 30 Sep 2024 19:32:23 +0200 Subject: [PATCH 001/150] Support translation branches in Crowdin (#32174) --- .github/workflows/crowdin-download-stable.yml | 69 +++++++++++++++++++ .github/workflows/crowdin-upload.yml | 2 +- 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/crowdin-download-stable.yml diff --git a/.github/workflows/crowdin-download-stable.yml b/.github/workflows/crowdin-download-stable.yml new file mode 100644 index 0000000000..c0b402a5b9 --- /dev/null +++ b/.github/workflows/crowdin-download-stable.yml @@ -0,0 +1,69 @@ +name: Crowdin / Download translations (stable branches) +on: + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +jobs: + download-translations-stable: + runs-on: ubuntu-latest + if: github.repository == 'mastodon/mastodon' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Increase Git http.postBuffer + # This is needed due to a bug in Ubuntu's cURL version? + # See https://github.com/orgs/community/discussions/55820 + run: | + git config --global http.version HTTP/1.1 + git config --global http.postBuffer 157286400 + + # Download the translation files from Crowdin + - name: crowdin action + uses: crowdin/github-action@v2 + with: + upload_sources: false + upload_translations: false + download_translations: true + crowdin_branch_name: ${{ github.base_ref || github.ref_name }} + push_translations: false + create_pull_request: false + env: + CROWDIN_PROJECT_ID: ${{ vars.CROWDIN_PROJECT_ID }} + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} + + # As the files are extracted from a Docker container, they belong to root:root + # We need to fix this before the next steps + - name: Fix file permissions + run: sudo chown -R runner:docker . + + # This is needed to run the normalize step + - name: Set up Ruby environment + uses: ./.github/actions/setup-ruby + + - name: Run i18n normalize task + run: bundle exec i18n-tasks normalize + + # Create or update the pull request + - name: Create Pull Request + uses: peter-evans/create-pull-request@v7.0.1 + with: + commit-message: 'New Crowdin translations' + title: 'New Crowdin Translations for ${{ github.base_ref || github.ref_name }} (automated)' + author: 'GitHub Actions ' + body: | + New Crowdin translations, automated with GitHub Actions + + See `.github/workflows/crowdin-download.yml` + + This PR will be updated every day with new translations. + + Due to a limitation in GitHub Actions, checks are not running on this PR without manual action. + If you want to run the checks, then close and re-open it. + branch: i18n/crowdin/translations-${{ github.base_ref || github.ref_name }} + base: ${{ github.base_ref || github.ref_name }} + labels: i18n diff --git a/.github/workflows/crowdin-upload.yml b/.github/workflows/crowdin-upload.yml index b7a0a2b819..62ad1150bc 100644 --- a/.github/workflows/crowdin-upload.yml +++ b/.github/workflows/crowdin-upload.yml @@ -31,7 +31,7 @@ jobs: upload_sources: true upload_translations: false download_translations: false - crowdin_branch_name: main + crowdin_branch_name: ${{ github.base_ref || github.ref_name }} env: CROWDIN_PROJECT_ID: ${{ vars.CROWDIN_PROJECT_ID }} From 0b6d217b9e0c51cd4132f8e7d24c8df4b9f02f20 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 04:19:53 -0400 Subject: [PATCH 002/150] Use account display name for pretend blog example in attribution area (#32188) --- app/views/settings/verifications/show.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/settings/verifications/show.html.haml b/app/views/settings/verifications/show.html.haml index 5318b0767d..af9556d004 100644 --- a/app/views/settings/verifications/show.html.haml +++ b/app/views/settings/verifications/show.html.haml @@ -50,13 +50,13 @@ = image_tag frontend_asset_url('images/preview.png'), alt: '', class: 'status-card__image-image' .status-card__content %span.status-card__host - %span= t('author_attribution.s_blog', name: @account.username) + %span= t('author_attribution.s_blog', name: display_name(@account)) · %time.time-ago{ datetime: 1.year.ago.to_date.iso8601 } %strong.status-card__title= t('author_attribution.example_title') .more-from-author = logo_as_symbol(:icon) - = t('author_attribution.more_from_html', name: link_to(root_url, class: 'story__details__shared__author-link') { image_tag(@account.avatar.url, class: 'account__avatar', width: 16, height: 16, alt: '') + content_tag(:bdi, display_name(@account)) }) + = t('author_attribution.more_from_html', name: link_to(root_url, class: 'story__details__shared__author-link') { image_tag(@account.avatar.url, class: 'account__avatar', width: 16, height: 16, alt: '') + tag.bdi(display_name(@account)) }) .actions = f.button :button, t('generic.save_changes'), type: :submit From 5839ee434ba8510f9eb50804ee4530dacf146e97 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 08:21:17 +0000 Subject: [PATCH 003/150] New Crowdin Translations (automated) (#32195) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/ar.json | 3 +- app/javascript/mastodon/locales/el.json | 8 ++++ app/javascript/mastodon/locales/fr-CA.json | 1 + app/javascript/mastodon/locales/fr.json | 1 + app/javascript/mastodon/locales/gd.json | 10 ++++- app/javascript/mastodon/locales/hu.json | 6 +++ app/javascript/mastodon/locales/kab.json | 4 +- app/javascript/mastodon/locales/pt-BR.json | 8 +++- config/locales/doorkeeper.el.yml | 1 + config/locales/el.yml | 43 ++++++++++++++++++++++ config/locales/eo.yml | 5 +++ config/locales/gd.yml | 6 ++- config/locales/kab.yml | 9 +++++ config/locales/pt-BR.yml | 2 +- 14 files changed, 101 insertions(+), 6 deletions(-) diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index 18830708db..b11382cf03 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -84,6 +84,7 @@ "alert.rate_limited.title": "معدل الطلبات محدود", "alert.unexpected.message": "لقد طرأ خطأ غير متوقّع.", "alert.unexpected.title": "المعذرة!", + "alt_text_badge.title": "نص بديل", "announcement.announcement": "إعلان", "attachments_list.unprocessed": "(غير معالَج)", "audio.hide": "إخفاء المقطع الصوتي", @@ -758,7 +759,7 @@ "status.history.edited": "عدله {name} {date}", "status.load_more": "حمّل المزيد", "status.media.open": "اضغط للفتح", - "status.media.show": "اضغط لإظهاره", + "status.media.show": "اضغط لإظهارها", "status.media_hidden": "وسائط مخفية", "status.mention": "أذكُر @{name}", "status.more": "المزيد", diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index 85f893c63d..2565f5da68 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -85,6 +85,7 @@ "alert.rate_limited.title": "Περιορισμός συχνότητας", "alert.unexpected.message": "Προέκυψε απροσδόκητο σφάλμα.", "alert.unexpected.title": "Ουπς!", + "alt_text_badge.title": "Εναλλακτικό κείμενο", "announcement.announcement": "Ανακοίνωση", "attachments_list.unprocessed": "(μη επεξεργασμένο)", "audio.hide": "Απόκρυψη αρχείου ήχου", @@ -221,6 +222,8 @@ "domain_block_modal.they_cant_follow": "Κανείς από αυτόν τον διακομιστή δεν μπορεί να σε ακολουθήσει.", "domain_block_modal.they_wont_know": "Δεν θα ξέρουν ότι έχουν αποκλειστεί.", "domain_block_modal.title": "Αποκλεισμός τομέα;", + "domain_block_modal.you_will_lose_num_followers": "Θα χάσετε {followersCount, plural, one {{followersCountDisplay} ακόλουθο} other {{followersCountDisplay} ακόλουθους}} και {followingCount, plural, one {{followingCountDisplay} άτομο που ακολουθείτε} other {{followingCountDisplay} άτομα που ακολουθείτε}}.", + "domain_block_modal.you_will_lose_relationships": "Θα χάσετε όλους τους ακόλουθους και τα άτομα που ακολουθείτε από αυτόν τον διακομιστή.", "domain_block_modal.you_wont_see_posts": "Δεν θα βλέπεις αναρτήσεις ή ειδοποιήσεις από χρήστες σε αυτόν το διακομιστή.", "domain_pill.activitypub_lets_connect": "Σού επιτρέπει να συνδεθείς και να αλληλεπιδράσεις με τους ανθρώπους όχι μόνο στο Mastodon, αλλά και σε διαφορετικές κοινωνικές εφαρμογές.", "domain_pill.activitypub_like_language": "Το ActivityPub είναι σαν τη γλώσσα Mastodon μιλάει με άλλα κοινωνικά δίκτυα.", @@ -849,6 +852,11 @@ "upload_error.poll": "Στις δημοσκοπήσεις δεν επιτρέπεται η μεταφόρτωση αρχείου.", "upload_form.audio_description": "Περιγραφή για άτομα με προβλήματα ακοής", "upload_form.description": "Περιγραφή για άτομα με προβλήματα όρασης", + "upload_form.drag_and_drop.instructions": "Για να επιλέξετε ένα συνημμένο αρχείο πολυμέσων, πατήστε το Space ή το Enter. Ενώ το σέρνετε, χρησιμοποιήστε τα πλήκτρα βέλους για να μετακινήσετε το συνημμένο αρχείο πολυμέσων προς οποιαδήποτε κατεύθυνση. Πατήστε ξανά το Space ή το Enter για να αποθέσετε το συνημμένο αρχείο πολυμέσων στη νέα του θέση ή πατήστε το Escape για ακύρωση.", + "upload_form.drag_and_drop.on_drag_cancel": "Η μετακίνηση ακυρώθηκε. Έγινε απόθεση του συνημμένου αρχείου πολυμέσων «{item}».", + "upload_form.drag_and_drop.on_drag_end": "Έγινε απόθεση του συνημμένου αρχείου πολυμέσων «{item}».", + "upload_form.drag_and_drop.on_drag_over": "Έγινε μετακίνηση του συνημμένου αρχείου πολυμέσων «{item}».", + "upload_form.drag_and_drop.on_drag_start": "Έγινε επιλογή του συνημμένου αρχείου πολυμέσων «{item}».", "upload_form.edit": "Επεξεργασία", "upload_form.thumbnail": "Αλλαγή μικρογραφίας", "upload_form.video_description": "Περιγραφή για άτομα με προβλήματα ακοής ή όρασης", diff --git a/app/javascript/mastodon/locales/fr-CA.json b/app/javascript/mastodon/locales/fr-CA.json index bdceb9bd30..3349be4fad 100644 --- a/app/javascript/mastodon/locales/fr-CA.json +++ b/app/javascript/mastodon/locales/fr-CA.json @@ -852,6 +852,7 @@ "upload_error.poll": "L’envoi de fichiers n’est pas autorisé avec les sondages.", "upload_form.audio_description": "Décrire pour les personnes ayant des difficultés d’audition", "upload_form.description": "Décrire pour les malvoyants", + "upload_form.drag_and_drop.instructions": "Pour choisir un média joint, appuyez sur la touche espace ou entrée. Tout en faisant glisser, utilisez les touches fléchées pour déplacer le fichier média dans une direction donnée. Appuyez à nouveau sur la touche espace ou entrée pour déposer le fichier média dans sa nouvelle position, ou appuyez sur la touche Echap pour annuler.", "upload_form.edit": "Modifier", "upload_form.thumbnail": "Changer la vignette", "upload_form.video_description": "Décrire pour les personnes ayant des problèmes de vue ou d'audition", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 2acad02093..5c4e582a87 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -852,6 +852,7 @@ "upload_error.poll": "L’envoi de fichiers n’est pas autorisé avec les sondages.", "upload_form.audio_description": "Décrire pour les personnes ayant des difficultés d’audition", "upload_form.description": "Décrire pour les malvoyant·e·s", + "upload_form.drag_and_drop.instructions": "Pour choisir un média joint, appuyez sur la touche espace ou entrée. Tout en faisant glisser, utilisez les touches fléchées pour déplacer le fichier média dans une direction donnée. Appuyez à nouveau sur la touche espace ou entrée pour déposer le fichier média dans sa nouvelle position, ou appuyez sur la touche Echap pour annuler.", "upload_form.edit": "Modifier", "upload_form.thumbnail": "Changer la vignette", "upload_form.video_description": "Décrire pour les personnes ayant des problèmes de vue ou d'audition", diff --git a/app/javascript/mastodon/locales/gd.json b/app/javascript/mastodon/locales/gd.json index ecbc11f3a2..f6d3f172ca 100644 --- a/app/javascript/mastodon/locales/gd.json +++ b/app/javascript/mastodon/locales/gd.json @@ -85,6 +85,7 @@ "alert.rate_limited.title": "Cuingeachadh ùine", "alert.unexpected.message": "Thachair mearachd ris nach robh dùil.", "alert.unexpected.title": "Oich!", + "alt_text_badge.title": "Roghainn teacsa", "announcement.announcement": "Brath-fios", "attachments_list.unprocessed": "(gun phròiseasadh)", "audio.hide": "Falaich an fhuaim", @@ -221,6 +222,8 @@ "domain_block_modal.they_cant_follow": "Chan urrainn do neach sam bith a th’ air an fhrithealaiche seo do leantainn.", "domain_block_modal.they_wont_know": "Cha bhi fios aca gun deach am bacadh.", "domain_block_modal.title": "A bheil thu airson an àrainn a bhacadh?", + "domain_block_modal.you_will_lose_num_followers": "Caillidh tu {followersCount, plural, one {{followersCountDisplay} neach-leantainn} two {{followersCountDisplay} luchd-leantainn} few {{followersCountDisplay} luchd-leantainn} other {{followersCountDisplay} luchd-leantainn}} ’s {followingCount, plural, one {{followingCountDisplay} neach a tha thu a’ leantainn} two {{followingCountDisplay} daoine a tha thu a’ leantainn} few {{followingCountDisplay} daoine a tha thu a’ leantainn} other {{followingCountDisplay} daoine a tha thu a’ leantainn}}.", + "domain_block_modal.you_will_lose_relationships": "Caillidh tu a h-uile luchd-leantainn ’s neach a leanas tu air an fhrithealaiche seo.", "domain_block_modal.you_wont_see_posts": "Chan fhaic thu postaichean no brathan o chleachdaichean a th’ air an fhrithealaiche seo.", "domain_pill.activitypub_lets_connect": "Leigidh e leat ceangal a dhèanamh ri daoine chan ann air Mastodon a-mhàin ach air feadh aplacaidean sòisealta eile cuideachd agus conaltradh leotha.", "domain_pill.activitypub_like_language": "Tha ActivityPub coltach ri cànan a bhruidhneas Mastodon ri lìonraidhean sòisealta eile.", @@ -330,7 +333,7 @@ "footer.about": "Mu dhèidhinn", "footer.directory": "Eòlaire nam pròifil", "footer.get_app": "Faigh an aplacaid", - "footer.invite": "Thoir cuireadh do dhaoine", + "footer.invite": "Thoir cuireadh", "footer.keyboard_shortcuts": "Ath-ghoiridean a’ mheur-chlàir", "footer.privacy_policy": "Poileasaidh prìobhaideachd", "footer.source_code": "Seall am bun-tùs", @@ -849,6 +852,11 @@ "upload_error.poll": "Chan fhaod thu faidhle a luchdadh suas an cois cunntais-bheachd.", "upload_form.audio_description": "Mìnich e dhan fheadhainn le èisteachd bheag", "upload_form.description": "Mìnich e dhan fheadhainn le cion-lèirsinne", + "upload_form.drag_and_drop.instructions": "Airson ceanglachan meadhain a thogail, brùth air space no enter. Fhad ’ a bhios tu ’ga shlaodadh, cleachd na h-iuchraichean-saighde airson an ceanglachan meadhain a ghluasad gu comhair sam bith. Brùth air space no enter a-rithist airson an ceanglachen meadhain a leigeil às air an ionad ùr aige no brùth air escape airson sgur dheth.", + "upload_form.drag_and_drop.on_drag_cancel": "Chaidh sgur dhen t-slaodadh. Chaidh an ceanglachan meadhain {item} a leigeil às.", + "upload_form.drag_and_drop.on_drag_end": "Chaidh an ceanglachan meadhain {item} a leigeil às.", + "upload_form.drag_and_drop.on_drag_over": "Chaidh an ceanglachan meadhain {item} a ghluasad.", + "upload_form.drag_and_drop.on_drag_start": "Chaidh an ceanglachan meadhain {item} a thogail.", "upload_form.edit": "Deasaich", "upload_form.thumbnail": "Atharraich an dealbhag", "upload_form.video_description": "Mìnich e dhan fheadhainn le èisteachd bheag no cion-lèirsinne", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index 34a9949afd..8baf584b78 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -85,6 +85,7 @@ "alert.rate_limited.title": "Adatforgalom korlátozva", "alert.unexpected.message": "Váratlan hiba történt.", "alert.unexpected.title": "Hoppá!", + "alt_text_badge.title": "Helyettesítő szöveg", "announcement.announcement": "Közlemény", "attachments_list.unprocessed": "(feldolgozatlan)", "audio.hide": "Hang elrejtése", @@ -851,6 +852,11 @@ "upload_error.poll": "Szavazásnál nem lehet fájlt feltölteni.", "upload_form.audio_description": "Leírás siket vagy hallássérült emberek számára", "upload_form.description": "Leírás vak vagy gyengénlátó emberek számára", + "upload_form.drag_and_drop.instructions": "Egy médiamelléklet kiválasztásához nyomjon Szóközt vagy Entert. Húzás közben használja a nyílgombokat a médiamelléklet adott irányba történő mozgatásához. A médiamelléklet új pozícióba helyezéséhez nyomja meg a Szóközt vagy az Entert, vagy a megszakításhoz nyomja meg az Esc gombot.", + "upload_form.drag_and_drop.on_drag_cancel": "Az áthúzást megszakította. A(z) {item} médiamelléklet el lett dobva.", + "upload_form.drag_and_drop.on_drag_end": "A(z) {item} médiamelléklet el lett dobva.", + "upload_form.drag_and_drop.on_drag_over": "A(z) {item} médiamelléklet át lett helyezve.", + "upload_form.drag_and_drop.on_drag_start": "A(z) {item} médiamelléklet fel lett véve.", "upload_form.edit": "Szerkesztés", "upload_form.thumbnail": "Bélyegkép megváltoztatása", "upload_form.video_description": "Leírás siket, hallássérült, vak vagy gyengénlátó emberek számára", diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json index 9e2c9f3af8..ff06c9c464 100644 --- a/app/javascript/mastodon/locales/kab.json +++ b/app/javascript/mastodon/locales/kab.json @@ -1,5 +1,5 @@ { - "about.blocks": "Ulac agbur", + "about.blocks": "Iqeddacen yettwaɛassen", "about.contact": "Anermis:", "about.disclaimer": "Mastodon d aseɣẓan ilelli, d aseɣẓan n uɣbalu yeldin, d tnezzut n Mastodon gGmbH.", "about.domain_blocks.no_reason_available": "Ulac taɣẓint", @@ -550,6 +550,7 @@ "report_notification.attached_statuses": "{count, plural, one {{count} n tsuffeɣt} other {{count} n tsuffiɣin}} ttwaqnent", "report_notification.categories.legal": "Azerfan", "report_notification.categories.other": "Ayen nniḍen", + "report_notification.categories.other_sentence": "ayen nniḍen", "report_notification.categories.spam": "Aspam", "report_notification.categories.spam_sentence": "aspam", "report_notification.open": "Ldi aneqqis", @@ -589,6 +590,7 @@ "status.direct": "Bder-d @{name} weḥd-s", "status.direct_indicator": "Abdar uslig", "status.edit": "Ẓreg", + "status.edited": "Taẓrigt taneggarut {date}", "status.edited_x_times": "Tettwaẓreg {count, plural, one {{count} n tikkelt} other {{count} n tikkal}}", "status.embed": "Awi-d tangalt n weslaɣ", "status.favourite": "Amenyaf", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index d1a3ecdaa7..ab5701cde0 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -437,6 +437,7 @@ "lightbox.next": "Próximo", "lightbox.previous": "Anterior", "lightbox.zoom_in": "Voltar para o tamanho real", + "lightbox.zoom_out": "Zoom para ajustar", "limited_account_hint.action": "Exibir perfil mesmo assim", "limited_account_hint.title": "Este perfil foi ocultado pelos moderadores do {domain}.", "link_preview.author": "Por {name}", @@ -813,7 +814,7 @@ "status.reblogs.empty": "Nada aqui. Quando alguém der boost, o usuário aparecerá aqui.", "status.redraft": "Excluir e rascunhar", "status.remove_bookmark": "Remover do Salvos", - "status.replied_in_thread": "Respondido na discussão", + "status.replied_in_thread": "Respondido na conversa", "status.replied_to": "Em resposta a {name}", "status.reply": "Responder", "status.replyAll": "Responder a conversa", @@ -851,6 +852,11 @@ "upload_error.poll": "Mídias não podem ser anexadas em toots com enquetes.", "upload_form.audio_description": "Descrever para deficientes auditivos", "upload_form.description": "Descrever para deficientes visuais", + "upload_form.drag_and_drop.instructions": "Para pegar um anexo de mídia, pressione espaço ou enter. Enquanto arrastar, use as setas do teclado para mover o anexo de mídia em qualquer direção. Pressione espaço ou insira novamente para soltar o anexo de mídia em sua nova posição, ou pressione escape para cancelar.", + "upload_form.drag_and_drop.on_drag_cancel": "O arrastamento foi cancelado. O anexo da mídia {item} foi descartado.", + "upload_form.drag_and_drop.on_drag_end": "O anexo {item} foi removido.", + "upload_form.drag_and_drop.on_drag_over": "O anexo de mídia {item} foi movido.", + "upload_form.drag_and_drop.on_drag_start": "Foi coletado o anexo de mídia {item}.", "upload_form.edit": "Editar", "upload_form.thumbnail": "Alterar miniatura", "upload_form.video_description": "Descrever para deficientes auditivos ou visuais", diff --git a/config/locales/doorkeeper.el.yml b/config/locales/doorkeeper.el.yml index 59877b6bd0..984eff8871 100644 --- a/config/locales/doorkeeper.el.yml +++ b/config/locales/doorkeeper.el.yml @@ -60,6 +60,7 @@ el: error: title: Εμφανίστηκε σφάλμα new: + prompt_html: Το %{client_name} επιθυμεί το δικαίωμα πρόσβασης στον λογαριασμό σας. Εγκρίνετε αυτό το αίτημα μόνο αν αναγνωρίζετε και εμπιστεύεστε αυτήν την πηγή. review_permissions: Ανασκόπηση δικαιωμάτων title: Απαιτείται έγκριση show: diff --git a/config/locales/el.yml b/config/locales/el.yml index 610ae40265..4496ec51a6 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -953,6 +953,7 @@ el: used_by_over_week: one: Χρησιμοποιήθηκε από ένα άτομο την τελευταία εβδομάδα other: Χρησιμοποιήθηκε από %{count} άτομα την τελευταία εβδομάδα + title: Προτάσεις και τάσεις trending: Τάσεις warning_presets: add_new: Πρόσθεση νέου @@ -1037,7 +1038,9 @@ el: guide_link_text: Μπορεί να συνεισφέρει ο οποιοσδήποτε. sensitive_content: Ευαίσθητο περιεχόμενο application_mailer: + notification_preferences: Αλλαγή προτιμήσεων email salutation: "%{name}," + settings: 'Αλλαγή προτιμήσεων email: %{link}' unsubscribe: Κατάργηση εγγραφής view: 'Προβολή:' view_profile: Προβολή προφίλ @@ -1084,6 +1087,7 @@ el: or_log_in_with: Ή συνδέσου με privacy_policy_agreement_html: Έχω διαβάσει και συμφωνώ με την πολιτική απορρήτου progress: + confirm: Επιβεβαίωση email details: Τα στοιχεία σας review: Η αξιολόγησή μας rules: Αποδοχή κανόνων @@ -1123,6 +1127,8 @@ el: view_strikes: Προβολή προηγούμενων ποινών εναντίον του λογαριασμού σας too_fast: Η φόρμα υποβλήθηκε πολύ γρήγορα, προσπαθήστε ξανά. use_security_key: Χρήση κλειδιού ασφαλείας + author_attribution: + example_title: Δείγμα κειμένου challenge: confirm: Συνέχεια hint_html: "Συμβουλή: Δεν θα σου ζητήσουμε τον κωδικό ασφαλείας σου ξανά για την επόμενη ώρα." @@ -1342,7 +1348,10 @@ el: time_started: Ξεκίνησε στις titles: blocking: Εισαγωγή αποκλεισμένων λογαριασμών + bookmarks: Εισαγωγή σελιδοδεικτών + domain_blocking: Εισαγωγή αποκλεισμένων τομέων following: Εισαγωγή λογαριασμών που ακολουθείτε + lists: Εισαγωγή λιστών type: Τύπος εισαγωγής type_groups: destructive: Μπλοκ & σίγαση @@ -1351,6 +1360,7 @@ el: bookmarks: Σελιδοδείκτες domain_blocking: Λίστα αποκλεισμένων τομέων following: Λίστα ατόμων που ακολουθείτε + lists: Λίστες muting: Λίστα αποσιωπήσεων upload: Μεταμόρφωση invites: @@ -1365,6 +1375,7 @@ el: '86400': 1 μέρα expires_in_prompt: Ποτέ generate: Δημιουργία συνδέσμου πρόσκλησης + invalid: Αυτή η πρόσκληση δεν είναι έγκυρη invited_by: 'Σε προσκάλεσε ο/η:' max_uses: one: 1 χρήσης @@ -1388,6 +1399,11 @@ el: failed_sign_in_html: Αποτυχημένη προσπάθεια σύνδεσης με %{method} από %{ip} (%{browser}) successful_sign_in_html: Επιτυχής σύνδεση με %{method} από %{ip} (%{browser}) title: Ιστορικό ελέγχου ταυτότητας + mail_subscriptions: + unsubscribe: + action: Ναι, κατάργηση συνδρομής + complete: Η συνδρομή καταργήθηκε + title: Κατάργηση συνδρομής media_attachments: validations: images_and_video: Δεν γίνεται να προσθέσεις βίντεο σε ανάρτηση που ήδη περιέχει εικόνες @@ -1467,6 +1483,7 @@ el: update: subject: "%{name} επεξεργάστηκε μια ανάρτηση" notifications: + email_events: Συμβάντα για ειδοποιήσεις μέσω email email_events_hint: 'Επέλεξε συμβάντα για τα οποία θέλεις να λαμβάνεις ειδοποιήσεις μέσω email:' number: human: @@ -1507,12 +1524,18 @@ el: other: Άλλες posting_defaults: Προεπιλογές ανάρτησης public_timelines: Δημόσιες ροές + privacy: + privacy: Απόρρητο + search: Αναζήτηση privacy_policy: title: Πολιτική Απορρήτου reactions: errors: limit_reached: Το όριο διαφορετικών αντιδράσεων ξεπεράστηκε unrecognized_emoji: δεν είναι ένα αναγνωρισμένο emoji + redirects: + prompt: Αν εμπιστεύεστε αυτόν τον σύνδεσμο, κάντε κλικ σε αυτόν για να συνεχίσετε. + title: Αποχωρείτε από το %{instance}. relationships: activity: Δραστηριότητα λογαριασμού confirm_follow_selected_followers: Είσαι βέβαιος ότι θες να ακολουθήσεις τους επιλεγμένους ακόλουθους; @@ -1548,6 +1571,9 @@ el: over_daily_limit: Έχεις υπερβεί το όριο των %{limit} προγραμματισμένων αναρτήσεων για εκείνη τη μέρα over_total_limit: Έχεις υπερβεί το όριο των %{limit} προγραμματισμένων αναρτήσεων too_soon: Η προγραμματισμένη ημερομηνία πρέπει να είναι στο μέλλον + self_destruct: + lead_html: Δυστυχώς, το %{domain} κλείνει οριστικά. Αν είχατε λογαριασμό εκεί, δεν θα μπορείτε να συνεχίσετε τη χρήση του, αλλά μπορείτε ακόμα να ζητήσετε ένα αντίγραφο ασφαλείας των δεδομένων σας. + title: Αυτός ο διακομιστής κλείνει οριστικά sessions: activity: Τελευταία δραστηριότητα browser: Φυλλομετρητής @@ -1604,10 +1630,12 @@ el: delete: Διαγραφή λογαριασμού development: Ανάπτυξη edit_profile: Επεξεργασία προφίλ + export: Εξαγωγή featured_tags: Παρεχόμενες ετικέτες import: Εισαγωγή import_and_export: Εισαγωγή και εξαγωγή migrate: Μετακόμιση λογαριασμού + notifications: Ειδοποιήσεις μέσω email preferences: Προτιμήσεις profile: Προφίλ relationships: Ακολουθείς και σε ακολουθούν @@ -1615,6 +1643,12 @@ el: strikes: Παραπτώματα από ομάδα συντονισμού two_factor_authentication: Πιστοποίηση 2 παραγόντων webauthn_authentication: Κλειδιά ασφαλείας + severed_relationships: + download: Λήψη (%{count}) + event_type: + account_suspension: Αναστολή λογαριασμού (%{target_name}) + domain_block: Αναστολή διακομιστή (%{target_name}) + type: Συμβάν statuses: attached: audio: @@ -1697,11 +1731,13 @@ el: contrast: Mastodon (Υψηλή αντίθεση) default: Mastodon (Σκοτεινό) mastodon-light: Mastodon (Ανοιχτόχρωμο) + system: Αυτόματο (θέμα συστήματος) time: formats: default: "%b %d, %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d %b %Y, %H:%M %Z" two_factor_authentication: add: Προσθήκη disable: Απενεργοποίηση 2FA @@ -1789,6 +1825,10 @@ el: feature_action: Μάθε περισσότερα feature_audience: Το Mastodon σού παρέχει μια μοναδική δυνατότητα διαχείρισης του κοινού σου χωρίς μεσάζοντες. Το Mastodon όταν αναπτύσσεται στη δική σου υποδομή σού επιτρέπει να ακολουθείς και να ακολουθείσαι από οποιονδήποτε άλλο συνδεδεμένο διακομιστή Mastodon και κανείς δεν τον ελέγχει, εκτός από σένα. feature_audience_title: Χτίσε το κοινό σου με σιγουριά + post_action: Σύνθεση + share_action: Κοινοποίηση + share_title: Μοιραστείτε το προφίλ σας στο Mastodon + sign_in_action: Σύνδεση subject: Καλώς ήρθες στο Mastodon title: Καλώς όρισες, %{name}! users: @@ -1798,7 +1838,10 @@ el: otp_lost_help_html: Αν χάσεις πρόσβαση και στα δύο, μπορείς να επικοινωνήσεις με %{email} signed_in_as: 'Έχεις συνδεθεί ως:' verification: + here_is_how: Δείτε πώς verification: Πιστοποίηση + verified_links: Οι επαληθευμένοι σύνδεσμοι σας + website_verification: Επαλήθευση ιστοτόπου webauthn_credentials: add: Προσθήκη νέου κλειδιού ασφαλείας create: diff --git a/config/locales/eo.yml b/config/locales/eo.yml index a3f968d139..10b297f1a8 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -218,18 +218,22 @@ eo: update_custom_emoji: Ĝisdatigi proprajn emoĝiojn update_domain_block: Ĝigdatigi domajnan blokadon update_ip_block: Krei IP-regulon + update_report: Ĝisdatigo de Raporto update_status: Ĝisdatigi afiŝon update_user_role: Ĝisdatigi rolon actions: approve_appeal_html: "%{name} aprobis apelacion kontraŭ moderiga decido de %{target}" approve_user_html: "%{name} aprobis registriĝon de %{target}" assigned_to_self_report_html: "%{name} asignis signalon %{target} al si mem" + change_email_user_html: "%{name} ŝanĝis retadreson de uzanto %{target}" change_role_user_html: "%{name} ŝanĝis rolon de %{target}" + confirm_user_html: "%{name} konfirmis retadreson de uzanto %{target}" create_account_warning_html: "%{name} sendis averton al %{target}" create_announcement_html: "%{name} kreis novan anoncon %{target}" create_custom_emoji_html: "%{name} alŝutis novan emoĝion %{target}" create_domain_allow_html: "%{name} aldonis domajnon %{target} al la blanka listo" create_domain_block_html: "%{name} blokis domajnon %{target}" + create_email_domain_block_html: "%{name} blokis retpoŝtan domajnon %{target}" create_ip_block_html: "%{name} kreis regulon por IP %{target}" create_unavailable_domain_html: "%{name} ĉesis sendon al domajno %{target}" create_user_role_html: "%{name} kreis rolon de %{target}" @@ -238,6 +242,7 @@ eo: destroy_custom_emoji_html: "%{name} forigis emoĝion %{target}" destroy_domain_allow_html: "%{name} forigis domajnon %{target} el la blanka listo" destroy_domain_block_html: "%{name} malblokis domajnon %{target}" + destroy_email_domain_block_html: "%{name} malblokis retpoŝtan domajnon %{target}" destroy_instance_html: "%{name} forigis domajnon %{target}" destroy_ip_block_html: "%{name} forigis regulon por IP %{target}" destroy_status_html: "%{name} forigis mesaĝojn de %{target}" diff --git a/config/locales/gd.yml b/config/locales/gd.yml index 90d03c74e1..a030b0d185 100644 --- a/config/locales/gd.yml +++ b/config/locales/gd.yml @@ -903,6 +903,9 @@ gd: message_html: Cha do mhìnich thu riaghailtean an fhrithealaiche fhathast. sidekiq_process_check: message_html: Chan eil pròiseas Sidekiq sam bith a ruith dhan chiutha/dha na ciuthan %{value}. Thoir sùil air an rèiteachadh Sidekiq agad + software_version_check: + action: Faic na h-ùrachaidhean a tha ri fhaighinn + message_html: Tha ùrachadh Mastodon ri fhaighinn. software_version_critical_check: action: Faic na h-ùrachaidhean a tha ri fhaighinn message_html: Tha ùrachadh èiginneach air Mastodon ri fhaighinn, ùraich cho luath ’s a ghabhas. @@ -1021,7 +1024,7 @@ gd: delete: Sguab às edit_preset: Deasaich rabhadh ro-shuidhichte empty: Cha do mhìnich thu ro-sheataichean rabhaidhean fhathast. - title: Ro-sheataichean rabhaidhean + title: Rabhaidhean ro-shocraichte webhooks: add_new: Cuir puing-dheiridh ris delete: Sguab às @@ -1744,6 +1747,7 @@ gd: delete: Sguabadh às cunntais development: Leasachadh edit_profile: Deasaich a’ phròifil + export: Às-phortadh featured_tags: Tagaichean hais brosnaichte import: Ion-phortadh import_and_export: Ion-phortadh ⁊ às-phortadh diff --git a/config/locales/kab.yml b/config/locales/kab.yml index 12bda84d46..993488f1fc 100644 --- a/config/locales/kab.yml +++ b/config/locales/kab.yml @@ -264,6 +264,8 @@ kab: domain: Taɣult new: create: Rnu taɣult + export_domain_allows: + no_file: Ula d yiwen ufaylu ma yettwafran export_domain_blocks: no_file: Ulac afaylu yettwafernen follow_recommendations: @@ -529,6 +531,10 @@ kab: account_status: Addad n umiḍan functional: Amiḍan-inek·inem yetteddu s lekmal-is. use_security_key: Seqdec tasarut n teɣlist + author_attribution: + example_title: Amedya n weḍris + more_from_html: Ugar s ɣur %{name} + s_blog: Ablug n %{name} challenge: confirm: Kemmel invalid_password: Yir awal uffir @@ -685,6 +691,9 @@ kab: subject: Yuder-ik·ikem-id %{name} reblog: subject: "%{name} yesselha addad-ik·im" + title: Azuzer amaynut + status: + subject: "%{name} akken i d-y·t·essufeɣ" number: human: decimal_units: diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 5e7317c5fb..6451e7c601 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -1888,7 +1888,7 @@ pt-BR: none: Aviso sensitive: Conta marcada como sensível silence: Conta silenciada - suspend: Conta banida + suspend: Conta suspensa welcome: apps_android_action: Disponível no Google Play apps_ios_action: Disponível na App Store From 1be55ce24418ea149a9ca0def237a76f4c6501af Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Tue, 1 Oct 2024 10:22:14 +0200 Subject: [PATCH 004/150] Fix follow notifications from streaming being grouped (#32179) --- .../mastodon/actions/notification_groups.ts | 4 + .../mastodon/reducers/notification_groups.ts | 79 ++++++++++--------- 2 files changed, 46 insertions(+), 37 deletions(-) diff --git a/app/javascript/mastodon/actions/notification_groups.ts b/app/javascript/mastodon/actions/notification_groups.ts index b40b04f8cc..a359913e61 100644 --- a/app/javascript/mastodon/actions/notification_groups.ts +++ b/app/javascript/mastodon/actions/notification_groups.ts @@ -70,6 +70,10 @@ function dispatchAssociatedRecords( const supportedGroupedNotificationTypes = ['favourite', 'reblog']; +export function shouldGroupNotificationType(type: string) { + return supportedGroupedNotificationTypes.includes(type); +} + export const fetchNotifications = createDataLoadingThunk( 'notificationGroups/fetch', async (_params, { getState }) => diff --git a/app/javascript/mastodon/reducers/notification_groups.ts b/app/javascript/mastodon/reducers/notification_groups.ts index f3c83ccd8d..375e643876 100644 --- a/app/javascript/mastodon/reducers/notification_groups.ts +++ b/app/javascript/mastodon/reducers/notification_groups.ts @@ -21,6 +21,7 @@ import { unmountNotifications, refreshStaleNotificationGroups, pollRecentNotifications, + shouldGroupNotificationType, } from 'mastodon/actions/notification_groups'; import { disconnectTimeline, @@ -205,46 +206,50 @@ function processNewNotification( groups: NotificationGroupsState['groups'], notification: ApiNotificationJSON, ) { - const existingGroupIndex = groups.findIndex( - (group) => - group.type !== 'gap' && group.group_key === notification.group_key, - ); + if (shouldGroupNotificationType(notification.type)) { + const existingGroupIndex = groups.findIndex( + (group) => + group.type !== 'gap' && group.group_key === notification.group_key, + ); - // In any case, we are going to add a group at the top - // If there is currently a gap at the top, now is the time to update it - if (groups.length > 0 && groups[0]?.type === 'gap') { - groups[0].maxId = notification.id; - } - - if (existingGroupIndex > -1) { - const existingGroup = groups[existingGroupIndex]; - - if ( - existingGroup && - existingGroup.type !== 'gap' && - !existingGroup.sampleAccountIds.includes(notification.account.id) // This can happen for example if you like, then unlike, then like again the same post - ) { - // Update the existing group - if ( - existingGroup.sampleAccountIds.unshift(notification.account.id) > - NOTIFICATIONS_GROUP_MAX_AVATARS - ) - existingGroup.sampleAccountIds.pop(); - - existingGroup.most_recent_notification_id = notification.id; - existingGroup.page_max_id = notification.id; - existingGroup.latest_page_notification_at = notification.created_at; - existingGroup.notifications_count += 1; - - groups.splice(existingGroupIndex, 1); - mergeGapsAround(groups, existingGroupIndex); - - groups.unshift(existingGroup); + // In any case, we are going to add a group at the top + // If there is currently a gap at the top, now is the time to update it + if (groups.length > 0 && groups[0]?.type === 'gap') { + groups[0].maxId = notification.id; + } + + if (existingGroupIndex > -1) { + const existingGroup = groups[existingGroupIndex]; + + if ( + existingGroup && + existingGroup.type !== 'gap' && + !existingGroup.sampleAccountIds.includes(notification.account.id) // This can happen for example if you like, then unlike, then like again the same post + ) { + // Update the existing group + if ( + existingGroup.sampleAccountIds.unshift(notification.account.id) > + NOTIFICATIONS_GROUP_MAX_AVATARS + ) + existingGroup.sampleAccountIds.pop(); + + existingGroup.most_recent_notification_id = notification.id; + existingGroup.page_max_id = notification.id; + existingGroup.latest_page_notification_at = notification.created_at; + existingGroup.notifications_count += 1; + + groups.splice(existingGroupIndex, 1); + mergeGapsAround(groups, existingGroupIndex); + + groups.unshift(existingGroup); + + return; + } } - } else { - // Create a new group - groups.unshift(createNotificationGroupFromNotificationJSON(notification)); } + + // We have not found an existing group, create a new one + groups.unshift(createNotificationGroupFromNotificationJSON(notification)); } function trimNotifications(state: NotificationGroupsState) { From 685067efd148e28cc7c158705ac1fa1199daeeda Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 04:23:05 -0400 Subject: [PATCH 005/150] Avoid `id` duplication conflict with main navigation from settings profile link (#32181) --- app/views/settings/shared/_profile_navigation.html.haml | 4 ++-- config/navigation.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/settings/shared/_profile_navigation.html.haml b/app/views/settings/shared/_profile_navigation.html.haml index d490bd7566..2f81cb5cfd 100644 --- a/app/views/settings/shared/_profile_navigation.html.haml +++ b/app/views/settings/shared/_profile_navigation.html.haml @@ -1,7 +1,7 @@ .content__heading__tabs = render_navigation renderer: :links do |primary| :ruby - primary.item :profile, safe_join([material_symbol('person'), t('settings.edit_profile')]), settings_profile_path - primary.item :privacy, safe_join([material_symbol('lock'), t('privacy.title')]), settings_privacy_path + primary.item :edit_profile, safe_join([material_symbol('person'), t('settings.edit_profile')]), settings_profile_path + primary.item :privacy_reach, safe_join([material_symbol('lock'), t('privacy.title')]), settings_privacy_path primary.item :verification, safe_join([material_symbol('check'), t('verification.verification')]), settings_verification_path primary.item :featured_tags, safe_join([material_symbol('tag'), t('settings.featured_tags')]), settings_featured_tags_path diff --git a/config/navigation.rb b/config/navigation.rb index 33efb78b1e..c79e96835b 100644 --- a/config/navigation.rb +++ b/config/navigation.rb @@ -35,7 +35,7 @@ SimpleNavigation::Configuration.run do |navigation| s.item :export, safe_join([material_symbol('cloud_download'), t('settings.export')]), settings_export_path end - n.item :invites, safe_join([material_symbol('person_add'), t('invites.title')]), invites_path, if: -> { current_user.can?(:invite_users) && current_user.functional? && !self_destruct } + n.item :user_invites, safe_join([material_symbol('person_add'), t('invites.title')]), invites_path, if: -> { current_user.can?(:invite_users) && current_user.functional? && !self_destruct } n.item :development, safe_join([material_symbol('code'), t('settings.development')]), settings_applications_path, highlights_on: %r{/settings/applications}, if: -> { current_user.functional? && !self_destruct } n.item :trends, safe_join([material_symbol('trending_up'), t('admin.trends.title')]), admin_trends_statuses_path, if: -> { current_user.can?(:manage_taxonomies) && !self_destruct } do |s| From d9973f3b705d62db2305420af9b51b4a75c14332 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 08:28:50 +0000 Subject: [PATCH 006/150] Update peter-evans/create-pull-request action to v7.0.5 (#32164) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/crowdin-download-stable.yml | 2 +- .github/workflows/crowdin-download.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/crowdin-download-stable.yml b/.github/workflows/crowdin-download-stable.yml index c0b402a5b9..de21e2e58f 100644 --- a/.github/workflows/crowdin-download-stable.yml +++ b/.github/workflows/crowdin-download-stable.yml @@ -50,7 +50,7 @@ jobs: # Create or update the pull request - name: Create Pull Request - uses: peter-evans/create-pull-request@v7.0.1 + uses: peter-evans/create-pull-request@v7.0.5 with: commit-message: 'New Crowdin translations' title: 'New Crowdin Translations for ${{ github.base_ref || github.ref_name }} (automated)' diff --git a/.github/workflows/crowdin-download.yml b/.github/workflows/crowdin-download.yml index f1817b3e9a..900899dd52 100644 --- a/.github/workflows/crowdin-download.yml +++ b/.github/workflows/crowdin-download.yml @@ -52,7 +52,7 @@ jobs: # Create or update the pull request - name: Create Pull Request - uses: peter-evans/create-pull-request@v7.0.1 + uses: peter-evans/create-pull-request@v7.0.5 with: commit-message: 'New Crowdin translations' title: 'New Crowdin Translations (automated)' From 497e8d00b9644bed65c3085b5cc1ca3139eebd58 Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Tue, 1 Oct 2024 10:36:22 +0200 Subject: [PATCH 007/150] Bump `main` version 4.4.0-alpha.1 (#32180) --- lib/mastodon/version.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index 8ee37c683f..88aa515296 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -9,7 +9,7 @@ module Mastodon end def minor - 3 + 4 end def patch @@ -17,7 +17,7 @@ module Mastodon end def default_prerelease - 'rc.1' + 'alpha.1' end def prerelease From 675d3ea5c11d78821d505b8ea8debe6355dee2df Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 04:36:41 -0400 Subject: [PATCH 008/150] Extract dashboard partial for admin instance page (#32189) --- .../admin/instances/_dashboard.html.haml | 66 ++++++++++++++++++ app/views/admin/instances/show.html.haml | 67 +------------------ 2 files changed, 67 insertions(+), 66 deletions(-) create mode 100644 app/views/admin/instances/_dashboard.html.haml diff --git a/app/views/admin/instances/_dashboard.html.haml b/app/views/admin/instances/_dashboard.html.haml new file mode 100644 index 0000000000..ef8500103b --- /dev/null +++ b/app/views/admin/instances/_dashboard.html.haml @@ -0,0 +1,66 @@ +-# locals: (instance_domain:, period_end_at:, period_start_at:) +%p + = material_symbol 'info' + = t('admin.instances.totals_time_period_hint_html') + +.dashboard + .dashboard__item + = react_admin_component :counter, + end_at: period_end_at, + href: admin_accounts_path(origin: 'remote', by_domain: instance_domain), + label: t('admin.instances.dashboard.instance_accounts_measure'), + measure: 'instance_accounts', + params: { domain: instance_domain }, + start_at: period_start_at + .dashboard__item + = react_admin_component :counter, + end_at: period_end_at, + label: t('admin.instances.dashboard.instance_statuses_measure'), + measure: 'instance_statuses', + params: { domain: instance_domain }, + start_at: period_start_at + .dashboard__item + = react_admin_component :counter, + end_at: period_end_at, + label: t('admin.instances.dashboard.instance_media_attachments_measure'), + measure: 'instance_media_attachments', + params: { domain: instance_domain }, + start_at: period_start_at + .dashboard__item + = react_admin_component :counter, + end_at: period_end_at, + label: t('admin.instances.dashboard.instance_follows_measure'), + measure: 'instance_follows', + params: { domain: instance_domain }, + start_at: period_start_at + .dashboard__item + = react_admin_component :counter, + end_at: period_end_at, + label: t('admin.instances.dashboard.instance_followers_measure'), + measure: 'instance_followers', + params: { domain: instance_domain }, + start_at: period_start_at + .dashboard__item + = react_admin_component :counter, + end_at: period_end_at, + href: admin_reports_path(by_target_domain: instance_domain), + label: t('admin.instances.dashboard.instance_reports_measure'), + measure: 'instance_reports', + params: { domain: instance_domain }, + start_at: period_start_at + .dashboard__item + = react_admin_component :dimension, + dimension: 'instance_accounts', + end_at: period_end_at, + label: t('admin.instances.dashboard.instance_accounts_dimension'), + limit: 8, + params: { domain: instance_domain }, + start_at: period_start_at + .dashboard__item + = react_admin_component :dimension, + dimension: 'instance_languages', + end_at: period_end_at, + label: t('admin.instances.dashboard.instance_languages_dimension'), + limit: 8, + params: { domain: instance_domain }, + start_at: period_start_at diff --git a/app/views/admin/instances/show.html.haml b/app/views/admin/instances/show.html.haml index c55eb89dc9..dfedbf4cb4 100644 --- a/app/views/admin/instances/show.html.haml +++ b/app/views/admin/instances/show.html.haml @@ -8,72 +8,7 @@ = l(@time_period.last) - if @instance.persisted? - %p - = material_symbol 'info' - = t('admin.instances.totals_time_period_hint_html') - - .dashboard - .dashboard__item - = react_admin_component :counter, - end_at: @time_period.last, - href: admin_accounts_path(origin: 'remote', by_domain: @instance.domain), - label: t('admin.instances.dashboard.instance_accounts_measure'), - measure: 'instance_accounts', - params: { domain: @instance.domain }, - start_at: @time_period.first - .dashboard__item - = react_admin_component :counter, - end_at: @time_period.last, - label: t('admin.instances.dashboard.instance_statuses_measure'), - measure: 'instance_statuses', - params: { domain: @instance.domain }, - start_at: @time_period.first - .dashboard__item - = react_admin_component :counter, - end_at: @time_period.last, - label: t('admin.instances.dashboard.instance_media_attachments_measure'), - measure: 'instance_media_attachments', - params: { domain: @instance.domain }, - start_at: @time_period.first - .dashboard__item - = react_admin_component :counter, - end_at: @time_period.last, - label: t('admin.instances.dashboard.instance_follows_measure'), - measure: 'instance_follows', - params: { domain: @instance.domain }, - start_at: @time_period.first - .dashboard__item - = react_admin_component :counter, - end_at: @time_period.last, - label: t('admin.instances.dashboard.instance_followers_measure'), - measure: 'instance_followers', - params: { domain: @instance.domain }, - start_at: @time_period.first - .dashboard__item - = react_admin_component :counter, - end_at: @time_period.last, - href: admin_reports_path(by_target_domain: @instance.domain), - label: t('admin.instances.dashboard.instance_reports_measure'), - measure: 'instance_reports', - params: { domain: @instance.domain }, - start_at: @time_period.first - .dashboard__item - = react_admin_component :dimension, - dimension: 'instance_accounts', - end_at: @time_period.last, - label: t('admin.instances.dashboard.instance_accounts_dimension'), - limit: 8, - params: { domain: @instance.domain }, - start_at: @time_period.first - .dashboard__item - = react_admin_component :dimension, - dimension: 'instance_languages', - end_at: @time_period.last, - label: t('admin.instances.dashboard.instance_languages_dimension'), - limit: 8, - params: { domain: @instance.domain }, - start_at: @time_period.first - + = render 'dashboard', instance_domain: @instance.domain, period_end_at: @time_period.last, period_start_at: @time_period.first - else %p = t('admin.instances.unknown_instance') From f811fcb2b2749d1e7a30ee7558ddff9d01e86e70 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 05:08:29 -0400 Subject: [PATCH 009/150] Improve alignment of icons on admin roles list (#32153) --- app/javascript/styles/mastodon/admin.scss | 4 ++++ app/javascript/styles/mastodon/tables.scss | 1 + 2 files changed, 5 insertions(+) diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index 120bad27ed..da76fa1107 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -1054,6 +1054,10 @@ a.name-tag, } } + .icon { + vertical-align: middle; + } + a.announcements-list__item__title { &:hover, &:focus, diff --git a/app/javascript/styles/mastodon/tables.scss b/app/javascript/styles/mastodon/tables.scss index af8ccf5b38..0cbf5c1d55 100644 --- a/app/javascript/styles/mastodon/tables.scss +++ b/app/javascript/styles/mastodon/tables.scss @@ -137,6 +137,7 @@ a.table-action-link { padding: 0 10px; color: $darker-text-color; font-weight: 500; + white-space: nowrap; &:hover { color: $highlight-text-color; From 2829f72d1668ec2cda5f07137f0e69c7abd37274 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 11:13:29 +0200 Subject: [PATCH 010/150] Update dependency propshaft to v1.1.0 (#32192) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index b85d97761d..a06b4407a0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -601,7 +601,7 @@ GEM actionmailer (>= 3) net-smtp premailer (~> 1.7, >= 1.7.9) - propshaft (1.0.1) + propshaft (1.1.0) actionpack (>= 7.0.0) activesupport (>= 7.0.0) rack From 3d943f03fd5264ec5f8c636f4fde18867a4e22c3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 11:13:33 +0200 Subject: [PATCH 011/150] Update dependency webmock to v3.24.0 (#32190) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index a06b4407a0..b3c37393f2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -698,7 +698,7 @@ GEM responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) - rexml (3.3.7) + rexml (3.3.8) rotp (6.3.0) rouge (4.3.0) rpam2 (4.0.2) @@ -884,7 +884,7 @@ GEM webfinger (1.2.0) activesupport httpclient (>= 2.4) - webmock (3.23.1) + webmock (3.24.0) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) From b7ddf45924c35dc8d5ecc8f4ab3c611da9d70d94 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 11:29:38 +0200 Subject: [PATCH 012/150] Update docker/dockerfile Docker tag to v1.10 (#32166) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Dockerfile | 2 +- streaming/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index c7c02d9b46..0452e5d062 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -# syntax=docker/dockerfile:1.9 +# syntax=docker/dockerfile:1.10 # This file is designed for production server deployment, not local development work # For a containerized local dev environment, see: https://github.com/mastodon/mastodon/blob/main/README.md#docker diff --git a/streaming/Dockerfile b/streaming/Dockerfile index 938f1655d1..bed6b63738 100644 --- a/streaming/Dockerfile +++ b/streaming/Dockerfile @@ -1,4 +1,4 @@ -# syntax=docker/dockerfile:1.9 +# syntax=docker/dockerfile:1.10 # Please see https://docs.docker.com/engine/reference/builder for information about # the extended buildx capabilities used in this file. From 7a653001b42d07eb82858801b5c5b00d71fefa12 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 11:30:09 +0200 Subject: [PATCH 013/150] Update dependency haml_lint to v0.59.0 (#32146) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index b3c37393f2..cd939c9eba 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -301,7 +301,7 @@ GEM activesupport (>= 5.1) haml (>= 4.0.6) railties (>= 5.1) - haml_lint (0.58.0) + haml_lint (0.59.0) haml (>= 5.0) parallel (~> 1.10) rainbow @@ -862,7 +862,7 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.9.1) - unicode-display_width (2.5.0) + unicode-display_width (2.6.0) uri (0.13.1) validate_email (0.1.6) activemodel (>= 3.0) From f251edfc1daffecb30914d1f48e6919710c61b12 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 05:30:21 -0400 Subject: [PATCH 014/150] Add `date_range` view helper (#32187) --- app/helpers/admin/dashboard_helper.rb | 5 +++++ app/views/admin/dashboard/index.html.haml | 4 +--- app/views/admin/instances/show.html.haml | 4 +--- app/views/admin/tags/show.html.haml | 4 +--- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/app/helpers/admin/dashboard_helper.rb b/app/helpers/admin/dashboard_helper.rb index 6096ff1381..4de779b79a 100644 --- a/app/helpers/admin/dashboard_helper.rb +++ b/app/helpers/admin/dashboard_helper.rb @@ -18,6 +18,11 @@ module Admin::DashboardHelper end end + def date_range(range) + [l(range.first), l(range.last)] + .join(' - ') + end + def relevant_account_timestamp(account) timestamp, exact = if account.user_current_sign_in_at && account.user_current_sign_in_at < 24.hours.ago [account.user_current_sign_in_at, true] diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index 27d8f4790b..2b4d02fa67 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -2,9 +2,7 @@ = t('admin.dashboard.title') - content_for :heading_actions do - = l(@time_period.first) - = ' - ' - = l(@time_period.last) + = date_range(@time_period) - unless @system_checks.empty? .flash-message-stack diff --git a/app/views/admin/instances/show.html.haml b/app/views/admin/instances/show.html.haml index dfedbf4cb4..812a9c8870 100644 --- a/app/views/admin/instances/show.html.haml +++ b/app/views/admin/instances/show.html.haml @@ -3,9 +3,7 @@ - if current_user.can?(:view_dashboard) - content_for :heading_actions do - = l(@time_period.first) - = ' - ' - = l(@time_period.last) + = date_range(@time_period) - if @instance.persisted? = render 'dashboard', instance_domain: @instance.domain, period_end_at: @time_period.last, period_start_at: @time_period.first diff --git a/app/views/admin/tags/show.html.haml b/app/views/admin/tags/show.html.haml index 93387843b2..462ca312a0 100644 --- a/app/views/admin/tags/show.html.haml +++ b/app/views/admin/tags/show.html.haml @@ -4,9 +4,7 @@ - content_for :heading_actions do - if current_user.can?(:view_dashboard) .time-period - = l(@time_period.first) - = ' - ' - = l(@time_period.last) + = date_range(@time_period) = link_to t('admin.tags.open'), tag_url(@tag), class: 'button', target: '_blank', rel: 'noopener noreferrer' From 0b89765e9a9154c5f904b602ae5aaa0966880818 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 09:30:54 +0000 Subject: [PATCH 015/150] Update RuboCop (non-major) to v1.22.1 (#31573) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index cd939c9eba..334a9e30d1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -748,15 +748,15 @@ GEM parser (>= 3.3.1.0) rubocop-capybara (2.21.0) rubocop (~> 1.41) - rubocop-performance (1.21.1) + rubocop-performance (1.22.1) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rails (2.25.1) + rubocop-rails (2.26.2) activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 1.33.0, < 2.0) + rubocop (>= 1.52.0, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rspec (3.0.4) + rubocop-rspec (3.0.5) rubocop (~> 1.61) rubocop-rspec_rails (2.30.0) rubocop (~> 1.61) From e6cda8388c0eae4dee82437538544563b04e7f24 Mon Sep 17 00:00:00 2001 From: David Roetzel Date: Tue, 1 Oct 2024 11:38:42 +0200 Subject: [PATCH 016/150] Move OTP secret length to configuration (#32125) --- .../otp_authentication_controller.rb | 2 +- app/models/user.rb | 3 ++- spec/controllers/auth/sessions_controller_spec.rb | 6 +++--- spec/requests/auth/sessions/security_key_options_spec.rb | 2 +- spec/system/oauth_spec.rb | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/controllers/settings/two_factor_authentication/otp_authentication_controller.rb b/app/controllers/settings/two_factor_authentication/otp_authentication_controller.rb index 0bff01ec27..ca8d46afe4 100644 --- a/app/controllers/settings/two_factor_authentication/otp_authentication_controller.rb +++ b/app/controllers/settings/two_factor_authentication/otp_authentication_controller.rb @@ -15,7 +15,7 @@ module Settings end def create - session[:new_otp_secret] = User.generate_otp_secret(32) + session[:new_otp_secret] = User.generate_otp_secret redirect_to new_settings_two_factor_authentication_confirmation_path end diff --git a/app/models/user.rb b/app/models/user.rb index fcb0eced72..c32a575edf 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -71,7 +71,8 @@ class User < ApplicationRecord ACTIVE_DURATION = ENV.fetch('USER_ACTIVE_DAYS', 7).to_i.days.freeze devise :two_factor_authenticatable, - otp_secret_encryption_key: Rails.configuration.x.otp_secret + otp_secret_encryption_key: Rails.configuration.x.otp_secret, + otp_secret_length: 32 include LegacyOtpSecret # Must be after the above `devise` line in order to override the legacy method diff --git a/spec/controllers/auth/sessions_controller_spec.rb b/spec/controllers/auth/sessions_controller_spec.rb index 713ea3ff16..4a6956cb09 100644 --- a/spec/controllers/auth/sessions_controller_spec.rb +++ b/spec/controllers/auth/sessions_controller_spec.rb @@ -208,7 +208,7 @@ RSpec.describe Auth::SessionsController do context 'when using two-factor authentication' do context 'with OTP enabled as second factor' do let!(:user) do - Fabricate(:user, email: 'x@y.com', password: 'abcdefgh', otp_required_for_login: true, otp_secret: User.generate_otp_secret(32)) + Fabricate(:user, email: 'x@y.com', password: 'abcdefgh', otp_required_for_login: true, otp_secret: User.generate_otp_secret) end let!(:recovery_codes) do @@ -230,7 +230,7 @@ RSpec.describe Auth::SessionsController do context 'when using email and password after an unfinished log-in attempt to a 2FA-protected account' do let!(:other_user) do - Fabricate(:user, email: 'z@y.com', password: 'abcdefgh', otp_required_for_login: true, otp_secret: User.generate_otp_secret(32)) + Fabricate(:user, email: 'z@y.com', password: 'abcdefgh', otp_required_for_login: true, otp_secret: User.generate_otp_secret) end before do @@ -342,7 +342,7 @@ RSpec.describe Auth::SessionsController do context 'with WebAuthn and OTP enabled as second factor' do let!(:user) do - Fabricate(:user, email: 'x@y.com', password: 'abcdefgh', otp_required_for_login: true, otp_secret: User.generate_otp_secret(32)) + Fabricate(:user, email: 'x@y.com', password: 'abcdefgh', otp_required_for_login: true, otp_secret: User.generate_otp_secret) end let!(:webauthn_credential) do diff --git a/spec/requests/auth/sessions/security_key_options_spec.rb b/spec/requests/auth/sessions/security_key_options_spec.rb index 6246e4beb3..e53b9802b4 100644 --- a/spec/requests/auth/sessions/security_key_options_spec.rb +++ b/spec/requests/auth/sessions/security_key_options_spec.rb @@ -6,7 +6,7 @@ require 'webauthn/fake_client' RSpec.describe 'Security Key Options' do describe 'GET /auth/sessions/security_key_options' do let!(:user) do - Fabricate(:user, email: 'x@y.com', password: 'abcdefgh', otp_required_for_login: true, otp_secret: User.generate_otp_secret(32)) + Fabricate(:user, email: 'x@y.com', password: 'abcdefgh', otp_required_for_login: true, otp_secret: User.generate_otp_secret) end context 'with WebAuthn and OTP enabled as second factor' do diff --git a/spec/system/oauth_spec.rb b/spec/system/oauth_spec.rb index 0f96a59675..64ac75879e 100644 --- a/spec/system/oauth_spec.rb +++ b/spec/system/oauth_spec.rb @@ -179,7 +179,7 @@ RSpec.describe 'Using OAuth from an external app' do end context 'when the user has set up TOTP' do - let(:user) { Fabricate(:user, email: email, password: password, otp_required_for_login: true, otp_secret: User.generate_otp_secret(32)) } + let(:user) { Fabricate(:user, email: email, password: password, otp_required_for_login: true, otp_secret: User.generate_otp_secret) } it 'when accepting the authorization request' do params = { client_id: client_app.uid, response_type: 'code', redirect_uri: client_app.redirect_uri, scope: 'read' } From e975b55c24f420316b14d5dc02b2eab3fbba4d6e Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 05:54:42 -0400 Subject: [PATCH 017/150] Remove `WebfingerHelper` module & move usage inline (#31203) --- app/helpers/webfinger_helper.rb | 7 ------- app/models/remote_follow.rb | 3 +-- app/services/activitypub/fetch_remote_actor_service.rb | 5 ++--- app/services/resolve_account_service.rb | 5 ++--- 4 files changed, 5 insertions(+), 15 deletions(-) delete mode 100644 app/helpers/webfinger_helper.rb diff --git a/app/helpers/webfinger_helper.rb b/app/helpers/webfinger_helper.rb deleted file mode 100644 index 482f4e19ea..0000000000 --- a/app/helpers/webfinger_helper.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -module WebfingerHelper - def webfinger!(uri) - Webfinger.new(uri).perform - end -end diff --git a/app/models/remote_follow.rb b/app/models/remote_follow.rb index 10715ac97d..fa0586f57e 100644 --- a/app/models/remote_follow.rb +++ b/app/models/remote_follow.rb @@ -3,7 +3,6 @@ class RemoteFollow include ActiveModel::Validations include RoutingHelper - include WebfingerHelper attr_accessor :acct, :addressable_template @@ -66,7 +65,7 @@ class RemoteFollow end def acct_resource - @acct_resource ||= webfinger!("acct:#{acct}") + @acct_resource ||= Webfinger.new("acct:#{acct}").perform rescue Webfinger::Error, HTTP::ConnectionError nil end diff --git a/app/services/activitypub/fetch_remote_actor_service.rb b/app/services/activitypub/fetch_remote_actor_service.rb index 2c372c2ec3..560cf424e1 100644 --- a/app/services/activitypub/fetch_remote_actor_service.rb +++ b/app/services/activitypub/fetch_remote_actor_service.rb @@ -3,7 +3,6 @@ class ActivityPub::FetchRemoteActorService < BaseService include JsonLdHelper include DomainControlHelper - include WebfingerHelper class Error < StandardError; end @@ -45,7 +44,7 @@ class ActivityPub::FetchRemoteActorService < BaseService private def check_webfinger! - webfinger = webfinger!("acct:#{@username}@#{@domain}") + webfinger = Webfinger.new("acct:#{@username}@#{@domain}").perform confirmed_username, confirmed_domain = split_acct(webfinger.subject) if @username.casecmp(confirmed_username).zero? && @domain.casecmp(confirmed_domain).zero? @@ -54,7 +53,7 @@ class ActivityPub::FetchRemoteActorService < BaseService return end - webfinger = webfinger!("acct:#{confirmed_username}@#{confirmed_domain}") + webfinger = Webfinger.new("acct:#{confirmed_username}@#{confirmed_domain}").perform @username, @domain = split_acct(webfinger.subject) raise Webfinger::RedirectError, "Too many webfinger redirects for URI #{@uri} (stopped at #{@username}@#{@domain})" unless confirmed_username.casecmp(@username).zero? && confirmed_domain.casecmp(@domain).zero? diff --git a/app/services/resolve_account_service.rb b/app/services/resolve_account_service.rb index 8a5863baba..cd96b55c74 100644 --- a/app/services/resolve_account_service.rb +++ b/app/services/resolve_account_service.rb @@ -2,7 +2,6 @@ class ResolveAccountService < BaseService include DomainControlHelper - include WebfingerHelper include Redisable include Lockable @@ -81,7 +80,7 @@ class ResolveAccountService < BaseService end def process_webfinger!(uri) - @webfinger = webfinger!("acct:#{uri}") + @webfinger = Webfinger.new("acct:#{uri}").perform confirmed_username, confirmed_domain = split_acct(@webfinger.subject) if confirmed_username.casecmp(@username).zero? && confirmed_domain.casecmp(@domain).zero? @@ -91,7 +90,7 @@ class ResolveAccountService < BaseService end # Account doesn't match, so it may have been redirected - @webfinger = webfinger!("acct:#{confirmed_username}@#{confirmed_domain}") + @webfinger = Webfinger.new("acct:#{confirmed_username}@#{confirmed_domain}").perform @username, @domain = split_acct(@webfinger.subject) raise Webfinger::RedirectError, "Too many webfinger redirects for URI #{uri} (stopped at #{@username}@#{@domain})" unless confirmed_username.casecmp(@username).zero? && confirmed_domain.casecmp(@domain).zero? From 454d21ab5ad87def97e712bc53e8e8ef50a5c678 Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Tue, 1 Oct 2024 11:56:58 +0200 Subject: [PATCH 018/150] Remove OAuth Password Grant Type support (#30960) --- config/initializers/doorkeeper.rb | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb index b47e76c08b..de1c75f576 100644 --- a/config/initializers/doorkeeper.rb +++ b/config/initializers/doorkeeper.rb @@ -9,16 +9,9 @@ Doorkeeper.configure do current_user || redirect_to(new_user_session_url) end - resource_owner_from_credentials do |_routes| - user = User.authenticate_with_ldap(email: request.params[:username], password: request.params[:password]) if Devise.ldap_authentication - user ||= User.authenticate_with_pam(email: request.params[:username], password: request.params[:password]) if Devise.pam_authentication - - if user.nil? - user = User.find_by(email: request.params[:username]) - user = nil unless user&.valid_password?(request.params[:password]) - end - - user unless user&.otp_required_for_login? + # Disable Resource Owner Password Credentials Grant Flow + resource_owner_from_credentials do + nil end # Doorkeeper provides some administrative interfaces for managing OAuth @@ -169,7 +162,7 @@ Doorkeeper.configure do # http://tools.ietf.org/html/rfc6819#section-4.4.3 # - grant_flows %w(authorization_code password client_credentials) + grant_flows %w(authorization_code client_credentials) # Under some circumstances you might want to have applications auto-approved, # so that the user skips the authorization step. From efd3f59627a2786b5601ef6a5c484ec96a777ae5 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 06:02:58 -0400 Subject: [PATCH 019/150] Use `module: :users` in routes/admin section (#30767) --- config/routes/admin.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 50c4c10594..3dba6fa5b8 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -144,8 +144,10 @@ namespace :admin do end resources :users, only: [] do - resource :two_factor_authentication, only: [:destroy], controller: 'users/two_factor_authentications' - resource :role, only: [:show, :update], controller: 'users/roles' + scope module: :users do + resource :two_factor_authentication, only: [:destroy] + resource :role, only: [:show, :update] + end end resources :custom_emojis, only: [:index, :new, :create] do From 8ae381fd042aa7dbcc546c13ccb158ccd8b01ff3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 10:04:12 +0000 Subject: [PATCH 020/150] Update dependency postcss-preset-env to v10.0.5 (#32019) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index 38402229bd..8970981d88 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1763,9 +1763,9 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-light-dark-function@npm:^2.0.2": - version: 2.0.2 - resolution: "@csstools/postcss-light-dark-function@npm:2.0.2" +"@csstools/postcss-light-dark-function@npm:^2.0.4": + version: 2.0.4 + resolution: "@csstools/postcss-light-dark-function@npm:2.0.4" dependencies: "@csstools/css-parser-algorithms": "npm:^3.0.1" "@csstools/css-tokenizer": "npm:^3.0.1" @@ -1773,7 +1773,7 @@ __metadata: "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/f8973c435868998e5d6af1fc0c35b27bbf65fa9d0c35f5055c689b8ee2807a16802044e296f7def39a7253ae544fb49559e8273ee22eb4e21845aa980a1bc82b + checksum: 10c0/0176422ad9747953964b1ceff002df1ecb1952ebc481db6192070d68777135b582ea6fd32ae819b9c64c96cb9170bd6907c647c85b48daa4984b7ed3d7f9bccb languageName: node linkType: hard @@ -13921,8 +13921,8 @@ __metadata: linkType: hard "postcss-preset-env@npm:^10.0.0": - version: 10.0.3 - resolution: "postcss-preset-env@npm:10.0.3" + version: 10.0.5 + resolution: "postcss-preset-env@npm:10.0.5" dependencies: "@csstools/postcss-cascade-layers": "npm:^5.0.0" "@csstools/postcss-color-function": "npm:^4.0.2" @@ -13936,7 +13936,7 @@ __metadata: "@csstools/postcss-ic-unit": "npm:^4.0.0" "@csstools/postcss-initial": "npm:^2.0.0" "@csstools/postcss-is-pseudo-class": "npm:^5.0.0" - "@csstools/postcss-light-dark-function": "npm:^2.0.2" + "@csstools/postcss-light-dark-function": "npm:^2.0.4" "@csstools/postcss-logical-float-and-clear": "npm:^3.0.0" "@csstools/postcss-logical-overflow": "npm:^2.0.0" "@csstools/postcss-logical-overscroll-behavior": "npm:^2.0.0" @@ -13987,7 +13987,7 @@ __metadata: postcss-selector-not: "npm:^8.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/da42caa2aab4d825fddfde00ebe2416d338c7b9a6f79a68840297888a8384f85991991c3fa10cf2d359fb230c885375f5cebd7bd63972725cd2a596d218f8b6a + checksum: 10c0/db5eb1175cb26bed3f1a4c47acc67935ffc784520321470520e59de366ac6f91be1e609fe36056af707ed20f7910721287cff0fae416c437dd3e944de13ffd05 languageName: node linkType: hard From 7e35bef97efc5b5c107434d0157326427b79660a Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 06:34:05 -0400 Subject: [PATCH 021/150] Remove explicit `put` action in settings forms (#32176) --- app/views/settings/applications/show.html.haml | 2 +- app/views/settings/preferences/appearance/show.html.haml | 2 +- app/views/settings/preferences/notifications/show.html.haml | 2 +- app/views/settings/preferences/other/show.html.haml | 2 +- app/views/settings/privacy/show.html.haml | 2 +- app/views/settings/profiles/show.html.haml | 2 +- app/views/settings/verifications/show.html.haml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/views/settings/applications/show.html.haml b/app/views/settings/applications/show.html.haml index 19630cf49b..099e0d96a8 100644 --- a/app/views/settings/applications/show.html.haml +++ b/app/views/settings/applications/show.html.haml @@ -23,7 +23,7 @@ %hr/ -= simple_form_for @application, url: settings_application_path(@application), method: :put do |form| += simple_form_for @application, url: settings_application_path(@application) do |form| = render form .actions diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml index f34ce4a6aa..22f88c7cdd 100644 --- a/app/views/settings/preferences/appearance/show.html.haml +++ b/app/views/settings/preferences/appearance/show.html.haml @@ -4,7 +4,7 @@ - content_for :heading_actions do = button_tag t('generic.save_changes'), class: 'button', form: 'edit_user' -= simple_form_for current_user, url: settings_preferences_appearance_path, html: { method: :put, id: 'edit_user' } do |f| += simple_form_for current_user, url: settings_preferences_appearance_path, html: { id: :edit_user } do |f| .fields-row .fields-group.fields-row__column.fields-row__column-6 = f.input :locale, diff --git a/app/views/settings/preferences/notifications/show.html.haml b/app/views/settings/preferences/notifications/show.html.haml index de318dda54..a8e179d019 100644 --- a/app/views/settings/preferences/notifications/show.html.haml +++ b/app/views/settings/preferences/notifications/show.html.haml @@ -4,7 +4,7 @@ - content_for :heading_actions do = button_tag t('generic.save_changes'), class: 'button', form: 'edit_notification' -= simple_form_for current_user, url: settings_preferences_notifications_path, html: { method: :put, id: 'edit_notification' } do |f| += simple_form_for current_user, url: settings_preferences_notifications_path, html: { id: :edit_notification } do |f| = render 'shared/error_messages', object: current_user %h4= t 'notifications.email_events' diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml index e2888f7212..92df8e5213 100644 --- a/app/views/settings/preferences/other/show.html.haml +++ b/app/views/settings/preferences/other/show.html.haml @@ -4,7 +4,7 @@ - content_for :heading_actions do = button_tag t('generic.save_changes'), class: 'button', form: 'edit_preferences' -= simple_form_for current_user, url: settings_preferences_other_path, html: { method: :put, id: 'edit_preferences' } do |f| += simple_form_for current_user, url: settings_preferences_other_path, html: { id: :edit_preferences } do |f| = render 'shared/error_messages', object: current_user = f.simple_fields_for :settings, current_user.settings do |ff| diff --git a/app/views/settings/privacy/show.html.haml b/app/views/settings/privacy/show.html.haml index 3c14382587..f7241cfb24 100644 --- a/app/views/settings/privacy/show.html.haml +++ b/app/views/settings/privacy/show.html.haml @@ -5,7 +5,7 @@ %h2= t('settings.profile') = render partial: 'settings/shared/profile_navigation' -= simple_form_for @account, url: settings_privacy_path, html: { method: :put } do |f| += simple_form_for @account, url: settings_privacy_path do |f| = render 'shared/error_messages', object: @account %p.lead= t('privacy.hint_html') diff --git a/app/views/settings/profiles/show.html.haml b/app/views/settings/profiles/show.html.haml index 8fb2132519..cad5aee669 100644 --- a/app/views/settings/profiles/show.html.haml +++ b/app/views/settings/profiles/show.html.haml @@ -5,7 +5,7 @@ %h2= t('settings.profile') = render partial: 'settings/shared/profile_navigation' -= simple_form_for @account, url: settings_profile_path, html: { method: :put, id: 'edit_profile' } do |f| += simple_form_for @account, url: settings_profile_path, html: { id: :edit_profile } do |f| = render 'shared/error_messages', object: @account %p.lead= t('edit_profile.hint_html') diff --git a/app/views/settings/verifications/show.html.haml b/app/views/settings/verifications/show.html.haml index af9556d004..00491866c6 100644 --- a/app/views/settings/verifications/show.html.haml +++ b/app/views/settings/verifications/show.html.haml @@ -31,7 +31,7 @@ = material_symbol 'check', class: 'verified-badge__mark' %span= field.value -= simple_form_for @account, url: settings_verification_path, html: { method: :put, class: 'form-section' } do |f| += simple_form_for @account, url: settings_verification_path, html: { class: 'form-section' } do |f| = render 'shared/error_messages', object: @account %h3= t('author_attribution.title') From 489abb817358bd27417ce464d144bafb5ae191fb Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 06:35:40 -0400 Subject: [PATCH 022/150] Remove explicit `put` action in prefs forms (#32175) From 4b4bf82ea99a5d4f223556e92d97a04dbfa45297 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 06:48:27 -0400 Subject: [PATCH 023/150] Fix nav item active highlight for some paths (#32159) --- config/navigation.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/config/navigation.rb b/config/navigation.rb index c79e96835b..09a7b55b5e 100644 --- a/config/navigation.rb +++ b/config/navigation.rb @@ -25,13 +25,13 @@ SimpleNavigation::Configuration.run do |navigation| n.item :statuses_cleanup, safe_join([material_symbol('history'), t('settings.statuses_cleanup')]), statuses_cleanup_path, if: -> { current_user.functional_or_moved? && !self_destruct } n.item :security, safe_join([material_symbol('lock'), t('settings.account')]), edit_user_registration_path do |s| - s.item :password, safe_join([material_symbol('lock'), t('settings.account_settings')]), edit_user_registration_path, highlights_on: %r{/auth/edit|/settings/delete|/settings/migration|/settings/aliases|/settings/login_activities|^/disputes} + s.item :password, safe_join([material_symbol('lock'), t('settings.account_settings')]), edit_user_registration_path, highlights_on: %r{^/auth|/settings/delete|/settings/migration|/settings/aliases|/settings/login_activities|^/disputes} s.item :two_factor_authentication, safe_join([material_symbol('safety_check'), t('settings.two_factor_authentication')]), settings_two_factor_authentication_methods_path, highlights_on: %r{/settings/two_factor_authentication|/settings/otp_authentication|/settings/security_keys} s.item :authorized_apps, safe_join([material_symbol('list_alt'), t('settings.authorized_apps')]), oauth_authorized_applications_path, if: -> { !self_destruct } end n.item :data, safe_join([material_symbol('cloud_sync'), t('settings.import_and_export')]), settings_export_path do |s| - s.item :import, safe_join([material_symbol('cloud_upload'), t('settings.import')]), settings_imports_path, if: -> { current_user.functional? && !self_destruct } + s.item :import, safe_join([material_symbol('cloud_upload'), t('settings.import')]), settings_imports_path, highlights_on: %r{/settings/imports}, if: -> { current_user.functional? && !self_destruct } s.item :export, safe_join([material_symbol('cloud_download'), t('settings.export')]), settings_export_path end @@ -51,7 +51,9 @@ SimpleNavigation::Configuration.run do |navigation| s.item :accounts, safe_join([material_symbol('groups'), t('admin.accounts.title')]), admin_accounts_path(origin: 'local'), highlights_on: %r{/admin/accounts|admin/account_moderation_notes|/admin/pending_accounts|/admin/users}, if: -> { current_user.can?(:manage_users) } s.item :tags, safe_join([material_symbol('tag'), t('admin.tags.title')]), admin_tags_path, highlights_on: %r{/admin/tags}, if: -> { current_user.can?(:manage_taxonomies) } s.item :invites, safe_join([material_symbol('person_add'), t('admin.invites.title')]), admin_invites_path, if: -> { current_user.can?(:manage_invites) } - s.item :instances, safe_join([material_symbol('cloud'), t('admin.instances.title')]), admin_instances_path(limited: limited_federation_mode? ? nil : '1'), highlights_on: %r{/admin/instances|/admin/domain_blocks|/admin/domain_allows}, if: -> { current_user.can?(:manage_federation) } + s.item :instances, safe_join([material_symbol('cloud'), t('admin.instances.title')]), admin_instances_path(limited: limited_federation_mode? ? nil : '1'), highlights_on: %r{/admin/instances|/admin/domain_blocks|/admin/domain_allows|/admin/export_domain_blocks}, if: lambda { + current_user.can?(:manage_federation) + } s.item :email_domain_blocks, safe_join([material_symbol('mail'), t('admin.email_domain_blocks.title')]), admin_email_domain_blocks_path, highlights_on: %r{/admin/email_domain_blocks}, if: -> { current_user.can?(:manage_blocks) } s.item :ip_blocks, safe_join([material_symbol('hide_source'), t('admin.ip_blocks.title')]), admin_ip_blocks_path, highlights_on: %r{/admin/ip_blocks}, if: -> { current_user.can?(:manage_blocks) } s.item :action_logs, safe_join([material_symbol('list'), t('admin.action_logs.title')]), admin_action_logs_path, if: -> { current_user.can?(:view_audit_log) } From 651846c62227917729492ff9d6fc4161ea8d86c5 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 07:03:13 -0400 Subject: [PATCH 024/150] Only show email domain blocks MX table when some found (#32155) --- app/views/admin/email_domain_blocks/new.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/email_domain_blocks/new.html.haml b/app/views/admin/email_domain_blocks/new.html.haml index dd4b83ee3f..2dfdca9376 100644 --- a/app/views/admin/email_domain_blocks/new.html.haml +++ b/app/views/admin/email_domain_blocks/new.html.haml @@ -16,7 +16,7 @@ label: I18n.t('admin.email_domain_blocks.allow_registrations_with_approval'), wrapper: :with_label - - if defined?(@resolved_records) + - if defined?(@resolved_records) && @resolved_records.any? %p.hint= t('admin.email_domain_blocks.resolved_dns_records_hint_html') .batch-table From c0095079128d04974a10821e04e046ec27fa6a3f Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 07:14:12 -0400 Subject: [PATCH 025/150] Use `button_to` for `method: :post` links on account show page (#32154) --- app/javascript/styles/mastodon/forms.scss | 4 ++++ app/views/admin/accounts/_buttons.html.haml | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss index 957a283522..4f974ea585 100644 --- a/app/javascript/styles/mastodon/forms.scss +++ b/app/javascript/styles/mastodon/forms.scss @@ -19,6 +19,10 @@ code { margin-bottom: 24px; } +form.button_to { + display: inline-block; +} + .fade-out-top { position: relative; overflow: hidden; diff --git a/app/views/admin/accounts/_buttons.html.haml b/app/views/admin/accounts/_buttons.html.haml index 2aaca8962c..eb1a7c3a4f 100644 --- a/app/views/admin/accounts/_buttons.html.haml +++ b/app/views/admin/accounts/_buttons.html.haml @@ -4,8 +4,8 @@ %p.muted-hint= deletion_request.present? ? t('admin.accounts.remote_suspension_reversible_hint_html', date: content_tag(:strong, l(deletion_request.due_at.to_date))) : t('admin.accounts.remote_suspension_irreversible') - else %p.muted-hint= deletion_request.present? ? t('admin.accounts.suspension_reversible_hint_html', date: content_tag(:strong, l(deletion_request.due_at.to_date))) : t('admin.accounts.suspension_irreversible') - = link_to t('admin.accounts.undo_suspension'), unsuspend_admin_account_path(account.id), method: :post, class: 'button' if can?(:unsuspend, account) - = link_to t('admin.accounts.redownload'), redownload_admin_account_path(account.id), method: :post, class: 'button' if can?(:redownload, account) && account.suspension_origin_remote? + = button_to t('admin.accounts.undo_suspension'), unsuspend_admin_account_path(account.id), class: :button if can?(:unsuspend, account) + = button_to t('admin.accounts.redownload'), redownload_admin_account_path(account.id), class: :button if can?(:redownload, account) && account.suspension_origin_remote? - if deletion_request.present? && can?(:destroy, account) = link_to t('admin.accounts.delete'), admin_account_path(account.id), method: :delete, class: 'button button--destructive', data: { confirm: t('admin.accounts.are_you_sure') } - else @@ -14,28 +14,28 @@ - if account.local? && account.user_approved? = link_to t('admin.accounts.warn'), new_admin_account_action_path(account.id, type: 'none'), class: 'button' if can?(:warn, account) - if account.user_disabled? - = link_to t('admin.accounts.enable'), enable_admin_account_path(account.id), method: :post, class: 'button' if can?(:enable, account.user) + = button_to t('admin.accounts.enable'), enable_admin_account_path(account.id), class: :button if can?(:enable, account.user) - elsif can?(:disable, account.user) = link_to t('admin.accounts.disable'), new_admin_account_action_path(account.id, type: 'disable'), class: 'button' - if account.sensitized? - = link_to t('admin.accounts.undo_sensitized'), unsensitive_admin_account_path(account.id), method: :post, class: 'button' if can?(:unsensitive, account) + = button_to t('admin.accounts.undo_sensitized'), unsensitive_admin_account_path(account.id), class: :button if can?(:unsensitive, account) - elsif !account.local? || account.user_approved? = link_to t('admin.accounts.sensitive'), new_admin_account_action_path(account.id, type: 'sensitive'), class: 'button' if can?(:sensitive, account) - if account.silenced? - = link_to t('admin.accounts.undo_silenced'), unsilence_admin_account_path(account.id), method: :post, class: 'button' if can?(:unsilence, account) + = button_to t('admin.accounts.undo_silenced'), unsilence_admin_account_path(account.id), class: :button if can?(:unsilence, account) - elsif !account.local? || account.user_approved? = link_to t('admin.accounts.silence'), new_admin_account_action_path(account.id, type: 'silence'), class: 'button' if can?(:silence, account) - if account.local? - if account.user_pending? - = link_to t('admin.accounts.approve'), approve_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' if can?(:approve, account.user) - = link_to t('admin.accounts.reject'), reject_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:reject, account.user) + = button_to t('admin.accounts.approve'), approve_admin_account_path(account.id), data: { confirm: t('admin.accounts.are_you_sure') }, class: :button if can?(:approve, account.user) + = button_to t('admin.accounts.reject'), reject_admin_account_path(account.id), data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:reject, account.user) - if !account.user_confirmed? && can?(:confirm, account.user) - = link_to t('admin.accounts.confirm'), admin_account_confirmation_path(account.id), method: :post, class: 'button' + = button_to t('admin.accounts.confirm'), admin_account_confirmation_path(account.id), class: :button - if (!account.local? || account.user_approved?) && can?(:suspend, account) = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(account.id, type: 'suspend'), class: 'button' %div - if account.local? - if !account.memorial? && account.user_approved? && can?(:memorialize, account) - = link_to t('admin.accounts.memorialize'), memorialize_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' + = button_to t('admin.accounts.memorialize'), memorialize_admin_account_path(account.id), data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' - elsif can?(:redownload, account) - = link_to t('admin.accounts.redownload'), redownload_admin_account_path(account.id), method: :post, class: 'button' + = button_to t('admin.accounts.redownload'), redownload_admin_account_path(account.id), class: :button From ec16ed37c39a79ae23d5b4d759f571b0fa66506b Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 07:36:25 -0400 Subject: [PATCH 026/150] Extract constants for header and avatar geometry (#32151) --- app/models/concerns/account/avatar.rb | 7 +++++-- app/models/concerns/account/header.rb | 5 ++++- app/views/settings/profiles/show.html.haml | 4 ++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/app/models/concerns/account/avatar.rb b/app/models/concerns/account/avatar.rb index 39f599db18..5ca8fa862f 100644 --- a/app/models/concerns/account/avatar.rb +++ b/app/models/concerns/account/avatar.rb @@ -6,10 +6,13 @@ module Account::Avatar IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].freeze LIMIT = 2.megabytes + AVATAR_DIMENSIONS = [400, 400].freeze + AVATAR_GEOMETRY = [AVATAR_DIMENSIONS.first, AVATAR_DIMENSIONS.last].join('x') + class_methods do def avatar_styles(file) - styles = { original: { geometry: '400x400#', file_geometry_parser: FastGeometryParser } } - styles[:static] = { geometry: '400x400#', format: 'png', convert_options: '-coalesce', file_geometry_parser: FastGeometryParser } if file.content_type == 'image/gif' + styles = { original: { geometry: "#{AVATAR_GEOMETRY}#", file_geometry_parser: FastGeometryParser } } + styles[:static] = { geometry: "#{AVATAR_GEOMETRY}#", format: 'png', convert_options: '-coalesce', file_geometry_parser: FastGeometryParser } if file.content_type == 'image/gif' styles end diff --git a/app/models/concerns/account/header.rb b/app/models/concerns/account/header.rb index 44ae774e94..2a47097fcf 100644 --- a/app/models/concerns/account/header.rb +++ b/app/models/concerns/account/header.rb @@ -5,7 +5,10 @@ module Account::Header IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].freeze LIMIT = 2.megabytes - MAX_PIXELS = 750_000 # 1500x500px + + HEADER_DIMENSIONS = [1500, 500].freeze + HEADER_GEOMETRY = [HEADER_DIMENSIONS.first, HEADER_DIMENSIONS.last].join('x') + MAX_PIXELS = HEADER_DIMENSIONS.first * HEADER_DIMENSIONS.last class_methods do def header_styles(file) diff --git a/app/views/settings/profiles/show.html.haml b/app/views/settings/profiles/show.html.haml index cad5aee669..427a4fa95a 100644 --- a/app/views/settings/profiles/show.html.haml +++ b/app/views/settings/profiles/show.html.haml @@ -34,7 +34,7 @@ .fields-row__column.fields-row__column-6 .fields-group = f.input :avatar, - hint: t('simple_form.hints.defaults.avatar', dimensions: '400x400', size: number_to_human_size(Account::Avatar::LIMIT)), + hint: t('simple_form.hints.defaults.avatar', dimensions: Account::Avatar::AVATAR_GEOMETRY, size: number_to_human_size(Account::Avatar::LIMIT)), input_html: { accept: Account::Avatar::IMAGE_MIME_TYPES.join(',') }, wrapper: :with_block_label @@ -50,7 +50,7 @@ .fields-row__column.fields-row__column-6 .fields-group = f.input :header, - hint: t('simple_form.hints.defaults.header', dimensions: '1500x500', size: number_to_human_size(Account::Header::LIMIT)), + hint: t('simple_form.hints.defaults.header', dimensions: Account::Header::HEADER_GEOMETRY, size: number_to_human_size(Account::Header::LIMIT)), input_html: { accept: Account::Header::IMAGE_MIME_TYPES.join(',') }, wrapper: :with_block_label From 44071fdbae14d12bcd2c64bdc0d4162aca9de486 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 08:45:58 -0400 Subject: [PATCH 027/150] Wrap datetime in `time` element with attrs (#32177) --- app/views/settings/exports/show.html.haml | 3 ++- app/views/settings/imports/index.html.haml | 5 ++++- app/views/severed_relationships/index.html.haml | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/views/settings/exports/show.html.haml b/app/views/settings/exports/show.html.haml index 320bb0c7ce..273c5a4ba6 100644 --- a/app/views/settings/exports/show.html.haml +++ b/app/views/settings/exports/show.html.haml @@ -61,7 +61,8 @@ %tbody - @backups.each do |backup| %tr - %td= l backup.created_at + %td + %time.formatted{ datetime: backup.created_at.iso8601, title: l(backup.created_at) }= l backup.created_at - if backup.processed? %td= number_to_human_size backup.dump_file_size %td= table_link_to 'download', t('exports.archive_takeout.download'), download_backup_url(backup) diff --git a/app/views/settings/imports/index.html.haml b/app/views/settings/imports/index.html.haml index 634631b5aa..55421991e1 100644 --- a/app/views/settings/imports/index.html.haml +++ b/app/views/settings/imports/index.html.haml @@ -55,7 +55,10 @@ = t("imports.states.#{import.state}") %td #{import.imported_items} / #{import.total_items} - %td= l(import.created_at) + %td + %time.formatted{ datetime: import.created_at.iso8601, title: l(import.created_at) } + = l(import.created_at) + %td - num_failed = import.processed_items - import.imported_items - if num_failed.positive? diff --git a/app/views/severed_relationships/index.html.haml b/app/views/severed_relationships/index.html.haml index 7c599e9c0e..cc9439b468 100644 --- a/app/views/severed_relationships/index.html.haml +++ b/app/views/severed_relationships/index.html.haml @@ -15,7 +15,9 @@ %tbody - @events.each do |event| %tr - %td= l event.created_at + %td + %time.formatted{ datetime: event.created_at.iso8601, title: l(event.created_at) } + = l(event.created_at) %td= t("severed_relationships.event_type.#{event.type}", target_name: event.target_name) - if event.purged? %td{ rowspan: 2 }= t('severed_relationships.purged') From c5f0da98e43134d5922ea76dc89db292cd3531e8 Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Tue, 1 Oct 2024 14:49:04 +0200 Subject: [PATCH 028/150] Add detection and download of material_symbol icons in config/navigation.rb (#31366) --- .../material-icons/400-24px/breaking_news-fill.svg | 1 + .../material-icons/400-24px/breaking_news.svg | 2 +- .../400-24px/captive_portal-fill.svg | 1 + .../material-icons/400-24px/captive_portal.svg | 2 +- .../material-icons/400-24px/chat_bubble-fill.svg | 1 + .../material-icons/400-24px/chat_bubble.svg | 2 +- .../material-icons/400-24px/cloud-fill.svg | 1 + app/javascript/material-icons/400-24px/cloud.svg | 2 +- .../400-24px/cloud_download-fill.svg | 1 + .../material-icons/400-24px/cloud_download.svg | 2 +- .../material-icons/400-24px/cloud_sync-fill.svg | 1 + .../material-icons/400-24px/cloud_sync.svg | 2 +- .../material-icons/400-24px/cloud_upload-fill.svg | 1 + .../material-icons/400-24px/cloud_upload.svg | 2 +- .../material-icons/400-24px/code-fill.svg | 1 + app/javascript/material-icons/400-24px/code.svg | 2 +- .../material-icons/400-24px/computer-fill.svg | 1 + .../material-icons/400-24px/computer.svg | 2 +- .../material-icons/400-24px/contact_mail-fill.svg | 1 + .../material-icons/400-24px/contact_mail.svg | 2 +- .../material-icons/400-24px/database-fill.svg | 1 + .../material-icons/400-24px/database.svg | 2 +- .../material-icons/400-24px/diamond-fill.svg | 1 + app/javascript/material-icons/400-24px/diamond.svg | 2 +- .../material-icons/400-24px/filter_alt-fill.svg | 1 + .../material-icons/400-24px/filter_alt.svg | 2 +- .../material-icons/400-24px/groups-fill.svg | 1 + app/javascript/material-icons/400-24px/groups.svg | 2 +- .../material-icons/400-24px/hide_source-fill.svg | 1 + .../material-icons/400-24px/hide_source.svg | 2 +- .../material-icons/400-24px/inbox-fill.svg | 1 + app/javascript/material-icons/400-24px/inbox.svg | 2 +- .../material-icons/400-24px/list-fill.svg | 1 + app/javascript/material-icons/400-24px/list.svg | 2 +- .../material-icons/400-24px/mail-fill.svg | 1 + app/javascript/material-icons/400-24px/mail.svg | 2 +- .../material-icons/400-24px/mood-fill.svg | 1 + app/javascript/material-icons/400-24px/mood.svg | 2 +- .../material-icons/400-24px/report-fill.svg | 1 + app/javascript/material-icons/400-24px/report.svg | 2 +- .../material-icons/400-24px/safety_check-fill.svg | 1 + .../material-icons/400-24px/safety_check.svg | 2 +- .../material-icons/400-24px/speed-fill.svg | 1 + app/javascript/material-icons/400-24px/speed.svg | 2 +- .../material-icons/400-24px/trending_up-fill.svg | 1 + .../material-icons/400-24px/trending_up.svg | 2 +- lib/tasks/icons.rake | 14 ++++++++++++++ 47 files changed, 60 insertions(+), 23 deletions(-) create mode 100644 app/javascript/material-icons/400-24px/breaking_news-fill.svg create mode 100644 app/javascript/material-icons/400-24px/captive_portal-fill.svg create mode 100644 app/javascript/material-icons/400-24px/chat_bubble-fill.svg create mode 100644 app/javascript/material-icons/400-24px/cloud-fill.svg create mode 100644 app/javascript/material-icons/400-24px/cloud_download-fill.svg create mode 100644 app/javascript/material-icons/400-24px/cloud_sync-fill.svg create mode 100644 app/javascript/material-icons/400-24px/cloud_upload-fill.svg create mode 100644 app/javascript/material-icons/400-24px/code-fill.svg create mode 100644 app/javascript/material-icons/400-24px/computer-fill.svg create mode 100644 app/javascript/material-icons/400-24px/contact_mail-fill.svg create mode 100644 app/javascript/material-icons/400-24px/database-fill.svg create mode 100644 app/javascript/material-icons/400-24px/diamond-fill.svg create mode 100644 app/javascript/material-icons/400-24px/filter_alt-fill.svg create mode 100644 app/javascript/material-icons/400-24px/groups-fill.svg create mode 100644 app/javascript/material-icons/400-24px/hide_source-fill.svg create mode 100644 app/javascript/material-icons/400-24px/inbox-fill.svg create mode 100644 app/javascript/material-icons/400-24px/list-fill.svg create mode 100644 app/javascript/material-icons/400-24px/mail-fill.svg create mode 100644 app/javascript/material-icons/400-24px/mood-fill.svg create mode 100644 app/javascript/material-icons/400-24px/report-fill.svg create mode 100644 app/javascript/material-icons/400-24px/safety_check-fill.svg create mode 100644 app/javascript/material-icons/400-24px/speed-fill.svg create mode 100644 app/javascript/material-icons/400-24px/trending_up-fill.svg diff --git a/app/javascript/material-icons/400-24px/breaking_news-fill.svg b/app/javascript/material-icons/400-24px/breaking_news-fill.svg new file mode 100644 index 0000000000..633ca48d57 --- /dev/null +++ b/app/javascript/material-icons/400-24px/breaking_news-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/breaking_news.svg b/app/javascript/material-icons/400-24px/breaking_news.svg index d7dd0c12f4..c043f11a8b 100644 --- a/app/javascript/material-icons/400-24px/breaking_news.svg +++ b/app/javascript/material-icons/400-24px/breaking_news.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/captive_portal-fill.svg b/app/javascript/material-icons/400-24px/captive_portal-fill.svg new file mode 100644 index 0000000000..5c0b26fb64 --- /dev/null +++ b/app/javascript/material-icons/400-24px/captive_portal-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/captive_portal.svg b/app/javascript/material-icons/400-24px/captive_portal.svg index 1f0f09c773..5c0b26fb64 100644 --- a/app/javascript/material-icons/400-24px/captive_portal.svg +++ b/app/javascript/material-icons/400-24px/captive_portal.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/chat_bubble-fill.svg b/app/javascript/material-icons/400-24px/chat_bubble-fill.svg new file mode 100644 index 0000000000..b47338a6c9 --- /dev/null +++ b/app/javascript/material-icons/400-24px/chat_bubble-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/chat_bubble.svg b/app/javascript/material-icons/400-24px/chat_bubble.svg index 7d210b4608..05d976d242 100644 --- a/app/javascript/material-icons/400-24px/chat_bubble.svg +++ b/app/javascript/material-icons/400-24px/chat_bubble.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/cloud-fill.svg b/app/javascript/material-icons/400-24px/cloud-fill.svg new file mode 100644 index 0000000000..d049a74c01 --- /dev/null +++ b/app/javascript/material-icons/400-24px/cloud-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/cloud.svg b/app/javascript/material-icons/400-24px/cloud.svg index 75b4e957fc..a36bddda91 100644 --- a/app/javascript/material-icons/400-24px/cloud.svg +++ b/app/javascript/material-icons/400-24px/cloud.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/cloud_download-fill.svg b/app/javascript/material-icons/400-24px/cloud_download-fill.svg new file mode 100644 index 0000000000..c55d49f7e5 --- /dev/null +++ b/app/javascript/material-icons/400-24px/cloud_download-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/cloud_download.svg b/app/javascript/material-icons/400-24px/cloud_download.svg index 2fc3717ff9..8e9314800c 100644 --- a/app/javascript/material-icons/400-24px/cloud_download.svg +++ b/app/javascript/material-icons/400-24px/cloud_download.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/cloud_sync-fill.svg b/app/javascript/material-icons/400-24px/cloud_sync-fill.svg new file mode 100644 index 0000000000..0c648e19e4 --- /dev/null +++ b/app/javascript/material-icons/400-24px/cloud_sync-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/cloud_sync.svg b/app/javascript/material-icons/400-24px/cloud_sync.svg index dbf6adc000..461796e323 100644 --- a/app/javascript/material-icons/400-24px/cloud_sync.svg +++ b/app/javascript/material-icons/400-24px/cloud_sync.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/cloud_upload-fill.svg b/app/javascript/material-icons/400-24px/cloud_upload-fill.svg new file mode 100644 index 0000000000..66a7bb22d3 --- /dev/null +++ b/app/javascript/material-icons/400-24px/cloud_upload-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/cloud_upload.svg b/app/javascript/material-icons/400-24px/cloud_upload.svg index 5e1a4b9aef..94968cb947 100644 --- a/app/javascript/material-icons/400-24px/cloud_upload.svg +++ b/app/javascript/material-icons/400-24px/cloud_upload.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/code-fill.svg b/app/javascript/material-icons/400-24px/code-fill.svg new file mode 100644 index 0000000000..8ef5c55cd4 --- /dev/null +++ b/app/javascript/material-icons/400-24px/code-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/code.svg b/app/javascript/material-icons/400-24px/code.svg index 5bdc338f7f..8ef5c55cd4 100644 --- a/app/javascript/material-icons/400-24px/code.svg +++ b/app/javascript/material-icons/400-24px/code.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/computer-fill.svg b/app/javascript/material-icons/400-24px/computer-fill.svg new file mode 100644 index 0000000000..91295d6846 --- /dev/null +++ b/app/javascript/material-icons/400-24px/computer-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/computer.svg b/app/javascript/material-icons/400-24px/computer.svg index 8c5bd9110e..b8af5d4644 100644 --- a/app/javascript/material-icons/400-24px/computer.svg +++ b/app/javascript/material-icons/400-24px/computer.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/contact_mail-fill.svg b/app/javascript/material-icons/400-24px/contact_mail-fill.svg new file mode 100644 index 0000000000..c42c799955 --- /dev/null +++ b/app/javascript/material-icons/400-24px/contact_mail-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/contact_mail.svg b/app/javascript/material-icons/400-24px/contact_mail.svg index 1ae26cc4d1..4547c48ec5 100644 --- a/app/javascript/material-icons/400-24px/contact_mail.svg +++ b/app/javascript/material-icons/400-24px/contact_mail.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/database-fill.svg b/app/javascript/material-icons/400-24px/database-fill.svg new file mode 100644 index 0000000000..3520f69614 --- /dev/null +++ b/app/javascript/material-icons/400-24px/database-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/database.svg b/app/javascript/material-icons/400-24px/database.svg index 54ca2f4e56..a3bc2bfbc2 100644 --- a/app/javascript/material-icons/400-24px/database.svg +++ b/app/javascript/material-icons/400-24px/database.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/diamond-fill.svg b/app/javascript/material-icons/400-24px/diamond-fill.svg new file mode 100644 index 0000000000..474968ad6f --- /dev/null +++ b/app/javascript/material-icons/400-24px/diamond-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/diamond.svg b/app/javascript/material-icons/400-24px/diamond.svg index 26f4814b44..b604492fa8 100644 --- a/app/javascript/material-icons/400-24px/diamond.svg +++ b/app/javascript/material-icons/400-24px/diamond.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/filter_alt-fill.svg b/app/javascript/material-icons/400-24px/filter_alt-fill.svg new file mode 100644 index 0000000000..ec1d90bba6 --- /dev/null +++ b/app/javascript/material-icons/400-24px/filter_alt-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/filter_alt.svg b/app/javascript/material-icons/400-24px/filter_alt.svg index 0294cf1da5..e4af9efd5d 100644 --- a/app/javascript/material-icons/400-24px/filter_alt.svg +++ b/app/javascript/material-icons/400-24px/filter_alt.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/groups-fill.svg b/app/javascript/material-icons/400-24px/groups-fill.svg new file mode 100644 index 0000000000..754eb0946c --- /dev/null +++ b/app/javascript/material-icons/400-24px/groups-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/groups.svg b/app/javascript/material-icons/400-24px/groups.svg index 0e795eb301..998ff03729 100644 --- a/app/javascript/material-icons/400-24px/groups.svg +++ b/app/javascript/material-icons/400-24px/groups.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/hide_source-fill.svg b/app/javascript/material-icons/400-24px/hide_source-fill.svg new file mode 100644 index 0000000000..959631bc1a --- /dev/null +++ b/app/javascript/material-icons/400-24px/hide_source-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/hide_source.svg b/app/javascript/material-icons/400-24px/hide_source.svg index d103ed770a..09633cef8c 100644 --- a/app/javascript/material-icons/400-24px/hide_source.svg +++ b/app/javascript/material-icons/400-24px/hide_source.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/inbox-fill.svg b/app/javascript/material-icons/400-24px/inbox-fill.svg new file mode 100644 index 0000000000..15ae2d8f3c --- /dev/null +++ b/app/javascript/material-icons/400-24px/inbox-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/inbox.svg b/app/javascript/material-icons/400-24px/inbox.svg index 427817958c..32c727e810 100644 --- a/app/javascript/material-icons/400-24px/inbox.svg +++ b/app/javascript/material-icons/400-24px/inbox.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/list-fill.svg b/app/javascript/material-icons/400-24px/list-fill.svg new file mode 100644 index 0000000000..c9cbe35eb5 --- /dev/null +++ b/app/javascript/material-icons/400-24px/list-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/list.svg b/app/javascript/material-icons/400-24px/list.svg index 457a820ab1..c9cbe35eb5 100644 --- a/app/javascript/material-icons/400-24px/list.svg +++ b/app/javascript/material-icons/400-24px/list.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/mail-fill.svg b/app/javascript/material-icons/400-24px/mail-fill.svg new file mode 100644 index 0000000000..5e7e4a2fb2 --- /dev/null +++ b/app/javascript/material-icons/400-24px/mail-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/mail.svg b/app/javascript/material-icons/400-24px/mail.svg index a92ea7b198..15e1d12d4e 100644 --- a/app/javascript/material-icons/400-24px/mail.svg +++ b/app/javascript/material-icons/400-24px/mail.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/mood-fill.svg b/app/javascript/material-icons/400-24px/mood-fill.svg new file mode 100644 index 0000000000..9480d0fb92 --- /dev/null +++ b/app/javascript/material-icons/400-24px/mood-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/mood.svg b/app/javascript/material-icons/400-24px/mood.svg index 27b3534244..46cafa7680 100644 --- a/app/javascript/material-icons/400-24px/mood.svg +++ b/app/javascript/material-icons/400-24px/mood.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/report-fill.svg b/app/javascript/material-icons/400-24px/report-fill.svg new file mode 100644 index 0000000000..50c638869d --- /dev/null +++ b/app/javascript/material-icons/400-24px/report-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/report.svg b/app/javascript/material-icons/400-24px/report.svg index f281f0e1fa..b08b5a1c98 100644 --- a/app/javascript/material-icons/400-24px/report.svg +++ b/app/javascript/material-icons/400-24px/report.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/safety_check-fill.svg b/app/javascript/material-icons/400-24px/safety_check-fill.svg new file mode 100644 index 0000000000..b38091a8ec --- /dev/null +++ b/app/javascript/material-icons/400-24px/safety_check-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/safety_check.svg b/app/javascript/material-icons/400-24px/safety_check.svg index f4eab46fb7..87bdba21fe 100644 --- a/app/javascript/material-icons/400-24px/safety_check.svg +++ b/app/javascript/material-icons/400-24px/safety_check.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/speed-fill.svg b/app/javascript/material-icons/400-24px/speed-fill.svg new file mode 100644 index 0000000000..dca22ac521 --- /dev/null +++ b/app/javascript/material-icons/400-24px/speed-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/speed.svg b/app/javascript/material-icons/400-24px/speed.svg index ceb855c684..0837877f42 100644 --- a/app/javascript/material-icons/400-24px/speed.svg +++ b/app/javascript/material-icons/400-24px/speed.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/trending_up-fill.svg b/app/javascript/material-icons/400-24px/trending_up-fill.svg new file mode 100644 index 0000000000..cd0e368964 --- /dev/null +++ b/app/javascript/material-icons/400-24px/trending_up-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/trending_up.svg b/app/javascript/material-icons/400-24px/trending_up.svg index 06f9ba2063..cd0e368964 100644 --- a/app/javascript/material-icons/400-24px/trending_up.svg +++ b/app/javascript/material-icons/400-24px/trending_up.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/lib/tasks/icons.rake b/lib/tasks/icons.rake index 96e0a14315..9a05cf3499 100644 --- a/lib/tasks/icons.rake +++ b/lib/tasks/icons.rake @@ -38,6 +38,20 @@ def find_used_icons end end + Rails.root.join('config', 'navigation.rb').open('r') do |file| + pattern = /material_symbol\('(?[^']*)'\)/ + file.each_line do |line| + match = pattern.match(line) + next if match.blank? + + # navigation.rb only uses 400x24 icons, per material_symbol() in + # app/helpers/application_helper.rb + icons_by_weight_and_size[400] ||= {} + icons_by_weight_and_size[400][24] ||= Set.new + icons_by_weight_and_size[400][24] << match['icon'] + end + end + icons_by_weight_and_size end From 7b92cf3b4771b42ff3895f247c006679e9a11ff6 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 1 Oct 2024 14:52:13 +0200 Subject: [PATCH 029/150] Fix unneeded requests to blocked domains when receiving relayed signed activities from them (#31161) --- app/services/activitypub/process_collection_service.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/services/activitypub/process_collection_service.rb b/app/services/activitypub/process_collection_service.rb index 4f049a5ae9..cadc7d2d10 100644 --- a/app/services/activitypub/process_collection_service.rb +++ b/app/services/activitypub/process_collection_service.rb @@ -2,6 +2,7 @@ class ActivityPub::ProcessCollectionService < BaseService include JsonLdHelper + include DomainControlHelper def call(body, actor, **options) @account = actor @@ -69,6 +70,9 @@ class ActivityPub::ProcessCollectionService < BaseService end def verify_account! + return unless @json['signature'].is_a?(Hash) + return if domain_not_allowed?(@json['signature']['creator']) + @options[:relayed_through_actor] = @account @account = ActivityPub::LinkedDataSignature.new(@json).verify_actor! @account = nil unless @account.is_a?(Account) From f73787a4b84eb23ccad9d425b52aa09e1c26e18c Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 09:38:29 -0400 Subject: [PATCH 030/150] Fix broken border on applications list (#32147) --- app/views/settings/applications/index.html.haml | 4 +++- app/views/settings/applications/show.html.haml | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/views/settings/applications/index.html.haml b/app/views/settings/applications/index.html.haml index 80eaed5c39..e3011947a6 100644 --- a/app/views/settings/applications/index.html.haml +++ b/app/views/settings/applications/index.html.haml @@ -18,7 +18,9 @@ - @applications.each do |application| %tr %td= link_to application.name, settings_application_path(application) - %th= application.scopes + %th + - application.scopes.to_s.split.each do |scope| + = tag.samp(scope, class: 'information-badge', title: t("doorkeeper.scopes.#{scope}")) %td = table_link_to 'close', t('doorkeeper.applications.index.delete'), settings_application_path(application), method: :delete, data: { confirm: t('doorkeeper.applications.confirmations.destroy') } diff --git a/app/views/settings/applications/show.html.haml b/app/views/settings/applications/show.html.haml index 099e0d96a8..bfde27daa9 100644 --- a/app/views/settings/applications/show.html.haml +++ b/app/views/settings/applications/show.html.haml @@ -15,10 +15,11 @@ %td %code= @application.secret %tr - %th{ rowspan: 2 }= t('applications.your_token') + %th= t('applications.your_token') %td %code= current_user.token_for_app(@application).token %tr + %th %td= table_link_to 'refresh', t('applications.regenerate_token'), regenerate_settings_application_path(@application), method: :post %hr/ From f10d61bf86559bc1464b2e7972b8980ae789908d Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 09:41:25 -0400 Subject: [PATCH 031/150] Adjust spacing on setting sub-nav items when below mobile size (#32137) --- app/javascript/styles/mastodon/admin.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index da76fa1107..0712a0d3f4 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -226,6 +226,10 @@ $content-width: 840px; gap: 5px; white-space: nowrap; + @media screen and (max-width: $mobile-breakpoint) { + flex: 1 0 50%; + } + &:hover, &:focus, &:active { From df98cf71e30063ece4022ae4a8a73c21dfea5f74 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 09:50:20 -0400 Subject: [PATCH 032/150] Avoid repeated icon stack in settings sidebar (#32201) --- config/navigation.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/navigation.rb b/config/navigation.rb index 09a7b55b5e..7ec7ecb7e7 100644 --- a/config/navigation.rb +++ b/config/navigation.rb @@ -24,7 +24,7 @@ SimpleNavigation::Configuration.run do |navigation| n.item :filters, safe_join([material_symbol('filter_alt'), t('filters.index.title')]), filters_path, highlights_on: %r{/filters}, if: -> { current_user.functional? && !self_destruct } n.item :statuses_cleanup, safe_join([material_symbol('history'), t('settings.statuses_cleanup')]), statuses_cleanup_path, if: -> { current_user.functional_or_moved? && !self_destruct } - n.item :security, safe_join([material_symbol('lock'), t('settings.account')]), edit_user_registration_path do |s| + n.item :security, safe_join([material_symbol('account_circle'), t('settings.account')]), edit_user_registration_path do |s| s.item :password, safe_join([material_symbol('lock'), t('settings.account_settings')]), edit_user_registration_path, highlights_on: %r{^/auth|/settings/delete|/settings/migration|/settings/aliases|/settings/login_activities|^/disputes} s.item :two_factor_authentication, safe_join([material_symbol('safety_check'), t('settings.two_factor_authentication')]), settings_two_factor_authentication_methods_path, highlights_on: %r{/settings/two_factor_authentication|/settings/otp_authentication|/settings/security_keys} s.item :authorized_apps, safe_join([material_symbol('list_alt'), t('settings.authorized_apps')]), oauth_authorized_applications_path, if: -> { !self_destruct } From 65508bb0c07bab4760576a9c59cacb43cf7d1301 Mon Sep 17 00:00:00 2001 From: Jeong Arm Date: Tue, 1 Oct 2024 22:54:28 +0900 Subject: [PATCH 033/150] Show timestamp when the user deletes their account on admin dashboard (#25640) Co-authored-by: Claire --- app/helpers/admin/dashboard_helper.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/helpers/admin/dashboard_helper.rb b/app/helpers/admin/dashboard_helper.rb index 4de779b79a..f87fdad708 100644 --- a/app/helpers/admin/dashboard_helper.rb +++ b/app/helpers/admin/dashboard_helper.rb @@ -30,6 +30,8 @@ module Admin::DashboardHelper [account.user_current_sign_in_at, false] elsif account.user_pending? [account.user_created_at, true] + elsif account.suspended_at.present? && account.local? && account.user.nil? + [account.suspended_at, true] elsif account.last_status_at.present? [account.last_status_at, true] else From 4cae309f6a1835dcff6b85ac31b046092e2985a1 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 09:56:43 -0400 Subject: [PATCH 034/150] Fix `Rails/CreateTableWithTimestamps` cop (#30836) --- db/migrate/.rubocop.yml | 5 +++++ db/migrate/20170508230434_create_conversation_mutes.rb | 2 +- db/migrate/20170823162448_create_status_pins.rb | 2 +- db/migrate/20171116161857_create_list_accounts.rb | 2 +- db/migrate/20180929222014_create_account_conversations.rb | 2 +- db/migrate/20181007025445_create_pghero_space_stats.rb | 2 +- db/migrate/20190103124649_create_scheduled_statuses.rb | 2 +- db/migrate/20220824233535_create_status_trends.rb | 2 +- db/migrate/20221006061337_create_preview_card_trends.rb | 2 +- 9 files changed, 13 insertions(+), 8 deletions(-) diff --git a/db/migrate/.rubocop.yml b/db/migrate/.rubocop.yml index 4e23800dd1..6f8b6cc60d 100644 --- a/db/migrate/.rubocop.yml +++ b/db/migrate/.rubocop.yml @@ -2,3 +2,8 @@ inherit_from: ../../.rubocop.yml Naming/VariableNumber: CheckSymbols: false + +# Enabled here as workaround for https://docs.rubocop.org/rubocop/configuration.html#path-relativity +Rails/CreateTableWithTimestamps: + Include: + - '*.rb' diff --git a/db/migrate/20170508230434_create_conversation_mutes.rb b/db/migrate/20170508230434_create_conversation_mutes.rb index 01122c4516..4beba9dfa3 100644 --- a/db/migrate/20170508230434_create_conversation_mutes.rb +++ b/db/migrate/20170508230434_create_conversation_mutes.rb @@ -2,7 +2,7 @@ class CreateConversationMutes < ActiveRecord::Migration[5.0] def change - create_table :conversation_mutes do |t| + create_table :conversation_mutes do |t| # rubocop:disable Rails/CreateTableWithTimestamps t.integer :account_id, null: false t.bigint :conversation_id, null: false end diff --git a/db/migrate/20170823162448_create_status_pins.rb b/db/migrate/20170823162448_create_status_pins.rb index c8d3fab3a5..2cf3a85ca9 100644 --- a/db/migrate/20170823162448_create_status_pins.rb +++ b/db/migrate/20170823162448_create_status_pins.rb @@ -2,7 +2,7 @@ class CreateStatusPins < ActiveRecord::Migration[5.1] def change - create_table :status_pins do |t| + create_table :status_pins do |t| # rubocop:disable Rails/CreateTableWithTimestamps t.belongs_to :account, foreign_key: { on_delete: :cascade }, null: false t.belongs_to :status, foreign_key: { on_delete: :cascade }, null: false end diff --git a/db/migrate/20171116161857_create_list_accounts.rb b/db/migrate/20171116161857_create_list_accounts.rb index ff9ab3faad..b0371e4c88 100644 --- a/db/migrate/20171116161857_create_list_accounts.rb +++ b/db/migrate/20171116161857_create_list_accounts.rb @@ -2,7 +2,7 @@ class CreateListAccounts < ActiveRecord::Migration[5.2] def change - create_table :list_accounts do |t| + create_table :list_accounts do |t| # rubocop:disable Rails/CreateTableWithTimestamps t.belongs_to :list, foreign_key: { on_delete: :cascade }, null: false t.belongs_to :account, foreign_key: { on_delete: :cascade }, null: false t.belongs_to :follow, foreign_key: { on_delete: :cascade }, null: false diff --git a/db/migrate/20180929222014_create_account_conversations.rb b/db/migrate/20180929222014_create_account_conversations.rb index 9386b86e7c..4e85e68d47 100644 --- a/db/migrate/20180929222014_create_account_conversations.rb +++ b/db/migrate/20180929222014_create_account_conversations.rb @@ -2,7 +2,7 @@ class CreateAccountConversations < ActiveRecord::Migration[5.2] def change - create_table :account_conversations do |t| + create_table :account_conversations do |t| # rubocop:disable Rails/CreateTableWithTimestamps t.belongs_to :account, foreign_key: { on_delete: :cascade } t.belongs_to :conversation, foreign_key: { on_delete: :cascade } t.bigint :participant_account_ids, array: true, null: false, default: [] diff --git a/db/migrate/20181007025445_create_pghero_space_stats.rb b/db/migrate/20181007025445_create_pghero_space_stats.rb index ddaf4aef31..696b53d8d7 100644 --- a/db/migrate/20181007025445_create_pghero_space_stats.rb +++ b/db/migrate/20181007025445_create_pghero_space_stats.rb @@ -2,7 +2,7 @@ class CreatePgheroSpaceStats < ActiveRecord::Migration[5.2] def change - create_table :pghero_space_stats do |t| + create_table :pghero_space_stats do |t| # rubocop:disable Rails/CreateTableWithTimestamps t.text :database t.text :schema t.text :relation diff --git a/db/migrate/20190103124649_create_scheduled_statuses.rb b/db/migrate/20190103124649_create_scheduled_statuses.rb index a66546187e..02b4916be8 100644 --- a/db/migrate/20190103124649_create_scheduled_statuses.rb +++ b/db/migrate/20190103124649_create_scheduled_statuses.rb @@ -2,7 +2,7 @@ class CreateScheduledStatuses < ActiveRecord::Migration[5.2] def change - create_table :scheduled_statuses do |t| + create_table :scheduled_statuses do |t| # rubocop:disable Rails/CreateTableWithTimestamps t.belongs_to :account, foreign_key: { on_delete: :cascade } t.datetime :scheduled_at, index: true t.jsonb :params diff --git a/db/migrate/20220824233535_create_status_trends.rb b/db/migrate/20220824233535_create_status_trends.rb index 52dcbf8f38..e68e5b7c11 100644 --- a/db/migrate/20220824233535_create_status_trends.rb +++ b/db/migrate/20220824233535_create_status_trends.rb @@ -2,7 +2,7 @@ class CreateStatusTrends < ActiveRecord::Migration[6.1] def change - create_table :status_trends do |t| + create_table :status_trends do |t| # rubocop:disable Rails/CreateTableWithTimestamps t.references :status, null: false, foreign_key: { on_delete: :cascade }, index: { unique: true } t.references :account, null: false, foreign_key: { on_delete: :cascade } t.float :score, null: false, default: 0 diff --git a/db/migrate/20221006061337_create_preview_card_trends.rb b/db/migrate/20221006061337_create_preview_card_trends.rb index 934a06e24d..266f644023 100644 --- a/db/migrate/20221006061337_create_preview_card_trends.rb +++ b/db/migrate/20221006061337_create_preview_card_trends.rb @@ -2,7 +2,7 @@ class CreatePreviewCardTrends < ActiveRecord::Migration[6.1] def change - create_table :preview_card_trends do |t| + create_table :preview_card_trends do |t| # rubocop:disable Rails/CreateTableWithTimestamps t.references :preview_card, null: false, foreign_key: { on_delete: :cascade }, index: { unique: true } t.float :score, null: false, default: 0 t.integer :rank, null: false, default: 0 From a2c4ba20010a1fabca65ff6353e1b0fbea3b5f6d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 17:10:56 +0200 Subject: [PATCH 035/150] Update dependency rubocop-rspec to v3.1.0 (#32202) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 334a9e30d1..c623f92e7d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -756,7 +756,7 @@ GEM rack (>= 1.1) rubocop (>= 1.52.0, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rspec (3.0.5) + rubocop-rspec (3.1.0) rubocop (~> 1.61) rubocop-rspec_rails (2.30.0) rubocop (~> 1.61) From f91f077985eccf9933346052ce4ee532215099c6 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Tue, 1 Oct 2024 12:26:30 -0400 Subject: [PATCH 036/150] Enable ESLlint no-case-declarations (#30768) --- .eslintrc.js | 1 - app/javascript/mastodon/actions/streaming.js | 3 ++- app/javascript/mastodon/reducers/compose.js | 3 ++- app/javascript/mastodon/reducers/notifications.js | 3 ++- app/javascript/mastodon/reducers/search.js | 3 ++- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index b6e4253e61..93ff1d7b59 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -64,7 +64,6 @@ module.exports = defineConfig({ 'indent': ['error', 2], 'jsx-quotes': ['error', 'prefer-single'], 'semi': ['error', 'always'], - 'no-case-declarations': 'off', 'no-catch-shadow': 'error', 'no-console': [ 'warn', diff --git a/app/javascript/mastodon/actions/streaming.js b/app/javascript/mastodon/actions/streaming.js index b6fc31fae8..30e643363a 100644 --- a/app/javascript/mastodon/actions/streaming.js +++ b/app/javascript/mastodon/actions/streaming.js @@ -106,12 +106,13 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti dispatch(processNewNotificationForGroups(notificationJSON)); break; } - case 'notifications_merged': + case 'notifications_merged': { const state = getState(); if (state.notifications.top || !state.notifications.mounted) dispatch(expandNotifications({ forceLoad: true, maxId: undefined })); dispatch(refreshStaleNotificationGroups()); break; + } case 'conversation': // @ts-expect-error dispatch(updateConversations(JSON.parse(data.payload))); diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index 9f66c09631..e77f2ac6e6 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -407,7 +407,7 @@ export default function compose(state = initialState, action) { return item; })); - case INIT_MEDIA_EDIT_MODAL: + case INIT_MEDIA_EDIT_MODAL: { const media = state.get('media_attachments').find(item => item.get('id') === action.id); return state.set('media_modal', ImmutableMap({ id: action.id, @@ -416,6 +416,7 @@ export default function compose(state = initialState, action) { focusY: media.getIn(['meta', 'focus', 'y'], 0), dirty: false, })); + } case COMPOSE_CHANGE_MEDIA_DESCRIPTION: return state.setIn(['media_modal', 'description'], action.description).setIn(['media_modal', 'dirty'], true); case COMPOSE_CHANGE_MEDIA_FOCUS: diff --git a/app/javascript/mastodon/reducers/notifications.js b/app/javascript/mastodon/reducers/notifications.js index 622f5e8e88..c99a619b52 100644 --- a/app/javascript/mastodon/reducers/notifications.js +++ b/app/javascript/mastodon/reducers/notifications.js @@ -298,9 +298,10 @@ export default function notifications(state = initialState, action) { return action.payload.timeline === 'home' ? state.update(action.payload.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(null) : items) : state; - case NOTIFICATIONS_MARK_AS_READ: + case NOTIFICATIONS_MARK_AS_READ: { const lastNotification = state.get('items').find(item => item !== null); return lastNotification ? recountUnread(state, lastNotification.get('id')) : state; + } case NOTIFICATIONS_SET_BROWSER_SUPPORT: return state.set('browserSupport', action.value); case NOTIFICATIONS_SET_BROWSER_PERMISSION: diff --git a/app/javascript/mastodon/reducers/search.js b/app/javascript/mastodon/reducers/search.js index 7828d49eee..7de1c65c07 100644 --- a/app/javascript/mastodon/reducers/search.js +++ b/app/javascript/mastodon/reducers/search.js @@ -72,9 +72,10 @@ export default function search(state = initialState, action) { }); case SEARCH_EXPAND_REQUEST: return state.set('type', action.searchType).set('isLoading', true); - case SEARCH_EXPAND_SUCCESS: + case SEARCH_EXPAND_SUCCESS: { const results = action.searchType === 'hashtags' ? ImmutableOrderedSet(fromJS(action.results.hashtags)) : action.results[action.searchType].map(item => item.id); return state.updateIn(['results', action.searchType], list => list.union(results)).set('isLoading', false); + } case SEARCH_HISTORY_UPDATE: return state.set('recent', ImmutableOrderedSet(fromJS(action.recent))); default: From 66b2bc1c841d6ad59fe4961ff9f0075fa3e52d50 Mon Sep 17 00:00:00 2001 From: Jeong Arm Date: Wed, 2 Oct 2024 17:08:02 +0900 Subject: [PATCH 037/150] Ignore error if mentioned account was not processable (#29215) Co-authored-by: Claire --- app/lib/activitypub/activity/create.rb | 10 ++++++ app/workers/mention_resolve_worker.rb | 37 +++++++++++++++++++ spec/lib/activitypub/activity/create_spec.rb | 37 +++++++++++++++++++ spec/workers/mention_resolve_worker_spec.rb | 38 ++++++++++++++++++++ 4 files changed, 122 insertions(+) create mode 100644 app/workers/mention_resolve_worker.rb create mode 100644 spec/workers/mention_resolve_worker_spec.rb diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 09a8caf1fc..928803cd64 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -42,6 +42,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity def process_status @tags = [] @mentions = [] + @unresolved_mentions = [] @silenced_account_ids = [] @params = {} @@ -55,6 +56,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity end resolve_thread(@status) + resolve_unresolved_mentions(@status) fetch_replies(@status) distribute forward_for_reply @@ -197,6 +199,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity return if account.nil? @mentions << Mention.new(account: account, silent: false) + rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError + @unresolved_mentions << tag['href'] end def process_emoji(tag) @@ -301,6 +305,12 @@ class ActivityPub::Activity::Create < ActivityPub::Activity ThreadResolveWorker.perform_async(status.id, in_reply_to_uri, { 'request_id' => @options[:request_id] }) end + def resolve_unresolved_mentions(status) + @unresolved_mentions.uniq.each do |uri| + MentionResolveWorker.perform_in(rand(30...600).seconds, status.id, uri, { 'request_id' => @options[:request_id] }) + end + end + def fetch_replies(status) collection = @object['replies'] return if collection.blank? diff --git a/app/workers/mention_resolve_worker.rb b/app/workers/mention_resolve_worker.rb new file mode 100644 index 0000000000..72dcd9633f --- /dev/null +++ b/app/workers/mention_resolve_worker.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +class MentionResolveWorker + include Sidekiq::Worker + include ExponentialBackoff + include JsonLdHelper + + sidekiq_options queue: 'pull', retry: 7 + + def perform(status_id, uri, options = {}) + status = Status.find_by(id: status_id) + return if status.nil? + + account = account_from_uri(uri) + account = ActivityPub::FetchRemoteAccountService.new.call(uri, request_id: options[:request_id]) if account.nil? + + return if account.nil? + + status.mentions.create!(account: account, silent: false) + rescue ActiveRecord::RecordNotFound + # Do nothing + rescue Mastodon::UnexpectedResponseError => e + response = e.response + + if response_error_unsalvageable?(response) + # Give up + else + raise e + end + end + + private + + def account_from_uri(uri) + ActivityPub::TagManager.instance.uri_to_resource(uri, Account) + end +end diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb index 0986ae1715..bdc8fd9d51 100644 --- a/spec/lib/activitypub/activity/create_spec.rb +++ b/spec/lib/activitypub/activity/create_spec.rb @@ -63,6 +63,24 @@ RSpec.describe ActivityPub::Activity::Create do } end + let(:invalid_mention_json) do + { + id: [ActivityPub::TagManager.instance.uri_for(sender), 'post2'].join('/'), + type: 'Note', + to: [ + 'https://www.w3.org/ns/activitystreams#Public', + ActivityPub::TagManager.instance.uri_for(follower), + ], + content: '@bob lorem ipsum', + published: 1.hour.ago.utc.iso8601, + updated: 1.hour.ago.utc.iso8601, + tag: { + type: 'Mention', + href: 'http://notexisting.dontexistingtld/actor', + }, + } + end + def activity_for_object(json) { '@context': 'https://www.w3.org/ns/activitystreams', @@ -117,6 +135,25 @@ RSpec.describe ActivityPub::Activity::Create do # Creates two notifications expect(Notification.count).to eq 2 end + + it 'ignores unprocessable mention', :aggregate_failures do + stub_request(:get, invalid_mention_json[:tag][:href]).to_raise(HTTP::ConnectionError) + # When receiving the post that contains an invalid mention… + described_class.new(activity_for_object(invalid_mention_json), sender, delivery: true).perform + + # NOTE: Refering explicitly to the workers is a bit awkward + DistributionWorker.drain + FeedInsertWorker.drain + + # …it creates a status + status = Status.find_by(uri: invalid_mention_json[:id]) + + # Check the process did not crash + expect(status.nil?).to be false + + # It has queued a mention resolve job + expect(MentionResolveWorker).to have_enqueued_sidekiq_job(status.id, invalid_mention_json[:tag][:href], anything) + end end describe '#perform' do diff --git a/spec/workers/mention_resolve_worker_spec.rb b/spec/workers/mention_resolve_worker_spec.rb new file mode 100644 index 0000000000..5e23876b4a --- /dev/null +++ b/spec/workers/mention_resolve_worker_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe MentionResolveWorker do + let(:status_id) { -42 } + let(:uri) { 'https://example.com/users/unknown' } + + describe '#perform' do + subject { described_class.new.perform(status_id, uri, {}) } + + context 'with a non-existent status' do + it 'returns nil' do + expect(subject).to be_nil + end + end + + context 'with a valid user' do + let(:status) { Fabricate(:status) } + let(:status_id) { status.id } + + let(:service_double) { instance_double(ActivityPub::FetchRemoteAccountService) } + + before do + allow(ActivityPub::FetchRemoteAccountService).to receive(:new).and_return(service_double) + + allow(service_double).to receive(:call).with(uri, anything) { Fabricate(:account, domain: 'example.com', uri: uri) } + end + + it 'resolves the account and adds a new mention', :aggregate_failures do + expect { subject } + .to change { status.reload.mentions }.from([]).to(a_collection_including(having_attributes(account: having_attributes(uri: uri), silent: false))) + + expect(service_double).to have_received(:call).once + end + end + end +end From ea72d5ec3a2eda181baa6846a67aec9b8b4b0142 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 2 Oct 2024 09:05:57 +0000 Subject: [PATCH 038/150] New Crowdin Translations (automated) (#32214) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/cy.json | 7 +++ app/javascript/mastodon/locales/eo.json | 64 ++++++++++++------------ app/javascript/mastodon/locales/gl.json | 2 +- app/javascript/mastodon/locales/he.json | 8 +++ app/javascript/mastodon/locales/hu.json | 4 +- app/javascript/mastodon/locales/ja.json | 1 + app/javascript/mastodon/locales/kab.json | 2 + app/javascript/mastodon/locales/no.json | 2 + app/javascript/mastodon/locales/tr.json | 5 ++ config/locales/cy.yml | 4 ++ config/locales/doorkeeper.gl.yml | 2 +- config/locales/he.yml | 4 ++ config/locales/nn.yml | 6 +-- 13 files changed, 72 insertions(+), 39 deletions(-) diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json index f2d0708882..52dc6a49e2 100644 --- a/app/javascript/mastodon/locales/cy.json +++ b/app/javascript/mastodon/locales/cy.json @@ -85,6 +85,7 @@ "alert.rate_limited.title": "Cyfradd gyfyngedig", "alert.unexpected.message": "Digwyddodd gwall annisgwyl.", "alert.unexpected.title": "Wps!", + "alt_text_badge.title": "Testun Amgen", "announcement.announcement": "Cyhoeddiad", "attachments_list.unprocessed": "(heb eu prosesu)", "audio.hide": "Cuddio sain", @@ -221,6 +222,7 @@ "domain_block_modal.they_cant_follow": "Ni all neb o'r gweinydd hwn eich dilyn.", "domain_block_modal.they_wont_know": "Fyddan nhw ddim yn gwybod eu bod wedi cael eu blocio.", "domain_block_modal.title": "Blocio parth?", + "domain_block_modal.you_will_lose_relationships": "Byddwch yn colli'r holl ddilynwyr a phobl rydych chi'n eu dilyn o'r gweinydd hwn.", "domain_block_modal.you_wont_see_posts": "Fyddwch chi ddim yn gweld postiadau na hysbysiadau gan ddefnyddwyr ar y gweinydd hwn.", "domain_pill.activitypub_lets_connect": "Mae'n caniatáu ichi gysylltu a rhyngweithio â phobl nid yn unig ar Mastodon, ond ar draws gwahanol apiau cymdeithasol hefyd.", "domain_pill.activitypub_like_language": "Mae ActivityPub fel yr iaith y mae Mastodon yn ei siarad â rhwydweithiau cymdeithasol eraill.", @@ -849,6 +851,11 @@ "upload_error.poll": "Nid oes modd llwytho ffeiliau â phleidleisiau.", "upload_form.audio_description": "Disgrifio ar gyfer pobl sydd â cholled clyw", "upload_form.description": "Disgrifio i'r rheini a nam ar ei golwg", + "upload_form.drag_and_drop.instructions": "I godi atodiad cyfryngau, pwyswch y space neu enter. Wrth lusgo, defnyddiwch y bysellau saeth i symud yr atodiad cyfryngau i unrhyw gyfeiriad penodol. Pwyswch space neu enter eto i ollwng yr atodiad cyfryngau yn ei safle newydd, neu pwyswch escape i ddiddymu.", + "upload_form.drag_and_drop.on_drag_cancel": "Cafodd llusgo ei ddiddymu. Cafodd atodiad cyfryngau {item} ei ollwng.", + "upload_form.drag_and_drop.on_drag_end": "Cafodd atodiad cyfryngau {item} ei ollwng.", + "upload_form.drag_and_drop.on_drag_over": "Symudwyd atodiad cyfryngau {item}.", + "upload_form.drag_and_drop.on_drag_start": "Atodiad cyfryngau godwyd {item}.", "upload_form.edit": "Golygu", "upload_form.thumbnail": "Newid llun bach", "upload_form.video_description": "Disgrifio ar gyfer pobl sydd â cholled clyw neu amhariad golwg", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index 4268c38535..35c2a5c744 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -22,10 +22,10 @@ "account.cancel_follow_request": "Nuligi peton por sekvado", "account.copy": "Kopii ligilon al profilo", "account.direct": "Private mencii @{name}", - "account.disable_notifications": "Ne plu sciigi min, kiam @{name} mesaĝas", + "account.disable_notifications": "Ĉesu sciigi min kiam @{name} afiŝas", "account.domain_blocked": "Domajno blokita", "account.edit_profile": "Redakti la profilon", - "account.enable_notifications": "Sciigi min, kiam @{name} mesaĝas", + "account.enable_notifications": "Sciigu min kiam @{name} afiŝos", "account.endorse": "Rekomendi ĉe via profilo", "account.featured_tags.last_status_at": "Lasta afîŝo je {date}", "account.featured_tags.last_status_never": "Neniu afiŝo", @@ -49,14 +49,14 @@ "account.mention": "Mencii @{name}", "account.moved_to": "{name} indikis, ke ria nova konto estas nun:", "account.mute": "Silentigi @{name}", - "account.mute_notifications_short": "Silentigu Sciigojn", + "account.mute_notifications_short": "Silentigu sciigojn", "account.mute_short": "Silentigu", "account.muted": "Silentigita", "account.mutual": "Reciproka", "account.no_bio": "Neniu priskribo estas provizita.", "account.open_original_page": "Malfermi la originalan paĝon", "account.posts": "Afiŝoj", - "account.posts_with_replies": "Mesaĝoj kaj respondoj", + "account.posts_with_replies": "Afiŝoj kaj respondoj", "account.report": "Raporti @{name}", "account.requested": "Atendo de aprobo. Klaku por nuligi la peton por sekvado", "account.requested_follow": "{name} petis sekvi vin", @@ -69,7 +69,7 @@ "account.unendorse": "Ne plu rekomendi ĉe la profilo", "account.unfollow": "Ĉesi sekvi", "account.unmute": "Ne plu silentigi @{name}", - "account.unmute_notifications_short": "Malsilentigu Sciigojn", + "account.unmute_notifications_short": "Malsilentigu sciigojn", "account.unmute_short": "Ne plu silentigi", "account_note.placeholder": "Alklaku por aldoni noton", "admin.dashboard.daily_retention": "Uzantoretenprocento lau tag post registro", @@ -81,7 +81,7 @@ "admin.impact_report.instance_followers": "Sekvantojn niaj uzantoj perdus", "admin.impact_report.instance_follows": "Sekvantojn ties uzantoj perdus", "admin.impact_report.title": "Influa reporto", - "alert.rate_limited.message": "Bonvolu reprovi post {retry_time, time, medium}.", + "alert.rate_limited.message": "Bonvolu reprovi poste {retry_time, time, medium}.", "alert.rate_limited.title": "Mesaĝkvante limigita", "alert.unexpected.message": "Neatendita eraro okazis.", "alert.unexpected.title": "Aj!", @@ -163,7 +163,7 @@ "compose_form.poll.switch_to_single": "Ŝanĝi la balotenketon por permesi unu solan elekton", "compose_form.poll.type": "Stilo", "compose_form.publish": "Afiŝo", - "compose_form.publish_form": "Afiŝi", + "compose_form.publish_form": "Nova afiŝo", "compose_form.reply": "Respondi", "compose_form.save_changes": "Ĝisdatigi", "compose_form.spoiler.marked": "Forigi la averton de enhavo", @@ -173,7 +173,7 @@ "confirmations.block.confirm": "Bloki", "confirmations.delete.confirm": "Forigi", "confirmations.delete.message": "Ĉu vi certas, ke vi volas forigi ĉi tiun afiŝon?", - "confirmations.delete.title": "Ĉu forigi Afiŝon?", + "confirmations.delete.title": "Ĉu forigi afiŝon?", "confirmations.delete_list.confirm": "Forigi", "confirmations.delete_list.message": "Ĉu vi certas, ke vi volas porĉiame forigi ĉi tiun liston?", "confirmations.delete_list.title": "Ĉu forigi liston?", @@ -213,9 +213,9 @@ "dismissable_banner.community_timeline": "Jen la plej novaj publikaj afiŝoj de uzantoj, kies kontojn gastigas {domain}.", "dismissable_banner.dismiss": "Eksigi", "dismissable_banner.explore_links": "Tiuj novaĵoj estas aktuale priparolataj de uzantoj en tiu ĉi kaj aliaj serviloj, sur la malcentrigita reto.", - "dismissable_banner.explore_statuses": "Ĉi tioj estas afiŝoj de socia reto kiu populariĝas hodiau.", + "dismissable_banner.explore_statuses": "Ĉi tiuj estas afiŝoj de la tuta socia reto, kiuj populariĝas hodiaŭ. Pli novaj afiŝoj kun pli da diskonigoj kaj plej ŝatataj estas rangigitaj pli alte.", "dismissable_banner.explore_tags": "Ĉi tiuj kradvostoj populariĝas en ĉi tiu kaj aliaj serviloj en la malcentraliza reto nun.", - "dismissable_banner.public_timeline": "Ĉi tioj estas plej lastaj publikaj afiŝoj de personoj ĉe socia reto kiu personoj ĉe {domain} sekvas.", + "dismissable_banner.public_timeline": "Ĉi tiuj estas la plej lastatempaj publikaj afiŝoj de homoj en la socia reto, kiujn homoj sur {domain} sekvas.", "domain_block_modal.block": "Bloki servilon", "domain_block_modal.block_account_instead": "Bloki @{name} anstataŭe", "domain_block_modal.they_can_interact_with_old_posts": "Homoj de ĉi tiu servilo povas interagi kun viaj malnovaj afiŝoj.", @@ -265,8 +265,8 @@ "empty_column.direct": "Vi ankoraŭ ne havas privatan mencion. Kiam vi sendos aŭ ricevos iun, tiu aperos ĉi tie.", "empty_column.domain_blocks": "Ankoraŭ neniu domajno estas blokita.", "empty_column.explore_statuses": "Nenio tendencas nun. Rekontrolu poste!", - "empty_column.favourited_statuses": "Vi ankoraŭ ne havas stelumitan afiŝon.", - "empty_column.favourites": "Ankoraŭ neniu stelumis tiun afiŝon.", + "empty_column.favourited_statuses": "Vi ankoraŭ ne havas plej ŝatatajn afiŝojn. Kiam vi ŝatatas unu, ĝi aperos ĉi tie.", + "empty_column.favourites": "Neniu ankoraŭ ŝatis ĉi tiun afiŝon. Kiam iu ŝatos ĝin, ili aperos ĉi tie.", "empty_column.follow_requests": "Vi ne ankoraŭ havas iun peton de sekvado. Kiam vi ricevos unu, ĝi aperos ĉi tie.", "empty_column.followed_tags": "Vi ankoraŭ ne sekvas iujn kradvortojn. Kiam vi faras, ili aperos ĉi tie.", "empty_column.hashtag": "Ankoraŭ estas nenio per ĉi tiu kradvorto.", @@ -296,7 +296,7 @@ "filter_modal.added.review_and_configure": "Por kontroli kaj pli modifi ĉi tiu filtrilkategorio, iru al la {settings_link}.", "filter_modal.added.review_and_configure_title": "Filtrilopcioj", "filter_modal.added.settings_link": "opciopaĝo", - "filter_modal.added.short_explanation": "Ĉi tiu mesaĝo aldonitas al la filtrilkategorio: {title}.", + "filter_modal.added.short_explanation": "Ĉi tiu afiŝo aldonitas al la filtrilkategorio: {title}.", "filter_modal.added.title": "Filtrilo aldonita!", "filter_modal.select_filter.context_mismatch": "ne kongruas la kuntekston", "filter_modal.select_filter.expired": "eksvalidiĝinta", @@ -304,7 +304,7 @@ "filter_modal.select_filter.search": "Serĉi aŭ krei", "filter_modal.select_filter.subtitle": "Uzu ekzistantan kategorion aŭ kreu novan", "filter_modal.select_filter.title": "Filtri ĉi tiun afiŝon", - "filter_modal.title.status": "Filtri mesaĝon", + "filter_modal.title.status": "Filtri afiŝon", "filter_warning.matches_filter": "Filtrilo de kongruoj “{title}”", "filtered_notifications_banner.pending_requests": "El {count, plural, =0 {neniu} one {unu persono} other {# homoj}} vi eble konas", "filtered_notifications_banner.title": "Filtritaj sciigoj", @@ -351,7 +351,7 @@ "hashtag.column_settings.tag_toggle": "Aldoni pliajn etikedojn por ĉi tiu kolumno", "hashtag.counter_by_accounts": "{count, plural,one {{counter} partoprenanto} other {{counter} partoprenantoj}}", "hashtag.counter_by_uses": "{count, plural,one {{counter} afiŝo} other {{counter} afiŝoj}}", - "hashtag.counter_by_uses_today": "{count, plural,one {{counter} afiŝo} other {{counter} afiŝoj}} hodiau", + "hashtag.counter_by_uses_today": "{count, plural,one {{counter} afiŝo} other {{counter} afiŝoj}} hodiaŭ", "hashtag.follow": "Sekvi la kradvorton", "hashtag.unfollow": "Ne plu sekvi la kradvorton", "hashtags.and_other": "…kaj {count, plural,other {# pli}}", @@ -382,9 +382,9 @@ "ignore_notifications_modal.not_following_title": "Ĉu ignori sciigojn de homoj, kiujn vi ne sekvas?", "ignore_notifications_modal.private_mentions_title": "Ĉu ignori sciigojn de nepetitaj privataj mencioj?", "interaction_modal.description.favourite": "Per konto ĉe Mastodon, vi povas stelumiti ĉi tiun afiŝon por sciigi la afiŝanton ke vi aprezigas ŝin kaj konservas por la estonteco.", - "interaction_modal.description.follow": "Kun konto ĉe Mastodon, vi povos sekvi {name} por vidi ties mesaĝojn en via hejmo.", + "interaction_modal.description.follow": "Kun konto ĉe Mastodon, vi povas sekvi {name} por ricevi iliajn afiŝojn en via hejma fluo.", "interaction_modal.description.reblog": "Kun konto ĉe Mastodon, vi povas diskonigi ĉi tiun afiŝon, por ke viaj propraj sekvantoj vidu ĝin.", - "interaction_modal.description.reply": "Kun konto ĉe Mastodon, vi povos respondi al ĉi tiu mesaĝo.", + "interaction_modal.description.reply": "Kun konto ĉe Mastodon, vi povos respondi al ĉi tiu afiŝo.", "interaction_modal.login.action": "Prenu min hejmen", "interaction_modal.login.prompt": "Domajno de via hejma servilo, ekz. mastodon.social", "interaction_modal.no_account_yet": "Ĉu ne estas ĉe Mastodon?", @@ -402,12 +402,12 @@ "keyboard_shortcuts.back": "reveni", "keyboard_shortcuts.blocked": "Malfermi la liston de blokitaj uzantoj", "keyboard_shortcuts.boost": "Diskonigi la mesaĝon", - "keyboard_shortcuts.column": "fokusi mesaĝon en unu el la kolumnoj", + "keyboard_shortcuts.column": "Fokusi kolumnon", "keyboard_shortcuts.compose": "enfokusigi la tekstujon", "keyboard_shortcuts.description": "Priskribo", "keyboard_shortcuts.direct": "por malfermi la kolumnon pri privataj mencioj", "keyboard_shortcuts.down": "iri suben en la listo", - "keyboard_shortcuts.enter": "malfermi mesaĝon", + "keyboard_shortcuts.enter": "Malfermi afiŝon", "keyboard_shortcuts.favourite": "Stelumi afiŝon", "keyboard_shortcuts.favourites": "Malfermi la liston de la stelumoj", "keyboard_shortcuts.federated": "Malfermi la frataran templinion", @@ -421,16 +421,16 @@ "keyboard_shortcuts.my_profile": "malfermi vian profilon", "keyboard_shortcuts.notifications": "malfermi la kolumnon de sciigoj", "keyboard_shortcuts.open_media": "Malfermi plurmedion", - "keyboard_shortcuts.pinned": "malfermi la liston de alpinglitaj mesaĝoj", + "keyboard_shortcuts.pinned": "Malfermu alpinglitajn afiŝojn-liston", "keyboard_shortcuts.profile": "malfermi la profilon de la aŭtoro", - "keyboard_shortcuts.reply": "respondi", + "keyboard_shortcuts.reply": "Respondu al afiŝo", "keyboard_shortcuts.requests": "Malfermi la liston de petoj por sekvado", "keyboard_shortcuts.search": "enfokusigi la serĉilon", "keyboard_shortcuts.spoilers": "Montri/kaŝi la kampon de averto de enhavo (\"CW\")", "keyboard_shortcuts.start": "malfermi la kolumnon «por komenci»", "keyboard_shortcuts.toggle_hidden": "Montri/kaŝi tekston malantaŭ la averto de enhavo (\"CW\")", "keyboard_shortcuts.toggle_sensitivity": "Montri/kaŝi plurmedion", - "keyboard_shortcuts.toot": "Krei novan mesaĝon", + "keyboard_shortcuts.toot": "Komencu novan afiŝon", "keyboard_shortcuts.unfocus": "malenfokusigi la tekstujon aŭ la serĉilon", "keyboard_shortcuts.up": "iri supren en la listo", "lightbox.close": "Fermi", @@ -476,9 +476,9 @@ "navigation_bar.blocks": "Blokitaj uzantoj", "navigation_bar.bookmarks": "Legosignoj", "navigation_bar.community_timeline": "Loka templinio", - "navigation_bar.compose": "Skribi novan mesaĝon", + "navigation_bar.compose": "Redakti novan afiŝon", "navigation_bar.direct": "Privataj mencioj", - "navigation_bar.discover": "Esplori", + "navigation_bar.discover": "Malkovri", "navigation_bar.domain_blocks": "Blokitaj domajnoj", "navigation_bar.explore": "Esplori", "navigation_bar.favourites": "Stelumoj", @@ -487,12 +487,12 @@ "navigation_bar.followed_tags": "Sekvataj kradvortoj", "navigation_bar.follows_and_followers": "Sekvatoj kaj sekvantoj", "navigation_bar.lists": "Listoj", - "navigation_bar.logout": "Adiaŭi", + "navigation_bar.logout": "Elsaluti", "navigation_bar.moderation": "Modereco", "navigation_bar.mutes": "Silentigitaj uzantoj", "navigation_bar.opened_in_classic_interface": "Afiŝoj, kontoj, kaj aliaj specifaj paĝoj kiuj estas malfermititaj defaulta en la klasika reta interfaco.", "navigation_bar.personal": "Persone", - "navigation_bar.pins": "Alpinglitaj mesaĝoj", + "navigation_bar.pins": "Alpinglitaj afiŝoj", "navigation_bar.preferences": "Preferoj", "navigation_bar.public_timeline": "Fratara templinio", "navigation_bar.search": "Serĉi", @@ -572,7 +572,7 @@ "notifications.column_settings.reblog": "Diskonigoj:", "notifications.column_settings.show": "Montri en kolumno", "notifications.column_settings.sound": "Eligi sonon", - "notifications.column_settings.status": "Novaj mesaĝoj:", + "notifications.column_settings.status": "Novaj afiŝoj:", "notifications.column_settings.unread_notifications.category": "Nelegitaj sciigoj", "notifications.column_settings.unread_notifications.highlight": "Marki nelegitajn sciigojn", "notifications.column_settings.update": "Redaktoj:", @@ -660,7 +660,7 @@ "poll.votes": "{votes, plural, one {# voĉdono} other {# voĉdonoj}}", "poll_button.add_poll": "Aldoni balotenketon", "poll_button.remove_poll": "Forigi balotenketon", - "privacy.change": "Agordi mesaĝan privatecon", + "privacy.change": "Ŝanĝu afiŝan privatecon", "privacy.direct.long": "Ĉiuj menciitaj en la afiŝo", "privacy.direct.short": "Specifaj homoj", "privacy.private.long": "Nur viaj sekvantoj", @@ -775,13 +775,13 @@ "sign_in_banner.sso_redirect": "Ensalutu aŭ Registriĝi", "status.admin_account": "Malfermi fasadon de moderigado por @{name}", "status.admin_domain": "Malfermu moderigan interfacon por {domain}", - "status.admin_status": "Malfermi ĉi tiun mesaĝon en la kontrola interfaco", + "status.admin_status": "Malfermi ĉi tiun afiŝon en la kontrola interfaco", "status.block": "Bloki @{name}", "status.bookmark": "Aldoni al la legosignoj", "status.cancel_reblog_private": "Ne plu diskonigi", "status.cannot_reblog": "Ĉi tiun afiŝon ne eblas diskonigi", "status.continued_thread": "Daŭrigis fadenon", - "status.copy": "Kopii la ligilon al la mesaĝo", + "status.copy": "Kopii la ligilon al la afiŝo", "status.delete": "Forigi", "status.detailed_status": "Detala konversacia vido", "status.direct": "Private mencii @{name}", @@ -803,9 +803,9 @@ "status.more": "Pli", "status.mute": "Silentigi @{name}", "status.mute_conversation": "Silentigi konversacion", - "status.open": "Disvolvi la mesaĝon", + "status.open": "Pligrandigu ĉi tiun afiŝon", "status.pin": "Alpingli al la profilo", - "status.pinned": "Alpinglita mesaĝo", + "status.pinned": "Alpinglita afiŝo", "status.read_more": "Legi pli", "status.reblog": "Diskonigi", "status.reblog_private": "Diskonigi kun la sama videbleco", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index 3bc9e1ee59..2a31bfa463 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -193,7 +193,7 @@ "confirmations.reply.message": "Ao responder sobrescribirás a mensaxe que estás a compor. Tes a certeza de que queres continuar?", "confirmations.reply.title": "Editar a publicación?", "confirmations.unfollow.confirm": "Deixar de seguir", - "confirmations.unfollow.message": "Desexas deixar de seguir a {name}?", + "confirmations.unfollow.message": "Tes certeza de querer deixar de seguir a {name}?", "confirmations.unfollow.title": "Deixar de seguir á usuaria?", "content_warning.hide": "Agochar publicación", "content_warning.show": "Mostrar igualmente", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index 4ce0d41620..16f558e543 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -85,6 +85,7 @@ "alert.rate_limited.title": "חלה הגבלה על קצב התעבורה", "alert.unexpected.message": "אירעה שגיאה בלתי צפויה.", "alert.unexpected.title": "אופס!", + "alt_text_badge.title": "כיתוב חלופי", "announcement.announcement": "הכרזה", "attachments_list.unprocessed": "(לא מעובד)", "audio.hide": "השתק", @@ -221,6 +222,8 @@ "domain_block_modal.they_cant_follow": "משתמש משרת זה לא יכול לעקוב אחריך.", "domain_block_modal.they_wont_know": "הם לא ידעו כי נחסמו.", "domain_block_modal.title": "לחסום שרת?", + "domain_block_modal.you_will_lose_num_followers": "{followersCount, plural,one {יאבד לך עוקב אחד}other {יאבדו לך {followersCountDisplay} עוקבים}} {followingCount, plural,one {ונעקב אחד}other {ו־{followingCountDisplay} נעקבים}}.", + "domain_block_modal.you_will_lose_relationships": "יאבדו לך כל העוקבים והנעקבים משרת זה.", "domain_block_modal.you_wont_see_posts": "לא תוכלו לראות הודעות ממשתמשים על שרת זה.", "domain_pill.activitypub_lets_connect": "מאפשר לך להתחבר ולהתרועע עם אחרים לא רק במסטודון, אלא גם ביישומים חברתיים שונים אחרים.", "domain_pill.activitypub_like_language": "אקטיביטיפאב היא למעשה השפה בה מסטודון מדבר עם רשתות חברתיות אחרות.", @@ -849,6 +852,11 @@ "upload_error.poll": "לא ניתן להעלות קובץ עם סקר.", "upload_form.audio_description": "תאר/י עבור לקויי שמיעה", "upload_form.description": "תיאור לכבדי ראיה", + "upload_form.drag_and_drop.instructions": "כדי לבחור קובץ מוצמד, יש ללחוץ על מקש רווח או אנטר. בעת הגרירה, השתמשו במקשי החיצים כדי להזיז את הקובץ המוצמד בכל כיוון. לחצו רווח או אנטר בשנית כדי לעזוב את הקובץ במקומו החדש, או לחצו אסקייפ לביטול.", + "upload_form.drag_and_drop.on_drag_cancel": "הגרירה בוטלה. קובץ המדיה {item} נעזב.", + "upload_form.drag_and_drop.on_drag_end": "קובץ המדיה {item} נעזב.", + "upload_form.drag_and_drop.on_drag_over": "קובץ המדיה {item} הוזז.", + "upload_form.drag_and_drop.on_drag_start": "קובץ המדיה {item} נבחר.", "upload_form.edit": "עריכה", "upload_form.thumbnail": "שנה/י תמונה ממוזערת", "upload_form.video_description": "תאר/י עבור לקויי שמיעה ולקויי ראייה", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index 8baf584b78..f9f403177c 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -852,8 +852,8 @@ "upload_error.poll": "Szavazásnál nem lehet fájlt feltölteni.", "upload_form.audio_description": "Leírás siket vagy hallássérült emberek számára", "upload_form.description": "Leírás vak vagy gyengénlátó emberek számára", - "upload_form.drag_and_drop.instructions": "Egy médiamelléklet kiválasztásához nyomjon Szóközt vagy Entert. Húzás közben használja a nyílgombokat a médiamelléklet adott irányba történő mozgatásához. A médiamelléklet új pozícióba helyezéséhez nyomja meg a Szóközt vagy az Entert, vagy a megszakításhoz nyomja meg az Esc gombot.", - "upload_form.drag_and_drop.on_drag_cancel": "Az áthúzást megszakította. A(z) {item} médiamelléklet el lett dobva.", + "upload_form.drag_and_drop.instructions": "Egy médiamelléklet kiválasztásához nyomj Szóközt vagy Entert. Húzás közben használd a nyílgombokat a médiamelléklet adott irányba történő mozgatásához. A médiamelléklet új pozícióba helyezéséhez nyomd meg a Szóközt vagy az Entert, vagy a megszakításhoz nyomd meg az Esc gombot.", + "upload_form.drag_and_drop.on_drag_cancel": "Az áthúzás megszakítva. A(z) {item} médiamelléklet el lett dobva.", "upload_form.drag_and_drop.on_drag_end": "A(z) {item} médiamelléklet el lett dobva.", "upload_form.drag_and_drop.on_drag_over": "A(z) {item} médiamelléklet át lett helyezve.", "upload_form.drag_and_drop.on_drag_start": "A(z) {item} médiamelléklet fel lett véve.", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index f5e7cc9c04..46444863ac 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -85,6 +85,7 @@ "alert.rate_limited.title": "制限に達しました", "alert.unexpected.message": "不明なエラーが発生しました。", "alert.unexpected.title": "エラー!", + "alt_text_badge.title": "代替テキスト", "announcement.announcement": "お知らせ", "attachments_list.unprocessed": "(未処理)", "audio.hide": "音声を閉じる", diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json index ff06c9c464..07236bb73e 100644 --- a/app/javascript/mastodon/locales/kab.json +++ b/app/javascript/mastodon/locales/kab.json @@ -585,6 +585,7 @@ "status.bookmark": "Creḍ", "status.cancel_reblog_private": "Sefsex beṭṭu", "status.cannot_reblog": "Tasuffeɣt-a ur tezmir ara ad tettwabḍu tikelt-nniḍen", + "status.continued_thread": "Asentel yettkemmil", "status.copy": "Nɣel assaɣ ɣer tasuffeɣt", "status.delete": "Kkes", "status.direct": "Bder-d @{name} weḥd-s", @@ -616,6 +617,7 @@ "status.reblogs.empty": "Ula yiwen ur yebḍi tajewwiqt-agi ar tura. Ticki yebḍa-tt yiwen, ad d-iban da.", "status.redraft": "Kkes tɛiwdeḍ tira", "status.remove_bookmark": "Kkes tacreḍt", + "status.replied_in_thread": "Y·t·erra-d deg usentel", "status.replied_to": "Y·terra-yas i {name}", "status.reply": "Err", "status.replyAll": "Err i lxiḍ", diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index 8cd3387eaf..1dd5df32b8 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -502,6 +502,8 @@ "notification.reblog": "{name} fremhevet ditt innlegg", "notification.status": "{name} la nettopp ut", "notification.update": "{name} redigerte et innlegg", + "notification_requests.minimize_banner": "Minimer banneret for filtrerte varsler", + "notification_requests.view": "Vis varsler", "notifications.clear": "Fjern varsler", "notifications.clear_confirmation": "Er du sikker på at du vil fjerne alle dine varsler permanent?", "notifications.column_settings.admin.report": "Nye rapporter:", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 6feae5d137..2d9c7321d0 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -852,6 +852,11 @@ "upload_error.poll": "Anketlerde dosya yüklemesine izin verilmez.", "upload_form.audio_description": "İşitme kaybı olan kişiler için yazı ekleyiniz", "upload_form.description": "Görme engelliler için açıklama", + "upload_form.drag_and_drop.instructions": "Bir medya eklentisini taşımak için, boşluk veya enter tuşuna basın. Sürükleme sırasında medya eklentisini herhangi bir yöne hareket ettirmek için ok tuşlarını kullanın. Medya eklentisini yeni konumuna bırakmak için tekrar boşluk veya enter tuşuna basın veya işlemi iptal etmek için escape tuşuna basın.", + "upload_form.drag_and_drop.on_drag_cancel": "Sürükleme iptal edildi. Medya eklentisi {item} bırakıldı.", + "upload_form.drag_and_drop.on_drag_end": "Medya eklentisi {item} bırakıldı.", + "upload_form.drag_and_drop.on_drag_over": "Medya eklentisi {item} hareket ettirildi.", + "upload_form.drag_and_drop.on_drag_start": "Medya eklentisi {item} tutuldu.", "upload_form.edit": "Düzenle", "upload_form.thumbnail": "Küçük resmi değiştir", "upload_form.video_description": "İşitme kaybı veya görme engeli olan kişiler için açıklama ekleyiniz", diff --git a/config/locales/cy.yml b/config/locales/cy.yml index 1ae6aa08ff..a70d08ed8e 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -931,6 +931,9 @@ cy: message_html: Nid ydych wedi diffinio unrhyw reolau gweinydd. sidekiq_process_check: message_html: Does dim proses Sidekiq yn rhedeg ar gyfer y ciw(iau) %{value}. Adolygwch eich ffurfweddiad Sidekiq + software_version_check: + action: Gweld y diweddariadau sydd ar gael + message_html: Mae diweddariad Mastodon ar gael. software_version_critical_check: action: Gweld y diweddariadau sydd ar gael message_html: Mae diweddariad hanfodol Mastodon ar gael, diweddarwch cyn gynted â phosibl. @@ -1796,6 +1799,7 @@ cy: delete: Dileu cyfrif development: Datblygu edit_profile: Golygu proffil + export: Allforio featured_tags: Prif hashnodau import: Mewnforio import_and_export: Mewnforio ac allforio diff --git a/config/locales/doorkeeper.gl.yml b/config/locales/doorkeeper.gl.yml index adee6bd3d3..5d7148b84b 100644 --- a/config/locales/doorkeeper.gl.yml +++ b/config/locales/doorkeeper.gl.yml @@ -69,7 +69,7 @@ gl: buttons: revoke: Retirar autorización confirmations: - revoke: Estás segura? + revoke: Tes certeza? index: authorized_at: Autorizada o %{date} description_html: Estas aplicacións poden acceder á túa conta usando a API. Se ves aplicacións que non recoñeces, ou hai comportamentos non consentidos dalgunha delas, podes revogar o acceso. diff --git a/config/locales/he.yml b/config/locales/he.yml index c7af22660f..846b0d14af 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -903,6 +903,9 @@ he: message_html: לא הוגדרו שום כללי שרת. sidekiq_process_check: message_html: שום הליכי Sidekiq לא רצים עבור %{value} תור(ות). בחנו בבקשה את הגדרות Sidekiq + software_version_check: + action: ראו עדכונים זמינים + message_html: עדכון מסטודון זמין כעת. software_version_critical_check: action: ראו עדכונים זמינים message_html: יצא עדכון קריטי למסטודון, נא לעדכן את תוכנת מסטודון בהקדם האפשרי. @@ -1744,6 +1747,7 @@ he: delete: מחיקת חשבון development: פיתוח edit_profile: עריכת פרופיל + export: ייצוא featured_tags: תגיות נבחרות import: יבוא import_and_export: יבוא ויצוא diff --git a/config/locales/nn.yml b/config/locales/nn.yml index 8f6afc2426..ca5e34ee55 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -1,7 +1,7 @@ --- nn: about: - about_mastodon_html: 'Framtidas sosiale nettverk: Ingen annonsar, ingen verksemder som overvaker deg, etisk design og desentralisering! Eig idéane dine med Mastodon!' + about_mastodon_html: 'Framtidas sosiale nettverk: Ingen annonsar, ingen verksemder som overvaker deg, etisk design og desentralisering! Eig dataene dine med Mastodon!' contact_missing: Ikkje sett contact_unavailable: I/T hosted_on: "%{domain} er vert for Mastodon" @@ -39,7 +39,7 @@ nn: avatar: Bilete by_domain: Domene change_email: - changed_msg: Konto-e-posten er endra! + changed_msg: E-post for konto er endra! current_email: Noverande e-post label: Byt e-post new_email: Ny e-post @@ -62,7 +62,7 @@ nn: disable: Slå av disable_sign_in_token_auth: Slå av e-post-token-autentisering disable_two_factor_authentication: Slå av 2FA - disabled: Slege av + disabled: Inaktiv display_name: Synleg namn domain: Domene edit: Rediger From f0716368e642c4c3d21d2327009ddd59d27cec8b Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 2 Oct 2024 05:07:52 -0400 Subject: [PATCH 039/150] Update simplecov-html to version 0.13.1 (#32205) --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index c623f92e7d..3950a30d62 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -815,7 +815,7 @@ GEM docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) - simplecov-html (0.12.3) + simplecov-html (0.13.1) simplecov-lcov (0.8.0) simplecov_json_formatter (0.1.4) stackprof (0.2.26) From 33d3ca7cf19b5ae6e90163092d63d4a49fe45d4b Mon Sep 17 00:00:00 2001 From: Christian Schmidt Date: Wed, 2 Oct 2024 11:23:44 +0200 Subject: [PATCH 040/150] Support /.well-known/host-meta.json (#32206) --- .../well_known/host_meta_controller.rb | 18 ++++++++- config/routes.rb | 2 +- spec/requests/well_known/host_meta_spec.rb | 40 ++++++++++++++----- spec/routing/well_known_routes_spec.rb | 9 ++++- 4 files changed, 55 insertions(+), 14 deletions(-) diff --git a/app/controllers/well_known/host_meta_controller.rb b/app/controllers/well_known/host_meta_controller.rb index 201da9fbc3..6dee587baf 100644 --- a/app/controllers/well_known/host_meta_controller.rb +++ b/app/controllers/well_known/host_meta_controller.rb @@ -7,7 +7,23 @@ module WellKnown def show @webfinger_template = "#{webfinger_url}?resource={uri}" expires_in 3.days, public: true - render content_type: 'application/xrd+xml', formats: [:xml] + + respond_to do |format| + format.any do + render content_type: 'application/xrd+xml', formats: [:xml] + end + + format.json do + render json: { + links: [ + { + rel: 'lrdd', + template: @webfinger_template, + }, + ], + } + end + end end end end diff --git a/config/routes.rb b/config/routes.rb index 890102955c..83170fba0f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -67,7 +67,7 @@ Rails.application.routes.draw do scope path: '.well-known' do scope module: :well_known do get 'oauth-authorization-server', to: 'oauth_metadata#show', as: :oauth_metadata, defaults: { format: 'json' } - get 'host-meta', to: 'host_meta#show', as: :host_meta, defaults: { format: 'xml' } + get 'host-meta', to: 'host_meta#show', as: :host_meta get 'nodeinfo', to: 'node_info#index', as: :nodeinfo, defaults: { format: 'json' } get 'webfinger', to: 'webfinger#show', as: :webfinger end diff --git a/spec/requests/well_known/host_meta_spec.rb b/spec/requests/well_known/host_meta_spec.rb index 09f17baa89..726911dda1 100644 --- a/spec/requests/well_known/host_meta_spec.rb +++ b/spec/requests/well_known/host_meta_spec.rb @@ -9,19 +9,39 @@ RSpec.describe 'The /.well-known/host-meta request' do expect(response) .to have_http_status(200) .and have_attributes( - media_type: 'application/xrd+xml', - body: host_meta_xml_template + media_type: 'application/xrd+xml' + ) + + doc = Nokogiri::XML(response.parsed_body) + expect(doc.at_xpath('/xrd:XRD/xrd:Link[@rel="lrdd"]/@template', 'xrd' => 'http://docs.oasis-open.org/ns/xri/xrd-1.0').value) + .to eq 'https://cb6e6126.ngrok.io/.well-known/webfinger?resource={uri}' + end + + it 'returns http success with valid JSON response with .json extension' do + get '/.well-known/host-meta.json' + + expect(response) + .to have_http_status(200) + .and have_attributes( + media_type: 'application/json' + ) + + expect(response.parsed_body) + .to include( + links: [ + 'rel' => 'lrdd', + 'template' => 'https://cb6e6126.ngrok.io/.well-known/webfinger?resource={uri}', + ] ) end - private + it 'returns http success with valid JSON response with Accept header' do + get '/.well-known/host-meta', headers: { 'Accept' => 'application/json' } - def host_meta_xml_template - <<~XML - - - - - XML + expect(response) + .to have_http_status(200) + .and have_attributes( + media_type: 'application/json' + ) end end diff --git a/spec/routing/well_known_routes_spec.rb b/spec/routing/well_known_routes_spec.rb index 6578e939ae..84081059bb 100644 --- a/spec/routing/well_known_routes_spec.rb +++ b/spec/routing/well_known_routes_spec.rb @@ -4,9 +4,14 @@ require 'rails_helper' RSpec.describe 'Well Known routes' do describe 'the host-meta route' do - it 'routes to correct place with xml format' do + it 'routes to correct place' do expect(get('/.well-known/host-meta')) - .to route_to('well_known/host_meta#show', format: 'xml') + .to route_to('well_known/host_meta#show') + end + + it 'routes to correct place with json format' do + expect(get('/.well-known/host-meta.json')) + .to route_to('well_known/host_meta#show', format: 'json') end end From ebab3b80c7e8abb7e29d1ab912427e52d89faa1c Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 2 Oct 2024 05:43:04 -0400 Subject: [PATCH 041/150] Expand coverage for `Export` utility class (#32212) --- .../account_domain_block_fabricator.rb | 2 +- spec/models/export_spec.rb | 177 ++++++++++++++---- 2 files changed, 144 insertions(+), 35 deletions(-) diff --git a/spec/fabricators/account_domain_block_fabricator.rb b/spec/fabricators/account_domain_block_fabricator.rb index 83df509da2..a211b7c666 100644 --- a/spec/fabricators/account_domain_block_fabricator.rb +++ b/spec/fabricators/account_domain_block_fabricator.rb @@ -2,5 +2,5 @@ Fabricator(:account_domain_block) do account { Fabricate.build(:account) } - domain 'example.com' + domain { sequence { |n| "host-#{n}.example" } } end diff --git a/spec/models/export_spec.rb b/spec/models/export_spec.rb index 06bf07ed78..48e78830dd 100644 --- a/spec/models/export_spec.rb +++ b/spec/models/export_spec.rb @@ -3,66 +3,175 @@ require 'rails_helper' RSpec.describe Export do + subject { described_class.new(account) } + let(:account) { Fabricate(:account) } let(:target_accounts) do - [{}, { username: 'one', domain: 'local.host' }].map(&method(:Fabricate).curry(2).call(:account)) + [ + Fabricate(:account), + Fabricate(:account, username: 'one', domain: 'local.host'), + ] end - describe 'to_csv' do - it 'returns a csv of the blocked accounts' do - target_accounts.each { |target_account| account.block!(target_account) } + describe '#to_bookmarks_csv' do + before { Fabricate.times(2, :bookmark, account: account) } - export = described_class.new(account).to_blocked_accounts_csv - results = export.strip.split + let(:export) { CSV.parse(subject.to_bookmarks_csv) } - expect(results.size).to eq 2 - expect(results.first).to eq 'one@local.host' + it 'returns a csv of bookmarks' do + expect(export) + .to contain_exactly( + include(/statuses/), + include(/statuses/) + ) end + end + + describe '#to_blocked_accounts_csv' do + before { target_accounts.each { |target_account| account.block!(target_account) } } + + let(:export) { CSV.parse(subject.to_blocked_accounts_csv) } + + it 'returns a csv of the blocked accounts' do + expect(export) + .to contain_exactly( + include('one@local.host'), + include(be_present) + ) + end + end + + describe '#to_muted_accounts_csv' do + before { target_accounts.each { |target_account| account.mute!(target_account) } } + + let(:export) { CSV.parse(subject.to_muted_accounts_csv) } it 'returns a csv of the muted accounts' do - target_accounts.each { |target_account| account.mute!(target_account) } - - export = described_class.new(account).to_muted_accounts_csv - results = export.strip.split("\n") - - expect(results.size).to eq 3 - expect(results.first).to eq 'Account address,Hide notifications' - expect(results.second).to eq 'one@local.host,true' + expect(export) + .to contain_exactly( + contain_exactly('Account address', 'Hide notifications'), + include('one@local.host', 'true'), + include(be_present) + ) end + end + + describe '#to_following_accounts_csv' do + before { target_accounts.each { |target_account| account.follow!(target_account) } } + + let(:export) { CSV.parse(subject.to_following_accounts_csv) } it 'returns a csv of the following accounts' do - target_accounts.each { |target_account| account.follow!(target_account) } - - export = described_class.new(account).to_following_accounts_csv - results = export.strip.split("\n") - - expect(results.size).to eq 3 - expect(results.first).to eq 'Account address,Show boosts,Notify on new posts,Languages' - expect(results.second).to eq 'one@local.host,true,false,' + expect(export) + .to contain_exactly( + contain_exactly('Account address', 'Show boosts', 'Notify on new posts', 'Languages'), + include('one@local.host', 'true', 'false', be_blank), + include(be_present) + ) end end - describe 'total_storage' do + describe '#to_lists_csv' do + before do + target_accounts.each do |target_account| + account.follow!(target_account) + Fabricate(:list, account: account).accounts << target_account + end + end + + let(:export) { CSV.parse(subject.to_lists_csv) } + + it 'returns a csv of the lists' do + expect(export) + .to contain_exactly( + include('one@local.host'), + include(be_present) + ) + end + end + + describe '#to_blocked_domains_csv' do + before { Fabricate.times(2, :account_domain_block, account: account) } + + let(:export) { CSV.parse(subject.to_blocked_domains_csv) } + + it 'returns a csv of the blocked domains' do + expect(export) + .to contain_exactly( + include(/example/), + include(/example/) + ) + end + end + + describe '#total_storage' do it 'returns the total size of the media attachments' do media_attachment = Fabricate(:media_attachment, account: account) - expect(described_class.new(account).total_storage).to eq media_attachment.file_file_size || 0 + expect(subject.total_storage).to eq media_attachment.file_file_size || 0 end end - describe 'total_follows' do - it 'returns the total number of the followed accounts' do - target_accounts.each { |target_account| account.follow!(target_account) } - expect(described_class.new(account.reload).total_follows).to eq 2 + describe '#total_statuses' do + before { Fabricate.times(2, :status, account: account) } + + it 'returns the total number of statuses' do + expect(subject.total_statuses).to eq(2) end + end + + describe '#total_bookmarks' do + before { Fabricate.times(2, :bookmark, account: account) } + + it 'returns the total number of bookmarks' do + expect(subject.total_bookmarks).to eq(2) + end + end + + describe '#total_follows' do + before { target_accounts.each { |target_account| account.follow!(target_account) } } + + it 'returns the total number of the followed accounts' do + expect(subject.total_follows).to eq(2) + end + end + + describe '#total_lists' do + before { Fabricate.times(2, :list, account: account) } + + it 'returns the total number of lists' do + expect(subject.total_lists).to eq(2) + end + end + + describe '#total_followers' do + before { target_accounts.each { |target_account| target_account.follow!(account) } } + + it 'returns the total number of the follower accounts' do + expect(subject.total_followers).to eq(2) + end + end + + describe '#total_blocks' do + before { target_accounts.each { |target_account| account.block!(target_account) } } it 'returns the total number of the blocked accounts' do - target_accounts.each { |target_account| account.block!(target_account) } - expect(described_class.new(account.reload).total_blocks).to eq 2 + expect(subject.total_blocks).to eq(2) end + end + + describe '#total_mutes' do + before { target_accounts.each { |target_account| account.mute!(target_account) } } it 'returns the total number of the muted accounts' do - target_accounts.each { |target_account| account.mute!(target_account) } - expect(described_class.new(account.reload).total_mutes).to eq 2 + expect(subject.total_mutes).to eq(2) + end + end + + describe '#total_domain_blocks' do + before { Fabricate.times(2, :account_domain_block, account: account) } + + it 'returns the total number of account domain blocks' do + expect(subject.total_domain_blocks).to eq(2) end end end From 4a737a948a6aa8803ba366374569a93970437ec7 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 2 Oct 2024 12:03:04 +0200 Subject: [PATCH 042/150] Fix incorrect `'navigator'` check (#32219) --- app/javascript/mastodon/actions/markers.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/javascript/mastodon/actions/markers.ts b/app/javascript/mastodon/actions/markers.ts index 0b3280c212..251546cb9a 100644 --- a/app/javascript/mastodon/actions/markers.ts +++ b/app/javascript/mastodon/actions/markers.ts @@ -37,8 +37,7 @@ export const synchronouslySubmitMarkers = createAppAsyncThunk( }); return; - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - } else if ('navigator' && 'sendBeacon' in navigator) { + } else if ('sendBeacon' in navigator) { // Failing that, we can use sendBeacon, but we have to encode the data as // FormData for DoorKeeper to recognize the token. const formData = new FormData(); From 4aa26eba53a0c6c5e305f0de9367ea54c83f86db Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 2 Oct 2024 07:11:52 -0400 Subject: [PATCH 043/150] Extract `WebPushRequest` from push notification worker and subscription (#32208) --- app/lib/web_push_request.rb | 72 +++++++++++++++++++ app/models/web/push_subscription.rb | 28 -------- app/workers/web/push_notification_worker.rb | 40 +++++++---- .../web/push_notification_worker_spec.rb | 47 ++++++++---- 4 files changed, 131 insertions(+), 56 deletions(-) create mode 100644 app/lib/web_push_request.rb diff --git a/app/lib/web_push_request.rb b/app/lib/web_push_request.rb new file mode 100644 index 0000000000..a43e22480e --- /dev/null +++ b/app/lib/web_push_request.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +class WebPushRequest + SIGNATURE_ALGORITHM = 'p256ecdsa' + AUTH_HEADER = 'WebPush' + PAYLOAD_EXPIRATION = 24.hours + JWT_ALGORITHM = 'ES256' + JWT_TYPE = 'JWT' + + attr_reader :web_push_subscription + + delegate( + :endpoint, + :key_auth, + :key_p256dh, + to: :web_push_subscription + ) + + def initialize(web_push_subscription) + @web_push_subscription = web_push_subscription + end + + def audience + @audience ||= Addressable::URI.parse(endpoint).normalized_site + end + + def authorization_header + [AUTH_HEADER, encoded_json_web_token].join(' ') + end + + def crypto_key_header + [SIGNATURE_ALGORITHM, vapid_key.public_key_for_push_header].join('=') + end + + def encrypt(payload) + Webpush::Encryption.encrypt(payload, key_p256dh, key_auth) + end + + private + + def encoded_json_web_token + JWT.encode( + web_token_payload, + vapid_key.curve, + JWT_ALGORITHM, + typ: JWT_TYPE + ) + end + + def web_token_payload + { + aud: audience, + exp: PAYLOAD_EXPIRATION.from_now.to_i, + sub: payload_subject, + } + end + + def payload_subject + [:mailto, contact_email].join(':') + end + + def vapid_key + @vapid_key ||= Webpush::VapidKey.from_keys( + Rails.configuration.x.vapid_public_key, + Rails.configuration.x.vapid_private_key + ) + end + + def contact_email + @contact_email ||= ::Setting.site_contact_email + end +end diff --git a/app/models/web/push_subscription.rb b/app/models/web/push_subscription.rb index ddfd08146e..9d30881bf3 100644 --- a/app/models/web/push_subscription.rb +++ b/app/models/web/push_subscription.rb @@ -29,26 +29,6 @@ class Web::PushSubscription < ApplicationRecord delegate :locale, to: :associated_user - def encrypt(payload) - Webpush::Encryption.encrypt(payload, key_p256dh, key_auth) - end - - def audience - @audience ||= Addressable::URI.parse(endpoint).normalized_site - end - - def crypto_key_header - p256ecdsa = vapid_key.public_key_for_push_header - - "p256ecdsa=#{p256ecdsa}" - end - - def authorization_header - jwt = JWT.encode({ aud: audience, exp: 24.hours.from_now.to_i, sub: "mailto:#{contact_email}" }, vapid_key.curve, 'ES256', typ: 'JWT') - - "WebPush #{jwt}" - end - def pushable?(notification) policy_allows_notification?(notification) && alert_enabled_for_notification_type?(notification) end @@ -92,14 +72,6 @@ class Web::PushSubscription < ApplicationRecord ) end - def vapid_key - @vapid_key ||= Webpush::VapidKey.from_keys(Rails.configuration.x.vapid_public_key, Rails.configuration.x.vapid_private_key) - end - - def contact_email - @contact_email ||= ::Setting.site_contact_email - end - def alert_enabled_for_notification_type?(notification) truthy?(data&.dig('alerts', notification.type.to_s)) end diff --git a/app/workers/web/push_notification_worker.rb b/app/workers/web/push_notification_worker.rb index 7e9691aaba..104503f130 100644 --- a/app/workers/web/push_notification_worker.rb +++ b/app/workers/web/push_notification_worker.rb @@ -16,10 +16,10 @@ class Web::PushNotificationWorker # in the meantime, so we have to double-check before proceeding return unless @notification.activity.present? && @subscription.pushable?(@notification) - payload = @subscription.encrypt(push_notification_json) + payload = web_push_request.encrypt(push_notification_json) - request_pool.with(@subscription.audience) do |http_client| - request = Request.new(:post, @subscription.endpoint, body: payload.fetch(:ciphertext), http_client: http_client) + request_pool.with(web_push_request.audience) do |http_client| + request = Request.new(:post, web_push_request.endpoint, body: payload.fetch(:ciphertext), http_client: http_client) request.add_headers( 'Content-Type' => 'application/octet-stream', @@ -27,8 +27,8 @@ class Web::PushNotificationWorker 'Urgency' => URGENCY, 'Content-Encoding' => 'aesgcm', 'Encryption' => "salt=#{Webpush.encode64(payload.fetch(:salt)).delete('=')}", - 'Crypto-Key' => "dh=#{Webpush.encode64(payload.fetch(:server_public_key)).delete('=')};#{@subscription.crypto_key_header}", - 'Authorization' => @subscription.authorization_header + 'Crypto-Key' => "dh=#{Webpush.encode64(payload.fetch(:server_public_key)).delete('=')};#{web_push_request.crypto_key_header}", + 'Authorization' => web_push_request.authorization_header ) request.perform do |response| @@ -50,17 +50,27 @@ class Web::PushNotificationWorker private - def push_notification_json - json = I18n.with_locale(@subscription.locale.presence || I18n.default_locale) do - ActiveModelSerializers::SerializableResource.new( - @notification, - serializer: Web::NotificationSerializer, - scope: @subscription, - scope_name: :current_push_subscription - ).as_json - end + def web_push_request + @web_push_request || WebPushRequest.new(@subscription) + end - Oj.dump(json) + def push_notification_json + Oj.dump(serialized_notification_in_subscription_locale.as_json) + end + + def serialized_notification_in_subscription_locale + I18n.with_locale(@subscription.locale.presence || I18n.default_locale) do + serialized_notification + end + end + + def serialized_notification + ActiveModelSerializers::SerializableResource.new( + @notification, + serializer: Web::NotificationSerializer, + scope: @subscription, + scope_name: :current_push_subscription + ) end def request_pool diff --git a/spec/workers/web/push_notification_worker_spec.rb b/spec/workers/web/push_notification_worker_spec.rb index ced21d5bf7..7f836d99e4 100644 --- a/spec/workers/web/push_notification_worker_spec.rb +++ b/spec/workers/web/push_notification_worker_spec.rb @@ -22,27 +22,48 @@ RSpec.describe Web::PushNotificationWorker do let(:payload) { { ciphertext: ciphertext, salt: salt, server_public_key: server_public_key, shared_secret: shared_secret } } describe 'perform' do + around do |example| + original_private = Rails.configuration.x.vapid_private_key + original_public = Rails.configuration.x.vapid_public_key + Rails.configuration.x.vapid_private_key = vapid_private_key + Rails.configuration.x.vapid_public_key = vapid_public_key + example.run + Rails.configuration.x.vapid_private_key = original_private + Rails.configuration.x.vapid_public_key = original_public + end + before do - allow(subscription).to receive_messages(contact_email: contact_email, vapid_key: vapid_key) - allow(Web::PushSubscription).to receive(:find).with(subscription.id).and_return(subscription) + Setting.site_contact_email = contact_email + allow(Webpush::Encryption).to receive(:encrypt).and_return(payload) allow(JWT).to receive(:encode).and_return('jwt.encoded.payload') stub_request(:post, endpoint).to_return(status: 201, body: '') - - subject.perform(subscription.id, notification.id) end it 'calls the relevant service with the correct headers' do - expect(a_request(:post, endpoint).with(headers: { - 'Content-Encoding' => 'aesgcm', - 'Content-Type' => 'application/octet-stream', - 'Crypto-Key' => "dh=BAgtUks5d90kFmxGevk9tH7GEmvz9DB0qcEMUsOBgKwMf-TMjsKIIG6LQvGcFAf6jcmAod15VVwmYwGIIxE4VWE;p256ecdsa=#{vapid_public_key.delete('=')}", - 'Encryption' => 'salt=WJeVM-RY-F9351SVxTFx_g', - 'Ttl' => '172800', - 'Urgency' => 'normal', - 'Authorization' => 'WebPush jwt.encoded.payload', - }, body: "+\xB8\xDBT}\u0013\xB6\xDD.\xF9\xB0\xA7\xC8Ҁ\xFD\x99#\xF7\xAC\x83\xA4\xDB,\u001F\xB5\xB9w\x85>\xF7\xADr")).to have_been_made + subject.perform(subscription.id, notification.id) + + expect(web_push_endpoint_request) + .to have_been_made + end + + def web_push_endpoint_request + a_request( + :post, + endpoint + ).with( + headers: { + 'Content-Encoding' => 'aesgcm', + 'Content-Type' => 'application/octet-stream', + 'Crypto-Key' => "dh=BAgtUks5d90kFmxGevk9tH7GEmvz9DB0qcEMUsOBgKwMf-TMjsKIIG6LQvGcFAf6jcmAod15VVwmYwGIIxE4VWE;p256ecdsa=#{vapid_public_key.delete('=')}", + 'Encryption' => 'salt=WJeVM-RY-F9351SVxTFx_g', + 'Ttl' => '172800', + 'Urgency' => 'normal', + 'Authorization' => 'WebPush jwt.encoded.payload', + }, + body: "+\xB8\xDBT}\u0013\xB6\xDD.\xF9\xB0\xA7\xC8Ҁ\xFD\x99#\xF7\xAC\x83\xA4\xDB,\u001F\xB5\xB9w\x85>\xF7\xADr" + ) end end end From 1f65a95421a4dcbe44e25bd9e36329830a396eef Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 2 Oct 2024 08:26:16 -0400 Subject: [PATCH 044/150] Remove unneeded `reorder(nil)` conditions (#32200) --- app/lib/vacuum/imports_vacuum.rb | 4 ++-- app/models/account_filter.rb | 2 +- app/models/admin/tag_filter.rb | 2 +- app/services/purge_domain_service.rb | 4 ++-- app/workers/filtered_notification_cleanup_worker.rb | 2 +- app/workers/scheduler/user_cleanup_scheduler.rb | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/lib/vacuum/imports_vacuum.rb b/app/lib/vacuum/imports_vacuum.rb index 700bd81847..b67865194f 100644 --- a/app/lib/vacuum/imports_vacuum.rb +++ b/app/lib/vacuum/imports_vacuum.rb @@ -9,10 +9,10 @@ class Vacuum::ImportsVacuum private def clean_unconfirmed_imports! - BulkImport.state_unconfirmed.where(created_at: ..10.minutes.ago).reorder(nil).in_batches.delete_all + BulkImport.state_unconfirmed.where(created_at: ..10.minutes.ago).in_batches.delete_all end def clean_old_imports! - BulkImport.where(created_at: ..1.week.ago).reorder(nil).in_batches.delete_all + BulkImport.where(created_at: ..1.week.ago).in_batches.delete_all end end diff --git a/app/models/account_filter.rb b/app/models/account_filter.rb index 42b1c49538..e2f359a8c3 100644 --- a/app/models/account_filter.rb +++ b/app/models/account_filter.rb @@ -21,7 +21,7 @@ class AccountFilter end def results - scope = Account.includes(:account_stat, user: [:ips, :invite_request]).without_instance_actor.reorder(nil) + scope = Account.includes(:account_stat, user: [:ips, :invite_request]).without_instance_actor relevant_params.each do |key, value| next if key.to_s == 'page' diff --git a/app/models/admin/tag_filter.rb b/app/models/admin/tag_filter.rb index 6149c52175..5e75757b23 100644 --- a/app/models/admin/tag_filter.rb +++ b/app/models/admin/tag_filter.rb @@ -14,7 +14,7 @@ class Admin::TagFilter end def results - scope = Tag.reorder(nil) + scope = Tag.all params.each do |key, value| next if key == :page diff --git a/app/services/purge_domain_service.rb b/app/services/purge_domain_service.rb index ca0f0d441f..feab8aa1dd 100644 --- a/app/services/purge_domain_service.rb +++ b/app/services/purge_domain_service.rb @@ -16,12 +16,12 @@ class PurgeDomainService < BaseService end def purge_accounts! - Account.remote.where(domain: @domain).reorder(nil).find_each do |account| + Account.remote.where(domain: @domain).find_each do |account| DeleteAccountService.new.call(account, reserve_username: false, skip_side_effects: true) end end def purge_emojis! - CustomEmoji.remote.where(domain: @domain).reorder(nil).find_each(&:destroy) + CustomEmoji.remote.where(domain: @domain).find_each(&:destroy) end end diff --git a/app/workers/filtered_notification_cleanup_worker.rb b/app/workers/filtered_notification_cleanup_worker.rb index 2b955da3c0..87ff6a9eb5 100644 --- a/app/workers/filtered_notification_cleanup_worker.rb +++ b/app/workers/filtered_notification_cleanup_worker.rb @@ -4,6 +4,6 @@ class FilteredNotificationCleanupWorker include Sidekiq::Worker def perform(account_id, from_account_id) - Notification.where(account_id: account_id, from_account_id: from_account_id, filtered: true).reorder(nil).in_batches(order: :desc).delete_all + Notification.where(account_id: account_id, from_account_id: from_account_id, filtered: true).in_batches(order: :desc).delete_all end end diff --git a/app/workers/scheduler/user_cleanup_scheduler.rb b/app/workers/scheduler/user_cleanup_scheduler.rb index 9f58d9225b..f755128332 100644 --- a/app/workers/scheduler/user_cleanup_scheduler.rb +++ b/app/workers/scheduler/user_cleanup_scheduler.rb @@ -16,7 +16,7 @@ class Scheduler::UserCleanupScheduler private def clean_unconfirmed_accounts! - User.unconfirmed.where(confirmation_sent_at: ..UNCONFIRMED_ACCOUNTS_MAX_AGE_DAYS.days.ago).reorder(nil).find_in_batches do |batch| + User.unconfirmed.where(confirmation_sent_at: ..UNCONFIRMED_ACCOUNTS_MAX_AGE_DAYS.days.ago).find_in_batches do |batch| # We have to do it separately because of missing database constraints AccountModerationNote.where(target_account_id: batch.map(&:account_id)).delete_all Account.where(id: batch.map(&:account_id)).delete_all From cf859d151b494a0786c07167f26dc52d0cfd407f Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 2 Oct 2024 09:08:40 -0400 Subject: [PATCH 045/150] More link/button conversion across views (#32199) --- app/views/admin/accounts/show.html.haml | 2 +- app/views/admin/instances/show.html.haml | 12 ++++++------ app/views/admin/invites/index.html.haml | 2 +- app/views/admin/reports/_actions.html.haml | 2 +- app/views/admin/reports/show.html.haml | 4 ++-- app/views/disputes/strikes/show.html.haml | 4 ++-- app/views/settings/exports/show.html.haml | 2 +- .../otp_authentication/show.html.haml | 2 +- .../index.html.haml | 4 ++-- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index f148b9a082..2d9e30e368 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -30,7 +30,7 @@ = render 'admin/accounts/counters', account: @account - if @account.local? && @account.user.nil? - = link_to t('admin.accounts.unblock_email'), unblock_email_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unblock_email, @account) && CanonicalEmailBlock.exists?(reference_account_id: @account.id) + = button_to t('admin.accounts.unblock_email'), unblock_email_admin_account_path(@account.id), class: :button if can?(:unblock_email, @account) && CanonicalEmailBlock.exists?(reference_account_id: @account.id) - else .table-wrapper %table.table.inline-table diff --git a/app/views/admin/instances/show.html.haml b/app/views/admin/instances/show.html.haml index 812a9c8870..dd4c50549c 100644 --- a/app/views/admin/instances/show.html.haml +++ b/app/views/admin/instances/show.html.haml @@ -21,7 +21,7 @@ - if @instance.domain_allow = link_to t('admin.domain_allows.undo'), admin_domain_allow_path(@instance.domain_allow), class: 'button button--destructive', data: { confirm: t('admin.accounts.are_you_sure'), method: :delete } - else - = link_to t('admin.domain_allows.add_new'), admin_domain_allows_path(domain_allow: { domain: @instance.domain }), class: 'button', method: :post + = button_to t('admin.domain_allows.add_new'), admin_domain_allows_path(domain_allow: { domain: @instance.domain }), class: :button - else %p= t('admin.instances.content_policies.description_html') @@ -40,7 +40,7 @@ %td= @instance.domain_block.policies.map { |policy| t(policy, scope: 'admin.instances.content_policies.policies') }.join(' · ') = link_to t('admin.domain_blocks.edit'), edit_admin_domain_block_path(@instance.domain_block), class: 'button' - = link_to t('admin.domain_blocks.undo'), admin_domain_block_path(@instance.domain_block), class: 'button', data: { confirm: t('admin.accounts.are_you_sure'), method: :delete } + = button_to t('admin.domain_blocks.undo'), admin_domain_block_path(@instance.domain_block), class: :button, data: { confirm: t('admin.accounts.are_you_sure'), method: :delete } - else = link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: @instance.domain), class: 'button' @@ -70,16 +70,16 @@ - if @instance.unavailable? %span.negative-hint = t('admin.instances.availability.failure_threshold_reached', date: l(@instance.unavailable_domain.created_at.to_date)) - = link_to t('admin.instances.delivery.restart'), restart_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post } + = button_to t('admin.instances.delivery.restart'), restart_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure') } - elsif @instance.exhausted_deliveries_days.empty? %span.positive-hint = t('admin.instances.availability.no_failures_recorded') - = link_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post } + = button_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure') } - else %span.negative-hint = t('admin.instances.availability.failures_recorded', count: @instance.delivery_failure_tracker.days) - %span= link_to t('admin.instances.delivery.clear'), clear_delivery_errors_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post } unless @instance.exhausted_deliveries_days.empty? - %span= link_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post } + %span= button_to t('admin.instances.delivery.clear'), clear_delivery_errors_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure') } unless @instance.exhausted_deliveries_days.empty? + %span= button_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure') } - if @instance.purgeable? %p= t('admin.instances.purge_description_html') diff --git a/app/views/admin/invites/index.html.haml b/app/views/admin/invites/index.html.haml index 964deaba8f..bbccca3147 100644 --- a/app/views/admin/invites/index.html.haml +++ b/app/views/admin/invites/index.html.haml @@ -34,4 +34,4 @@ = paginate @invites - if policy(:invite).deactivate_all? - = link_to t('admin.invites.deactivate_all'), deactivate_all_admin_invites_path, method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' + = button_to t('admin.invites.deactivate_all'), deactivate_all_admin_invites_path, data: { confirm: t('admin.accounts.are_you_sure') }, class: :button diff --git a/app/views/admin/reports/_actions.html.haml b/app/views/admin/reports/_actions.html.haml index ef016e949b..c25f45e169 100644 --- a/app/views/admin/reports/_actions.html.haml +++ b/app/views/admin/reports/_actions.html.haml @@ -2,7 +2,7 @@ .report-actions .report-actions__item .report-actions__item__button - = link_to t('admin.reports.mark_as_resolved'), resolve_admin_report_path(report), method: :post, class: 'button' + = button_to t('admin.reports.mark_as_resolved'), resolve_admin_report_path(report), class: :button .report-actions__item__description = t('admin.reports.actions.resolve_description_html') - if statuses.any? { |status| (status.with_media? || status.with_preview_card?) && !status.discarded? } diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml index 69e9c02921..32b6b3be8d 100644 --- a/app/views/admin/reports/show.html.haml +++ b/app/views/admin/reports/show.html.haml @@ -3,9 +3,9 @@ - content_for :heading_actions do - if @report.unresolved? - = link_to t('admin.reports.mark_as_resolved'), resolve_admin_report_path(@report), method: :post, class: 'button' + = button_to t('admin.reports.mark_as_resolved'), resolve_admin_report_path(@report), class: :button - else - = link_to t('admin.reports.mark_as_unresolved'), reopen_admin_report_path(@report), method: :post, class: 'button' + = button_to t('admin.reports.mark_as_unresolved'), reopen_admin_report_path(@report), class: :button - unless @report.account.local? || @report.target_account.local? .flash-message= t('admin.reports.forwarded_replies_explanation') diff --git a/app/views/disputes/strikes/show.html.haml b/app/views/disputes/strikes/show.html.haml index 150dc06759..1d71e0ddd1 100644 --- a/app/views/disputes/strikes/show.html.haml +++ b/app/views/disputes/strikes/show.html.haml @@ -3,8 +3,8 @@ - content_for :heading_actions do - if @appeal.persisted? - = link_to t('disputes.strikes.approve_appeal'), approve_admin_disputes_appeal_path(@appeal), method: :post, class: 'button' if can?(:approve, @appeal) - = link_to t('disputes.strikes.reject_appeal'), reject_admin_disputes_appeal_path(@appeal), method: :post, class: 'button button--destructive' if can?(:reject, @appeal) + = button_to t('disputes.strikes.approve_appeal'), approve_admin_disputes_appeal_path(@appeal), class: :button if can?(:approve, @appeal) + = button_to t('disputes.strikes.reject_appeal'), reject_admin_disputes_appeal_path(@appeal), class: 'button button--destructive' if can?(:reject, @appeal) - if @strike.overruled? %p.hint diff --git a/app/views/settings/exports/show.html.haml b/app/views/settings/exports/show.html.haml index 273c5a4ba6..61d55350c2 100644 --- a/app/views/settings/exports/show.html.haml +++ b/app/views/settings/exports/show.html.haml @@ -46,7 +46,7 @@ %p.muted-hint= t('exports.archive_takeout.hint_html') - if policy(:backup).create? - %p= link_to t('exports.archive_takeout.request'), settings_export_path, class: 'button', method: :post + %p= button_to t('exports.archive_takeout.request'), settings_export_path, class: :button - unless @backups.empty? %hr.spacer/ diff --git a/app/views/settings/two_factor_authentication/otp_authentication/show.html.haml b/app/views/settings/two_factor_authentication/otp_authentication/show.html.haml index d069ba12a9..01f385dbea 100644 --- a/app/views/settings/two_factor_authentication/otp_authentication/show.html.haml +++ b/app/views/settings/two_factor_authentication/otp_authentication/show.html.haml @@ -6,4 +6,4 @@ %hr.spacer/ - = link_to t('otp_authentication.setup'), settings_otp_authentication_path, data: { method: :post }, class: 'block-button' + = button_to t('otp_authentication.setup'), settings_otp_authentication_path, class: 'block-button' diff --git a/app/views/settings/two_factor_authentication_methods/index.html.haml b/app/views/settings/two_factor_authentication_methods/index.html.haml index 8b670283b9..e3a211a3d7 100644 --- a/app/views/settings/two_factor_authentication_methods/index.html.haml +++ b/app/views/settings/two_factor_authentication_methods/index.html.haml @@ -2,7 +2,7 @@ = t('settings.two_factor_authentication') - content_for :heading_actions do - = link_to t('two_factor_authentication.disable'), disable_settings_two_factor_authentication_methods_path, class: 'button button--destructive', method: :post + = button_to t('two_factor_authentication.disable'), disable_settings_two_factor_authentication_methods_path, class: 'button button--destructive' %p.hint %span.positive-hint @@ -38,4 +38,4 @@ %hr.spacer/ .simple_form - = link_to t('two_factor_authentication.generate_recovery_codes'), settings_two_factor_authentication_recovery_codes_path, data: { method: :post }, class: 'block-button' + = button_to t('two_factor_authentication.generate_recovery_codes'), settings_two_factor_authentication_recovery_codes_path, class: 'block-button' From 2151dfb8d687f08438fc76d8fdf670a473d6a1e8 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 2 Oct 2024 09:24:40 -0400 Subject: [PATCH 046/150] Add `relevant_params` to ReportFilter (matches account filter) (#32136) --- app/models/report_filter.rb | 14 +++++++++++++- spec/models/report_filter_spec.rb | 13 +++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/app/models/report_filter.rb b/app/models/report_filter.rb index fd0e23cb81..9d2b0fb374 100644 --- a/app/models/report_filter.rb +++ b/app/models/report_filter.rb @@ -18,13 +18,25 @@ class ReportFilter def results scope = Report.unresolved - params.each do |key, value| + relevant_params.each do |key, value| scope = scope.merge scope_for(key, value) end scope end + private + + def relevant_params + params.tap do |args| + args.delete(:target_origin) if origin_is_remote_and_domain_present? + end + end + + def origin_is_remote_and_domain_present? + params[:target_origin] == 'remote' && params[:by_target_domain].present? + end + def scope_for(key, value) case key.to_sym when :by_target_domain diff --git a/spec/models/report_filter_spec.rb b/spec/models/report_filter_spec.rb index 8668eb3d10..51933e475a 100644 --- a/spec/models/report_filter_spec.rb +++ b/spec/models/report_filter_spec.rb @@ -30,4 +30,17 @@ RSpec.describe ReportFilter do expect(Report).to have_received(:resolved) end end + + context 'when given remote target_origin and also by_target_domain' do + let!(:matching_report) { Fabricate :report, target_account: Fabricate(:account, domain: 'match.example') } + let!(:non_matching_report) { Fabricate :report, target_account: Fabricate(:account, domain: 'other.example') } + + it 'preserves the domain value' do + filter = described_class.new(by_target_domain: 'match.example', target_origin: 'remote') + + expect(filter.results) + .to include(matching_report) + .and not_include(non_matching_report) + end + end end From d270d6dd4fce6dd15107ee1fe9b7877a5fca02d9 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 2 Oct 2024 09:26:46 -0400 Subject: [PATCH 047/150] Provide `use_path` to qr generator for svg data size reduction (#32127) --- .../two_factor_authentication/confirmations/new.html.haml | 2 +- .../two_factor_authentication/confirmations_controller_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/settings/two_factor_authentication/confirmations/new.html.haml b/app/views/settings/two_factor_authentication/confirmations/new.html.haml index 0b8278a104..a35479b84e 100644 --- a/app/views/settings/two_factor_authentication/confirmations/new.html.haml +++ b/app/views/settings/two_factor_authentication/confirmations/new.html.haml @@ -5,7 +5,7 @@ %p.hint= t('otp_authentication.instructions_html') .qr-wrapper - .qr-code!= @qrcode.as_svg(padding: 0, module_size: 4) + .qr-code!= @qrcode.as_svg(padding: 0, module_size: 4, use_path: true) .qr-alternative %p.hint= t('otp_authentication.manual_instructions') diff --git a/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb b/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb index 34eaacdf49..224310b7ef 100644 --- a/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb +++ b/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb @@ -18,7 +18,7 @@ RSpec.describe Settings::TwoFactorAuthentication::ConfirmationsController do def qr_code_markup RQRCode::QRCode.new( 'otpauth://totp/cb6e6126.ngrok.io:local-part%40domain?secret=thisisasecretforthespecofnewview&issuer=cb6e6126.ngrok.io' - ).as_svg(padding: 0, module_size: 4) + ).as_svg(padding: 0, module_size: 4, use_path: true) end end From b5006539c995cbefda04db25888ffe5bb5995d3f Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 2 Oct 2024 15:28:36 +0200 Subject: [PATCH 048/150] Fix media uploads in composer appearing over search results in advanced interface (#32217) --- app/javascript/styles/mastodon/components.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 14de6e6818..5f410ead93 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -3611,6 +3611,7 @@ $ui-header-logo-wordmark-width: 99px; overflow-y: auto; width: 100%; height: 100%; + z-index: 0; } .drawer__inner__mastodon { From f760899b04ef5647d8688e9f1f08094fb3cf5894 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 2 Oct 2024 15:29:23 +0200 Subject: [PATCH 049/150] Fix editing description of media uploads with custom thumbnails (#32221) --- app/javascript/mastodon/reducers/compose.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index e77f2ac6e6..ba975b75a8 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -402,7 +402,7 @@ export default function compose(state = initialState, action) { .set('isUploadingThumbnail', false) .update('media_attachments', list => list.map(item => { if (item.get('id') === action.media.id) { - return fromJS(action.media); + return fromJS(action.media).set('unattached', item.get('unattached')); } return item; From b7bb850efd485466d4424f4744c1795541ca592f Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 2 Oct 2024 09:56:26 -0400 Subject: [PATCH 050/150] Enable hostname config for all system specs (#32109) --- spec/rails_helper.rb | 5 +++++ spec/system/invites_spec.rb | 5 +---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index ee03b49bc6..84cee0974f 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -161,6 +161,11 @@ RSpec.configure do |config| host! Rails.configuration.x.local_domain end + config.before :each, type: :system do + # Align with capybara config so that rails helpers called from rspec use matching host + host! 'localhost:3000' + end + config.after do Rails.cache.clear redis.del(redis.keys) diff --git a/spec/system/invites_spec.rb b/spec/system/invites_spec.rb index c57de871cc..fc60ce5913 100644 --- a/spec/system/invites_spec.rb +++ b/spec/system/invites_spec.rb @@ -7,10 +7,7 @@ RSpec.describe 'Invites' do let(:user) { Fabricate :user } - before do - host! 'localhost:3000' # TODO: Move into before for all system specs? - sign_in user - end + before { sign_in user } describe 'Viewing invites' do it 'Lists existing user invites' do From 36f9c96812c313c5f782a702df221ad4b57da0f3 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 2 Oct 2024 10:45:12 -0400 Subject: [PATCH 051/150] Clean up labels on development application form (#32116) --- app/helpers/application_helper.rb | 13 +++++-------- app/models/session_activation.rb | 4 +++- app/views/settings/applications/_form.html.haml | 4 ++-- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index de00f76d36..a40580fbae 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,12 +1,6 @@ # frozen_string_literal: true module ApplicationHelper - DANGEROUS_SCOPES = %w( - read - write - follow - ).freeze - RTL_LOCALES = %i( ar ckb @@ -95,8 +89,11 @@ module ApplicationHelper Rails.env.production? ? site_title : "#{site_title} (Dev)" end - def class_for_scope(scope) - 'scope-danger' if DANGEROUS_SCOPES.include?(scope.to_s) + def label_for_scope(scope) + safe_join [ + tag.samp(scope, class: { 'scope-danger' => SessionActivation::DEFAULT_SCOPES.include?(scope.to_s) }), + tag.span(t("doorkeeper.scopes.#{scope}"), class: :hint), + ] end def can?(action, record) diff --git a/app/models/session_activation.rb b/app/models/session_activation.rb index d0a77daf0a..8b8e533d30 100644 --- a/app/models/session_activation.rb +++ b/app/models/session_activation.rb @@ -28,6 +28,8 @@ class SessionActivation < ApplicationRecord before_create :assign_access_token + DEFAULT_SCOPES = %w(read write follow).freeze + class << self def active?(id) id && exists?(session_id: id) @@ -64,7 +66,7 @@ class SessionActivation < ApplicationRecord { application_id: Doorkeeper::Application.find_by(superapp: true)&.id, resource_owner_id: user_id, - scopes: 'read write follow', + scopes: DEFAULT_SCOPES.join(' '), expires_in: Doorkeeper.configuration.access_token_expires_in, use_refresh_token: Doorkeeper.configuration.refresh_token_enabled?, } diff --git a/app/views/settings/applications/_form.html.haml b/app/views/settings/applications/_form.html.haml index 66ea8bc12b..85fdefa0fc 100644 --- a/app/views/settings/applications/_form.html.haml +++ b/app/views/settings/applications/_form.html.haml @@ -18,7 +18,7 @@ .field-group .input.with_block_label - %label= t('activerecord.attributes.doorkeeper/application.scopes') + = form.label t('activerecord.attributes.doorkeeper/application.scopes'), required: true %span.hint= t('simple_form.hints.defaults.scopes') - Doorkeeper.configuration.scopes.group_by { |s| s.split(':').first }.each_value do |value| @@ -29,7 +29,7 @@ hint: false, include_blank: false, item_wrapper_tag: 'li', - label_method: ->(scope) { safe_join([content_tag(:samp, scope, class: class_for_scope(scope)), content_tag(:span, t("doorkeeper.scopes.#{scope}"), class: 'hint')]) }, + label_method: ->(scope) { label_for_scope(scope) }, label: false, required: false, selected: form.object.scopes.all, From 7d6b9ccd34fd10cce33114ac13201905222a807e Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 2 Oct 2024 10:45:54 -0400 Subject: [PATCH 052/150] Add `copyable_input` helper method to wrap shared options (#32119) --- app/helpers/application_helper.rb | 4 ++++ app/views/admin/invites/_invite.html.haml | 2 +- app/views/invites/_invite.html.haml | 2 +- app/views/oauth/authorizations/show.html.haml | 2 +- app/views/settings/verifications/show.html.haml | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a40580fbae..8f9a433d82 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -240,6 +240,10 @@ module ApplicationHelper full_asset_url(instance_presenter.mascot&.file&.url || frontend_asset_path('images/elephant_ui_plane.svg')) end + def copyable_input(options = {}) + tag.input(type: :text, maxlength: 999, spellcheck: false, readonly: true, **options) + end + private def storage_host_var diff --git a/app/views/admin/invites/_invite.html.haml b/app/views/admin/invites/_invite.html.haml index 8bd5f10fee..53eac1d0cd 100644 --- a/app/views/admin/invites/_invite.html.haml +++ b/app/views/admin/invites/_invite.html.haml @@ -2,7 +2,7 @@ %td .input-copy .input-copy__wrapper - %input{ type: :text, maxlength: '999', spellcheck: 'false', readonly: 'true', value: public_invite_url(invite_code: invite.code) } + = copyable_input value: public_invite_url(invite_code: invite.code) %button{ type: :button }= t('generic.copy') %td diff --git a/app/views/invites/_invite.html.haml b/app/views/invites/_invite.html.haml index 892fdc5a0e..7c94062de4 100644 --- a/app/views/invites/_invite.html.haml +++ b/app/views/invites/_invite.html.haml @@ -2,7 +2,7 @@ %td .input-copy .input-copy__wrapper - %input{ type: :text, maxlength: '999', spellcheck: 'false', readonly: 'true', value: public_invite_url(invite_code: invite.code) } + = copyable_input value: public_invite_url(invite_code: invite.code) %button{ type: :button }= t('generic.copy') - if invite.valid_for_use? diff --git a/app/views/oauth/authorizations/show.html.haml b/app/views/oauth/authorizations/show.html.haml index a5122a87fc..bdff336368 100644 --- a/app/views/oauth/authorizations/show.html.haml +++ b/app/views/oauth/authorizations/show.html.haml @@ -3,5 +3,5 @@ %p= t('doorkeeper.authorizations.show.title') .input-copy .input-copy__wrapper - %input.oauth-code{ type: 'text', spellcheck: 'false', readonly: true, value: params[:code] } + = copyable_input value: params[:code], class: 'oauth-code' %button{ type: :button }= t('generic.copy') diff --git a/app/views/settings/verifications/show.html.haml b/app/views/settings/verifications/show.html.haml index 00491866c6..560807f27c 100644 --- a/app/views/settings/verifications/show.html.haml +++ b/app/views/settings/verifications/show.html.haml @@ -16,7 +16,7 @@ .input-copy.lead .input-copy__wrapper - %input{ type: :text, maxlength: '999', spellcheck: 'false', readonly: 'true', value: link_to('Mastodon', ActivityPub::TagManager.instance.url_for(@account), rel: 'me').to_str } + = copyable_input value: link_to('Mastodon', ActivityPub::TagManager.instance.url_for(@account), rel: :me) %button{ type: :button }= t('generic.copy') %p.lead= t('verification.extra_instructions_html') From cec89613720c23cb18d566ae05a6f69ac52d115e Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 2 Oct 2024 10:47:00 -0400 Subject: [PATCH 053/150] Move admin action log type list generation to helper (#32178) --- app/helpers/admin/action_logs_helper.rb | 7 +++++++ app/views/admin/action_logs/index.html.haml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/helpers/admin/action_logs_helper.rb b/app/helpers/admin/action_logs_helper.rb index e8d5634126..51e28d8b4e 100644 --- a/app/helpers/admin/action_logs_helper.rb +++ b/app/helpers/admin/action_logs_helper.rb @@ -35,4 +35,11 @@ module Admin::ActionLogsHelper end end end + + def sorted_action_log_types + Admin::ActionLogFilter::ACTION_TYPE_MAP + .keys + .map { |key| [I18n.t("admin.action_logs.action_types.#{key}"), key] } + .sort_by(&:first) + end end diff --git a/app/views/admin/action_logs/index.html.haml b/app/views/admin/action_logs/index.html.haml index c02c8f0ad4..a5d4188294 100644 --- a/app/views/admin/action_logs/index.html.haml +++ b/app/views/admin/action_logs/index.html.haml @@ -16,7 +16,7 @@ %strong= t('admin.action_logs.filter_by_action') .input.select.optional = form.select :action_type, - options_for_select(Admin::ActionLogFilter::ACTION_TYPE_MAP.keys.map { |key| [I18n.t("admin.action_logs.action_types.#{key}"), key] }, params[:action_type]), + options_for_select(sorted_action_log_types, params[:action_type]), prompt: I18n.t('admin.accounts.moderation.all') - if @action_logs.empty? From f768a6eb16880f4e584db530e4106be9b9dcf206 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 2 Oct 2024 17:51:05 +0200 Subject: [PATCH 054/150] Hide badges in media gallery when media are hidden (#32224) --- app/javascript/mastodon/components/media_gallery.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/components/media_gallery.jsx b/app/javascript/mastodon/components/media_gallery.jsx index 84cb4e04dc..1380d244ad 100644 --- a/app/javascript/mastodon/components/media_gallery.jsx +++ b/app/javascript/mastodon/components/media_gallery.jsx @@ -196,7 +196,7 @@ class Item extends PureComponent { {visible && thumbnail} - {badges && ( + {visible && badges && (
{badges}
From 6ef510fe3f4a08908df223d33d2788f851d0cb52 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Oct 2024 11:04:12 +0200 Subject: [PATCH 055/150] Update dependency json-schema to v5.0.1 (#32234) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 3950a30d62..987234a73d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -369,7 +369,7 @@ GEM json-ld-preloaded (3.3.0) json-ld (~> 3.3) rdf (~> 3.3) - json-schema (5.0.0) + json-schema (5.0.1) addressable (~> 2.8) jsonapi-renderer (0.2.2) jwt (2.7.1) From 0be1d332f28ca31e734954d7b8d73b41d60f485f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Oct 2024 11:04:33 +0200 Subject: [PATCH 056/150] Update dependency aws-sdk-s3 to v1.167.0 (#32231) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 987234a73d..1c2bb8df08 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -100,8 +100,8 @@ GEM attr_required (1.0.2) awrence (1.2.1) aws-eventstream (1.3.0) - aws-partitions (1.978.0) - aws-sdk-core (3.209.0) + aws-partitions (1.983.0) + aws-sdk-core (3.209.1) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.9) @@ -109,7 +109,7 @@ GEM aws-sdk-kms (1.94.0) aws-sdk-core (~> 3, >= 3.207.0) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.166.0) + aws-sdk-s3 (1.167.0) aws-sdk-core (~> 3, >= 3.207.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) From d96351a87d7078e8d6a07486d7d30e4a7956745d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Oct 2024 09:05:11 +0000 Subject: [PATCH 057/150] Update babel monorepo to v7.25.7 (#32225) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 1366 ++++++++++++++++++++++++++--------------------------- 1 file changed, 679 insertions(+), 687 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8970981d88..0a7f89990c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -42,127 +42,127 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/code-frame@npm:7.24.7" +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/code-frame@npm:7.25.7" dependencies: - "@babel/highlight": "npm:^7.24.7" + "@babel/highlight": "npm:^7.25.7" picocolors: "npm:^1.0.0" - checksum: 10c0/ab0af539473a9f5aeaac7047e377cb4f4edd255a81d84a76058595f8540784cc3fbe8acf73f1e073981104562490aabfb23008cd66dc677a456a4ed5390fdde6 + checksum: 10c0/14825c298bdec914caf3d24d1383b6d4cd6b030714686004992f4fc251831ecf432236652896f99d5d341f17170ae9a07b58d8d7b15aa0df8cfa1c5a7d5474bc languageName: node linkType: hard -"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.25.2, @babel/compat-data@npm:^7.25.4": - version: 7.25.4 - resolution: "@babel/compat-data@npm:7.25.4" - checksum: 10c0/50d79734d584a28c69d6f5b99adfaa064d0f41609a378aef04eb06accc5b44f8520e68549eba3a082478180957b7d5783f1bfb1672e4ae8574e797ce8bae79fa +"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/compat-data@npm:7.25.7" + checksum: 10c0/e5cc915abdd18d021236474a96606b2d4a915c4fb620c1ad776b8a08d91111e788cb3b7e9bad43593d4e0bfa4f06894357bcb0984102de1861b9e7322b6bc9f8 languageName: node linkType: hard "@babel/core@npm:^7.10.4, @babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.22.1, @babel/core@npm:^7.24.4": - version: 7.25.2 - resolution: "@babel/core@npm:7.25.2" + version: 7.25.7 + resolution: "@babel/core@npm:7.25.7" dependencies: "@ampproject/remapping": "npm:^2.2.0" - "@babel/code-frame": "npm:^7.24.7" - "@babel/generator": "npm:^7.25.0" - "@babel/helper-compilation-targets": "npm:^7.25.2" - "@babel/helper-module-transforms": "npm:^7.25.2" - "@babel/helpers": "npm:^7.25.0" - "@babel/parser": "npm:^7.25.0" - "@babel/template": "npm:^7.25.0" - "@babel/traverse": "npm:^7.25.2" - "@babel/types": "npm:^7.25.2" + "@babel/code-frame": "npm:^7.25.7" + "@babel/generator": "npm:^7.25.7" + "@babel/helper-compilation-targets": "npm:^7.25.7" + "@babel/helper-module-transforms": "npm:^7.25.7" + "@babel/helpers": "npm:^7.25.7" + "@babel/parser": "npm:^7.25.7" + "@babel/template": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" convert-source-map: "npm:^2.0.0" debug: "npm:^4.1.0" gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: 10c0/a425fa40e73cb72b6464063a57c478bc2de9dbcc19c280f1b55a3d88b35d572e87e8594e7d7b4880331addb6faef641bbeb701b91b41b8806cd4deae5d74f401 + checksum: 10c0/dad20af39624086afc3a0910bd97ae712c9ad0e9dda09fc5da93876e8ea1802b63ddd81c44f4aa8a9834db46de801eaab1ce9b81ab54b4fe907ae052c24de136 languageName: node linkType: hard -"@babel/generator@npm:^7.25.0, @babel/generator@npm:^7.25.4, @babel/generator@npm:^7.7.2": - version: 7.25.4 - resolution: "@babel/generator@npm:7.25.4" +"@babel/generator@npm:^7.25.7, @babel/generator@npm:^7.7.2": + version: 7.25.7 + resolution: "@babel/generator@npm:7.25.7" dependencies: - "@babel/types": "npm:^7.25.4" + "@babel/types": "npm:^7.25.7" "@jridgewell/gen-mapping": "npm:^0.3.5" "@jridgewell/trace-mapping": "npm:^0.3.25" - jsesc: "npm:^2.5.1" - checksum: 10c0/a2d8cc39e759214740f836360c8d9c17aa93e16e41afe73368a9e7ccd1d5c3303a420ce3aca1c9a31fdb93d1899de471d5aac97d1c64f741f8750a25a6e91fbc + jsesc: "npm:^3.0.2" + checksum: 10c0/c03a26c79864d60d04ce36b649c3fa0d6fd7b2bf6a22e22854a0457aa09206508392dd73ee40e7bc8d50b3602f9ff068afa47770cda091d332e7db1ca382ee96 languageName: node linkType: hard -"@babel/helper-annotate-as-pure@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-annotate-as-pure@npm:7.24.7" +"@babel/helper-annotate-as-pure@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-annotate-as-pure@npm:7.25.7" dependencies: - "@babel/types": "npm:^7.24.7" - checksum: 10c0/4679f7df4dffd5b3e26083ae65228116c3da34c3fff2c11ae11b259a61baec440f51e30fd236f7a0435b9d471acd93d0bc5a95df8213cbf02b1e083503d81b9a + "@babel/types": "npm:^7.25.7" + checksum: 10c0/2f020b0fa9d336b5778485cc2de3141561ec436a7591b685457a5bcdae4ce41d9ddee68169c95504e0789e5a4327e73b8b7e72e5b60e82e96d730c4d19255248 languageName: node linkType: hard -"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.24.7" +"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.25.7" dependencies: - "@babel/traverse": "npm:^7.24.7" - "@babel/types": "npm:^7.24.7" - checksum: 10c0/0ed84abf848c79fb1cd4c1ddac12c771d32c1904d87fc3087f33cfdeb0c2e0db4e7892b74b407d9d8d0c000044f3645a7391a781f788da8410c290bb123a1f13 + "@babel/traverse": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/e9dc5a7920a1d74150dec53ccd5e34f2b31ae307df7cdeec6289866f7bda97ecb1328b49a7710ecde5db5b6daad768c904a030f9a0fa3184963b0017622c42aa languageName: node linkType: hard -"@babel/helper-builder-react-jsx@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-builder-react-jsx@npm:7.24.7" +"@babel/helper-builder-react-jsx@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-builder-react-jsx@npm:7.25.7" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/types": "npm:^7.24.7" - checksum: 10c0/c95c8856c67c57060461f39b669707b2dca3501149bcc54b7c3e49c95069afce52179fc7c2bd809981acfbfdf0860ef1035dd7512cdba46c83bdb1ad6f6dc53f + "@babel/helper-annotate-as-pure": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/f8123a76e8c3fcdbb24cc14bfefc80e4c7bf58112ab26bea3247298748c674cbaee70591c362d0d881e4d88154ea4809b145f3ddcf96221cf55ba27bfde535c6 languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.24.7, @babel/helper-compilation-targets@npm:^7.24.8, @babel/helper-compilation-targets@npm:^7.25.2": - version: 7.25.2 - resolution: "@babel/helper-compilation-targets@npm:7.25.2" +"@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-compilation-targets@npm:7.25.7" dependencies: - "@babel/compat-data": "npm:^7.25.2" - "@babel/helper-validator-option": "npm:^7.24.8" - browserslist: "npm:^4.23.1" + "@babel/compat-data": "npm:^7.25.7" + "@babel/helper-validator-option": "npm:^7.25.7" + browserslist: "npm:^4.24.0" lru-cache: "npm:^5.1.1" semver: "npm:^6.3.1" - checksum: 10c0/de10e986b5322c9f807350467dc845ec59df9e596a5926a3b5edbb4710d8e3b8009d4396690e70b88c3844fe8ec4042d61436dd4b92d1f5f75655cf43ab07e99 + checksum: 10c0/705be7e5274a3fdade68e3e2cf42e2b600316ab52794e13b91299a16f16c926f15886b6e9d6df20eb943ccc1cdba5a363d4766f8d01e47b8e6f4e01175f5e66c languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.24.7, @babel/helper-create-class-features-plugin@npm:^7.25.4": - version: 7.25.4 - resolution: "@babel/helper-create-class-features-plugin@npm:7.25.4" +"@babel/helper-create-class-features-plugin@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-create-class-features-plugin@npm:7.25.7" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/helper-member-expression-to-functions": "npm:^7.24.8" - "@babel/helper-optimise-call-expression": "npm:^7.24.7" - "@babel/helper-replace-supers": "npm:^7.25.0" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.24.7" - "@babel/traverse": "npm:^7.25.4" + "@babel/helper-annotate-as-pure": "npm:^7.25.7" + "@babel/helper-member-expression-to-functions": "npm:^7.25.7" + "@babel/helper-optimise-call-expression": "npm:^7.25.7" + "@babel/helper-replace-supers": "npm:^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/a765d9e0482e13cf96642fa8aa28e6f7d4d7d39f37840d6246e5e10a7c47f47c52d52522edd3073f229449d17ec0db6f9b7b5e398bff6bb0b4994d65957a164c + checksum: 10c0/405c3c1a137acda1206380a96993cf2cfd808b3bee1c11c4af47ee0f03a20858497aa53394d6adc5431793c543be5e02010620e871a5ab39d938ae90a54b50f2 languageName: node linkType: hard -"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.24.7, @babel/helper-create-regexp-features-plugin@npm:^7.25.0, @babel/helper-create-regexp-features-plugin@npm:^7.25.2": - version: 7.25.2 - resolution: "@babel/helper-create-regexp-features-plugin@npm:7.25.2" +"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-create-regexp-features-plugin@npm:7.25.7" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - regexpu-core: "npm:^5.3.1" + "@babel/helper-annotate-as-pure": "npm:^7.25.7" + regexpu-core: "npm:^6.1.1" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/85a7e3639c118856fb1113f54fb7e3bf7698171ddfd0cd6fccccd5426b3727bc1434fe7f69090441dcde327feef9de917e00d35e47ab820047057518dd675317 + checksum: 10c0/75919fd5a67cd7be8497b56f7b9ed6b4843cb401956ba8d403aa9ae5b005bc28e35c7f27e704d820edbd1154394ed7a7984d4719916795d89d716f6980fe8bd4 languageName: node linkType: hard @@ -181,223 +181,223 @@ __metadata: languageName: node linkType: hard -"@babel/helper-member-expression-to-functions@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/helper-member-expression-to-functions@npm:7.24.8" +"@babel/helper-member-expression-to-functions@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-member-expression-to-functions@npm:7.25.7" dependencies: - "@babel/traverse": "npm:^7.24.8" - "@babel/types": "npm:^7.24.8" - checksum: 10c0/7e14a5acc91f6cd26305a4441b82eb6f616bd70b096a4d2099a968f16b26d50207eec0b9ebfc466fefd62bd91587ac3be878117cdfec819b7151911183cb0e5a + "@babel/traverse": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/1e948162ab48d84593a7c6ec9570d14c906146f1697144fc369c59dbeb00e4a062da67dd06cb0d8f98a044cd8389002dcf2ab6f5613d99c35748307846ec63fc languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.0.0-beta.49, @babel/helper-module-imports@npm:^7.10.4, @babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-module-imports@npm:7.24.7" +"@babel/helper-module-imports@npm:^7.0.0-beta.49, @babel/helper-module-imports@npm:^7.10.4, @babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-module-imports@npm:7.25.7" dependencies: - "@babel/traverse": "npm:^7.24.7" - "@babel/types": "npm:^7.24.7" - checksum: 10c0/97c57db6c3eeaea31564286e328a9fb52b0313c5cfcc7eee4bc226aebcf0418ea5b6fe78673c0e4a774512ec6c86e309d0f326e99d2b37bfc16a25a032498af0 + "@babel/traverse": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/0fd0c3673835e5bf75558e184bcadc47c1f6dd2fe2016d53ebe1e5a6ae931a44e093015c2f9a6651c1a89f25c76d9246710c2b0b460b95ee069c464f2837fa2c languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.24.7, @babel/helper-module-transforms@npm:^7.24.8, @babel/helper-module-transforms@npm:^7.25.0, @babel/helper-module-transforms@npm:^7.25.2": - version: 7.25.2 - resolution: "@babel/helper-module-transforms@npm:7.25.2" +"@babel/helper-module-transforms@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-module-transforms@npm:7.25.7" dependencies: - "@babel/helper-module-imports": "npm:^7.24.7" - "@babel/helper-simple-access": "npm:^7.24.7" - "@babel/helper-validator-identifier": "npm:^7.24.7" - "@babel/traverse": "npm:^7.25.2" + "@babel/helper-module-imports": "npm:^7.25.7" + "@babel/helper-simple-access": "npm:^7.25.7" + "@babel/helper-validator-identifier": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/adaa15970ace0aee5934b5a633789b5795b6229c6a9cf3e09a7e80aa33e478675eee807006a862aa9aa517935d81f88a6db8a9f5936e3a2a40ec75f8062bc329 + checksum: 10c0/f37fa7d1d4df21690535b278468cbd5faf0133a3080f282000cfa4f3ffc9462a1458f866b04b6a2f2d1eec4691236cba9a867da61270dab3ab19846e62f05090 languageName: node linkType: hard -"@babel/helper-optimise-call-expression@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-optimise-call-expression@npm:7.24.7" +"@babel/helper-optimise-call-expression@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-optimise-call-expression@npm:7.25.7" dependencies: - "@babel/types": "npm:^7.24.7" - checksum: 10c0/ca6a9884705dea5c95a8b3ce132d1e3f2ae951ff74987d400d1d9c215dae9c0f9e29924d8f8e131e116533d182675bc261927be72f6a9a2968eaeeaa51eb1d0f + "@babel/types": "npm:^7.25.7" + checksum: 10c0/19b4cc7e77811b1fedca4928dbc14026afef913c2ba4142e5e110ebdcb5c3b2efc0f0fbee9f362c23a194674147b9d627adea71c289b9be08b9067bc0085308b languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.7, @babel/helper-plugin-utils@npm:^7.24.8, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": - version: 7.24.8 - resolution: "@babel/helper-plugin-utils@npm:7.24.8" - checksum: 10c0/0376037f94a3bfe6b820a39f81220ac04f243eaee7193774b983e956c1750883ff236b30785795abbcda43fac3ece74750566830c2daa4d6e3870bb0dff34c2d +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.25.7, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": + version: 7.25.7 + resolution: "@babel/helper-plugin-utils@npm:7.25.7" + checksum: 10c0/241f8cf3c5b7700e91cab7cfe5b432a3c710ae3cd5bb96dc554da536a6d25f5b9f000cc0c0917501ceb4f76ba92599ee3beb25e10adaf96be59f8df89a842faf languageName: node linkType: hard -"@babel/helper-remap-async-to-generator@npm:^7.24.7, @babel/helper-remap-async-to-generator@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/helper-remap-async-to-generator@npm:7.25.0" +"@babel/helper-remap-async-to-generator@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-remap-async-to-generator@npm:7.25.7" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/helper-wrap-function": "npm:^7.25.0" - "@babel/traverse": "npm:^7.25.0" + "@babel/helper-annotate-as-pure": "npm:^7.25.7" + "@babel/helper-wrap-function": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/0d17b5f7bb6a607edc9cc62fff8056dd9f341bf2f919884f97b99170d143022a5e7ae57922c4891e4fc360ad291e708d2f8cd8989f1d3cd7a17600159984f5a6 + checksum: 10c0/972d84876adce6ab61c87a2df47e1afc790b73cff0d1767d0a1c5d9f7aa5e91d8c581a272b66b2051a26cfbb167d8a780564705e488e3ce1f477f1c15059bc5f languageName: node linkType: hard -"@babel/helper-replace-supers@npm:^7.24.7, @babel/helper-replace-supers@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/helper-replace-supers@npm:7.25.0" +"@babel/helper-replace-supers@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-replace-supers@npm:7.25.7" dependencies: - "@babel/helper-member-expression-to-functions": "npm:^7.24.8" - "@babel/helper-optimise-call-expression": "npm:^7.24.7" - "@babel/traverse": "npm:^7.25.0" + "@babel/helper-member-expression-to-functions": "npm:^7.25.7" + "@babel/helper-optimise-call-expression": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/b4b6650ab3d56c39a259367cd97f8df2f21c9cebb3716fea7bca40a150f8847bfb82f481e98927c7c6579b48a977b5a8f77318a1c6aeb497f41ecd6dbc3fdfef + checksum: 10c0/761d64ee74429f7326a6aa65e2cd5bfcb8de9e3bc3f1efb14b8f610d2410f003b0fca52778dc801d49ff8fbc90b057e8f51b27c62b0b05c95eaf23140ca1287b languageName: node linkType: hard -"@babel/helper-simple-access@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-simple-access@npm:7.24.7" +"@babel/helper-simple-access@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-simple-access@npm:7.25.7" dependencies: - "@babel/traverse": "npm:^7.24.7" - "@babel/types": "npm:^7.24.7" - checksum: 10c0/7230e419d59a85f93153415100a5faff23c133d7442c19e0cd070da1784d13cd29096ee6c5a5761065c44e8164f9f80e3a518c41a0256df39e38f7ad6744fed7 + "@babel/traverse": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/eed1b499bfb4f613c18debd61517e3de77b6da2727ca025aa05ac81599e0269f1dddb5237db04e8bb598115d015874752e0a7f11ff38672d74a4976097417059 languageName: node linkType: hard -"@babel/helper-skip-transparent-expression-wrappers@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.24.7" +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.25.7" dependencies: - "@babel/traverse": "npm:^7.24.7" - "@babel/types": "npm:^7.24.7" - checksum: 10c0/e3a9b8ac9c262ac976a1bcb5fe59694db5e6f0b4f9e7bdba5c7693b8b5e28113c23bdaa60fe8d3ec32a337091b67720b2053bcb3d5655f5406536c3d0584242b + "@babel/traverse": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/5804adb893849a9d8cfb548e3812566a81d95cb0c9a10d66b52912d13f488e577c33063bf19bc06ac70e6333162a7370d67ba1a1c3544d37fb50d5f4a00db4de languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/helper-string-parser@npm:7.24.8" - checksum: 10c0/6361f72076c17fabf305e252bf6d580106429014b3ab3c1f5c4eb3e6d465536ea6b670cc0e9a637a77a9ad40454d3e41361a2909e70e305116a23d68ce094c08 +"@babel/helper-string-parser@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-string-parser@npm:7.25.7" + checksum: 10c0/73ef2ceb81f8294678a0afe8ab0103729c0370cac2e830e0d5128b03be5f6a2635838af31d391d763e3c5a4460ed96f42fd7c9b552130670d525be665913bc4c languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-validator-identifier@npm:7.24.7" - checksum: 10c0/87ad608694c9477814093ed5b5c080c2e06d44cb1924ae8320474a74415241223cc2a725eea2640dd783ff1e3390e5f95eede978bc540e870053152e58f1d651 +"@babel/helper-validator-identifier@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-validator-identifier@npm:7.25.7" + checksum: 10c0/07438e5bf01ab2882a15027fdf39ac3b0ba1b251774a5130917907014684e2f70fef8fd620137ca062c4c4eedc388508d2ea7a3a7d9936a32785f4fe116c68c0 languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.24.7, @babel/helper-validator-option@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/helper-validator-option@npm:7.24.8" - checksum: 10c0/73db93a34ae89201351288bee7623eed81a54000779462a986105b54ffe82069e764afd15171a428b82e7c7a9b5fec10b5d5603b216317a414062edf5c67a21f +"@babel/helper-validator-option@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-validator-option@npm:7.25.7" + checksum: 10c0/12ed418c8e3ed9ed44c8c80d823f4e42d399b5eb2e423adccb975e31a31a008cd3b5d8eab688b31f740caff4a1bb28fe06ea2fa7d635aee34cc0ad6995d50f0a languageName: node linkType: hard -"@babel/helper-wrap-function@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/helper-wrap-function@npm:7.25.0" +"@babel/helper-wrap-function@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-wrap-function@npm:7.25.7" dependencies: - "@babel/template": "npm:^7.25.0" - "@babel/traverse": "npm:^7.25.0" - "@babel/types": "npm:^7.25.0" - checksum: 10c0/d54601a98384c191cbc1ff07b03a19e288ef8d5c6bfafe270b2a303d96e7304eb296002921ed464cc1b105a547d1db146eb86b0be617924dee1ba1b379cdc216 + "@babel/template": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/b5d412f72697f4a4ce4cb9784fbaf82501c63cf95066c0eadd3179e3439cbbf0aa5fa4858d93590083671943cd357aeb87286958df34aa56fdf8a4c9dea39755 languageName: node linkType: hard -"@babel/helpers@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/helpers@npm:7.25.0" +"@babel/helpers@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helpers@npm:7.25.7" dependencies: - "@babel/template": "npm:^7.25.0" - "@babel/types": "npm:^7.25.0" - checksum: 10c0/b7fe007fc4194268abf70aa3810365085e290e6528dcb9fbbf7a765d43c74b6369ce0f99c5ccd2d44c413853099daa449c9a0123f0b212ac8d18643f2e8174b8 + "@babel/template": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/3b3ae9e373bd785414195ef8f59976a69d5a6ebe0ef2165fdcc5165e5c3ee09e0fcee94bb457df2ddb8c0532e4146d0a9b7a96b3497399a4bff4ffe196b30228 languageName: node linkType: hard -"@babel/highlight@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/highlight@npm:7.24.7" +"@babel/highlight@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/highlight@npm:7.25.7" dependencies: - "@babel/helper-validator-identifier": "npm:^7.24.7" + "@babel/helper-validator-identifier": "npm:^7.25.7" chalk: "npm:^2.4.2" js-tokens: "npm:^4.0.0" picocolors: "npm:^1.0.0" - checksum: 10c0/674334c571d2bb9d1c89bdd87566383f59231e16bcdcf5bb7835babdf03c9ae585ca0887a7b25bdf78f303984af028df52831c7989fecebb5101cc132da9393a + checksum: 10c0/1f5894fdb0a0af6101fb2822369b2eeeae32cbeae2ef73ff73fc6a0a4a20471565cd9cfa589f54ed69df66adeca7c57266031ca9134b7bd244d023a488d419aa languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.25.0, @babel/parser@npm:^7.25.4": - version: 7.25.4 - resolution: "@babel/parser@npm:7.25.4" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/parser@npm:7.25.7" dependencies: - "@babel/types": "npm:^7.25.4" + "@babel/types": "npm:^7.25.7" bin: parser: ./bin/babel-parser.js - checksum: 10c0/bdada5662f15d1df11a7266ec3bc9bb769bf3637ecf3d051eafcfc8f576dcf5a3ac1007c5e059db4a1e1387db9ae9caad239fc4f79e4c2200930ed610e779993 + checksum: 10c0/b771469bb6b636c18a8d642b9df3c73913c3860a979591e1a29a98659efd38b81d3e393047b5251fe382d4c82c681c12da9ce91c98d69316d2604d155a214bcf languageName: node linkType: hard -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.25.3": - version: 7.25.3 - resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.25.3" +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/traverse": "npm:^7.25.3" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/814b4d3f102e7556a5053d1acf57ef601cfcff39a2c81b8cdc6a5c842e3cb9838f5925d1466a5f1e6416e74c9c83586a3c07fbd7fb8610a396c2becdf9ae5790 + checksum: 10c0/c6ba97c39973897a2ab021c4a77221e1e93e853a5811d498db325da1bd692e41fa521db6d91bb709ccafd4e54ddd00869ffb35846923c3ccd49d46124b316904 languageName: node linkType: hard -"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.25.0" +"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/9645a1f47b3750acadb1353c02e71cc712d072aafe5ce115ed3a886bc14c5d9200cfb0b5b5e60e813baa549b800cf798f8714019fd246c699053cf68c428e426 + checksum: 10c0/ac284868bf410f952c6959b0d77708464127160416f003b05c8127d30e64792d671abc167ebf778b17707e32174223ea8d3ff487276991fa90297d92f0dac6e2 languageName: node linkType: hard -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.25.0" +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/ed1ce1c90cac46c01825339fd0f2a96fa071b016fb819d8dfaf8e96300eae30e74870cb47e4dc80d4ce2fb287869f102878b4f3b35bc927fec8b1d0d76bcf612 + checksum: 10c0/1bffc0a20c8c82b4c77515eb4c99b961b38184116f008bb42bed4e12d3379ba7b2bc6cf299bcea8118d645bb7a5e0caa83969842f16dd1fce49fb3a050e4ac65 languageName: node linkType: hard -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.24.7" +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.24.7" - "@babel/plugin-transform-optional-chaining": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.7" + "@babel/plugin-transform-optional-chaining": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.13.0 - checksum: 10c0/aeb6e7aa363a47f815cf956ea1053c5dd8b786a17799f065c9688ba4b0051fe7565d258bbe9400bfcbfb3114cb9fda66983e10afe4d750bc70ff75403e15dd36 + checksum: 10c0/32223f012614a0b2657579317ded7d0d09af2aa316285715c5012f974d0f15c2ce2fe0d8e80fdd9bac6c10c21c93cc925a9dfd6c8e21ce7ba1a9fe06a58088b4 languageName: node linkType: hard -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.25.0" +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/traverse": "npm:^7.25.0" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/45988025537a9d4a27b610fd696a18fd9ba9336621a69b4fb40560eeb10c79657f85c92a37f30c7c8fb29c22970eea0b373315795a891f1a05549a6cfe5a6bfe + checksum: 10c0/aa2ee7a5954d187de6cbcca0e0b64cfb79c4d224c332d1eb1e0e4afd92ef1a1f4bc4af24f66154097ccb348c08121a875456f47baed220b1b9e93584e6a19b65 languageName: node linkType: hard @@ -476,25 +476,25 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-import-assertions@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-syntax-import-assertions@npm:7.24.7" +"@babel/plugin-syntax-import-assertions@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-syntax-import-assertions@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/b82c53e095274ee71c248551352d73441cf65b3b3fc0107258ba4e9aef7090772a425442b3ed1c396fa207d0efafde8929c87a17d3c885b3ca2021316e87e246 + checksum: 10c0/0fee0d971f3c654749fdf92e09b6556bba26ab014c8e99b7252f6a7f1ca108f17edd7ceefb5401d7b7008e98ab1b6f8c3c6a5db72862e7c7b2fcd649d000d690 languageName: node linkType: hard -"@babel/plugin-syntax-import-attributes@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-syntax-import-attributes@npm:7.24.7" +"@babel/plugin-syntax-import-attributes@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-syntax-import-attributes@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/eccc54d0f03c96d0eec7a6e2fa124dadbc7298345b62ffc4238f173308c4325b5598f139695ff05a95cf78412ef6903599e4b814496612bf39aad4715a16375b + checksum: 10c0/fe00cdb96fd289ab126830a98e1dcf5ab7b529a6ef1c01a72506b5e7b1197d6e46c3c4d029cd90d1d61eb9a15ef77c282d156d0c02c7e32f168bb09d84150db4 languageName: node linkType: hard @@ -520,14 +520,14 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:7, @babel/plugin-syntax-jsx@npm:^7.24.7, @babel/plugin-syntax-jsx@npm:^7.7.2": - version: 7.24.7 - resolution: "@babel/plugin-syntax-jsx@npm:7.24.7" +"@babel/plugin-syntax-jsx@npm:7, @babel/plugin-syntax-jsx@npm:^7.25.7, @babel/plugin-syntax-jsx@npm:^7.7.2": + version: 7.25.7 + resolution: "@babel/plugin-syntax-jsx@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/f44d927a9ae8d5ef016ff5b450e1671e56629ddc12e56b938e41fd46e141170d9dfc9a53d6cb2b9a20a7dd266a938885e6a3981c60c052a2e1daed602ac80e51 + checksum: 10c0/17db499c31fcfaa94d5408726d943955d51d478353d1e2dd84eda6024f7e3d104b9456a77f8aabfae0db7f4dc32f810d08357112f7fcbe305e7c9fcf5b3cac13 languageName: node linkType: hard @@ -619,14 +619,14 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.24.7, @babel/plugin-syntax-typescript@npm:^7.7.2": - version: 7.24.7 - resolution: "@babel/plugin-syntax-typescript@npm:7.24.7" +"@babel/plugin-syntax-typescript@npm:^7.25.7, @babel/plugin-syntax-typescript@npm:^7.7.2": + version: 7.25.7 + resolution: "@babel/plugin-syntax-typescript@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/cdabd2e8010fb0ad15b49c2c270efc97c4bfe109ead36c7bbcf22da7a74bc3e49702fc4f22f12d2d6049e8e22a5769258df1fd05f0420ae45e11bdd5bc07805a + checksum: 10c0/ed51fd81a5cf571a89fc4cf4c0e3b0b91285c367237374c133d2e5e718f3963cfa61b81997df39220a8837dc99f9e9a8ab7701d259c09fae379e4843d9db60c2 languageName: node linkType: hard @@ -642,466 +642,466 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-arrow-functions@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-arrow-functions@npm:7.24.7" +"@babel/plugin-transform-arrow-functions@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-arrow-functions@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/6ac05a54e5582f34ac6d5dc26499e227227ec1c7fa6fc8de1f3d40c275f140d3907f79bbbd49304da2d7008a5ecafb219d0b71d78ee3290ca22020d878041245 + checksum: 10c0/c8d75ead93f130bf113b6d29493aca695092661ef039336d2a227169c3b7895aa5e9bcc548c42a95a6eaaaf49e512317b00699940bd40ccefd77443e703d3935 languageName: node linkType: hard -"@babel/plugin-transform-async-generator-functions@npm:^7.25.4": - version: 7.25.4 - resolution: "@babel/plugin-transform-async-generator-functions@npm:7.25.4" +"@babel/plugin-transform-async-generator-functions@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/helper-remap-async-to-generator": "npm:^7.25.0" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-remap-async-to-generator": "npm:^7.25.7" "@babel/plugin-syntax-async-generators": "npm:^7.8.4" - "@babel/traverse": "npm:^7.25.4" + "@babel/traverse": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/efed6f6be90b25ad77c15a622a0dc0b22dbf5d45599c207ab8fbc4e959aef21f574fa467d9cf872e45de664a46c32334e78dee2332d82f5f27e26249a34a0920 + checksum: 10c0/dcdd17d8cafafe0eb2edd0a46a7abe86c72235c957c8eb1157ccadb2b199572d5d1aa36a2d3bce5cb99990f7d3c6290ecf09959c62f3081c4df9ff717a1c84a4 languageName: node linkType: hard -"@babel/plugin-transform-async-to-generator@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-async-to-generator@npm:7.24.7" +"@babel/plugin-transform-async-to-generator@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-async-to-generator@npm:7.25.7" dependencies: - "@babel/helper-module-imports": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/helper-remap-async-to-generator": "npm:^7.24.7" + "@babel/helper-module-imports": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-remap-async-to-generator": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/83c82e243898875af8457972a26ab29baf8a2078768ee9f35141eb3edff0f84b165582a2ff73e90a9e08f5922bf813dbf15a85c1213654385198f4591c0dc45d + checksum: 10c0/1dbefba9c1455f7a92b8c59a93c622091db945294c936fc2c09b1648308c5b4cb2ecaae92baae0d07a324ab890a8a2ee27ceb046bc120932845d27aede275821 languageName: node linkType: hard -"@babel/plugin-transform-block-scoped-functions@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.24.7" +"@babel/plugin-transform-block-scoped-functions@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/113e86de4612ae91773ff5cb6b980f01e1da7e26ae6f6012127415d7ae144e74987bc23feb97f63ba4bc699331490ddea36eac004d76a20d5369e4cc6a7f61cd + checksum: 10c0/b1e77492295d1b271ef850a81b0404cf3d0dd6a2bcbeab28a0fd99e61c6de4bda91dff583bb42138eec61bf71282bdd3b1bebcb53b7e373035e77fd6ba66caeb languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/plugin-transform-block-scoping@npm:7.25.0" +"@babel/plugin-transform-block-scoping@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-block-scoping@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/382931c75a5d0ea560387e76cb57b03461300527e4784efcb2fb62f36c1eb0ab331327b6034def256baa0cad9050925a61f9c0d56261b6afd6a29c3065fb0bd4 + checksum: 10c0/b2057e00535cd0e8bd5ee5d4640aa2e952564aeafb1bcf4e7b6de33442422877bb0ca8669ad0a48262ec077271978c61eae87b6b3bc8f472d830fa781d6f7e44 languageName: node linkType: hard -"@babel/plugin-transform-class-properties@npm:^7.25.4": - version: 7.25.4 - resolution: "@babel/plugin-transform-class-properties@npm:7.25.4" +"@babel/plugin-transform-class-properties@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-class-properties@npm:7.25.7" dependencies: - "@babel/helper-create-class-features-plugin": "npm:^7.25.4" - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-create-class-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/0b41bc8a5920d3d17c7c06220b601cf43e0a32ac34f05f05cd0cdf08915e4521b1b707cb1e60942b4fc68a5dfac09f0444a8720e0c72ce76fb039e8ec5263115 + checksum: 10c0/1f41e6934b20ad3e05df63959cff9bc600ff3119153b9acbbd44c1731e7df04866397e6e17799173f4c53cdee6115e155632859aee20bf47ec7dcef3f2168a47 languageName: node linkType: hard -"@babel/plugin-transform-class-static-block@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-class-static-block@npm:7.24.7" +"@babel/plugin-transform-class-static-block@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-class-static-block@npm:7.25.7" dependencies: - "@babel/helper-create-class-features-plugin": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-create-class-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" "@babel/plugin-syntax-class-static-block": "npm:^7.14.5" peerDependencies: "@babel/core": ^7.12.0 - checksum: 10c0/b0ade39a3d09dce886f79dbd5907c3d99b48167eddb6b9bbde24a0598129654d7017e611c20494cdbea48b07ac14397cd97ea34e3754bbb2abae4e698128eccb + checksum: 10c0/cbb4b46cbd8ad10106eb2bedb5a0665661a1d1d5b6f3ab565ff454b802dab4718e02b25670fe0d40835494aedb3dc26757c06cc4da6ff3e80291c5f882269bd3 languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:^7.25.4": - version: 7.25.4 - resolution: "@babel/plugin-transform-classes@npm:7.25.4" +"@babel/plugin-transform-classes@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-classes@npm:7.25.7" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/helper-compilation-targets": "npm:^7.25.2" - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/helper-replace-supers": "npm:^7.25.0" - "@babel/traverse": "npm:^7.25.4" + "@babel/helper-annotate-as-pure": "npm:^7.25.7" + "@babel/helper-compilation-targets": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-replace-supers": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" globals: "npm:^11.1.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/c68424d9dd64860825111aa4a4ed5caf29494b7a02ddb9c36351d768c41e8e05127d89274795cdfcade032d9d299e6c677418259df58c71e68f1741583dcf467 + checksum: 10c0/8121781e1d8acd80e6169019106f73a399475ad9c895c1988a344dfed5a6ddd340938ac55123dc1e423bb8f25f255f5d11031116ad756ba3c314595a97c973af languageName: node linkType: hard -"@babel/plugin-transform-computed-properties@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-computed-properties@npm:7.24.7" +"@babel/plugin-transform-computed-properties@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-computed-properties@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/template": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/template": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/25636dbc1f605c0b8bc60aa58628a916b689473d11551c9864a855142e36742fe62d4a70400ba3b74902338e77fb3d940376c0a0ba154b6b7ec5367175233b49 + checksum: 10c0/7ad0a1c126f50935a02e77d438ebc39078a9d644b3a60de60bec32c5d9f49e7f2b193fcecb8c61bb1bc3cdd4af1e93f72d022d448511fa76a171527c633cd1bf languageName: node linkType: hard -"@babel/plugin-transform-destructuring@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/plugin-transform-destructuring@npm:7.24.8" +"@babel/plugin-transform-destructuring@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-destructuring@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/804968c1d5f5072c717505296c1e5d5ec33e90550423de66de82bbcb78157156e8470bbe77a04ab8c710a88a06360a30103cf223ac7eff4829adedd6150de5ce + checksum: 10c0/a563123b2fb267e03aa50104005f00b56226a685938906c42c1b251462e0cc9fc89e587d5656d3324159071eb8ebda8c68a6011f11d5a00fb1436cb5a5411b7b languageName: node linkType: hard -"@babel/plugin-transform-dotall-regex@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-dotall-regex@npm:7.24.7" +"@babel/plugin-transform-dotall-regex@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-dotall-regex@npm:7.25.7" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-create-regexp-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/793f14c9494972d294b7e7b97b747f47874b6d57d7804d3443c701becf5db192c9311be6a1835c07664486df1f5c60d33196c36fb7e11a53015e476b4c145b33 + checksum: 10c0/7f1db3ec20b7fae46db4a9c4c257d75418b0896b72c0a3de20b3044f952801480f0a2e75ebb0d64f13e8cd4db0e49aa42c5c0edff372b23c41679b1ea5dd3ed4 languageName: node linkType: hard -"@babel/plugin-transform-duplicate-keys@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-duplicate-keys@npm:7.24.7" +"@babel/plugin-transform-duplicate-keys@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-duplicate-keys@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/75ff7ec1117ac500e77bf20a144411d39c0fdd038f108eec061724123ce6d1bb8d5bd27968e466573ee70014f8be0043361cdb0ef388f8a182d1d97ad67e51b9 + checksum: 10c0/b4079981e2db19737a0f1a00254e7388e2d3c01ce36e9fd826e4d86d3c1755339495e29c71fd7c84a068201ec24687328d48f3bf53b32b6d6224f51d9a34da74 languageName: node linkType: hard -"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.25.0" +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.25.7" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.25.0" - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-create-regexp-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/1c9b57ddd9b33696e88911d0e7975e1573ebc46219c4b30eb1dc746cbb71aedfac6f6dab7fdfdec54dd58f31468bf6ab56b157661ea4ffe58f906d71f89544c8 + checksum: 10c0/e4946090ff6d88d54b78265ee653079ec34c117ac046e22f66f7c4ac44249cdc2dfca385bc5bf4386db668b9948eeb12985589500188bc252e684c7714c31475 languageName: node linkType: hard -"@babel/plugin-transform-dynamic-import@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-dynamic-import@npm:7.24.7" +"@babel/plugin-transform-dynamic-import@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-dynamic-import@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" "@babel/plugin-syntax-dynamic-import": "npm:^7.8.3" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/eeda48372efd0a5103cb22dadb13563c975bce18ae85daafbb47d57bb9665d187da9d4fe8d07ac0a6e1288afcfcb73e4e5618bf75ff63fddf9736bfbf225203b + checksum: 10c0/c733252ff20a32d9747dd081916270f5a073856597e849a5f458b12f4354499b18714f5e7049e341432851d9975077cb37effcd276c7f816faa6f5ff708dc5e1 languageName: node linkType: hard -"@babel/plugin-transform-exponentiation-operator@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.24.7" +"@babel/plugin-transform-exponentiation-operator@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.25.7" dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-builder-binary-assignment-operator-visitor": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/ace3e11c94041b88848552ba8feb39ae4d6cad3696d439ff51445bd2882d8b8775d85a26c2c0edb9b5e38c9e6013cc11b0dea89ec8f93c7d9d7ee95e3645078c + checksum: 10c0/c8537b9f3cddc5a8d3710f6980196dc7a0f4389f8f82617312a5f7b8b15bcd8ddaeba783c687c3ac6031eb0a4ba0bc380a98da6bf7efe98e225602a98ad42a1e languageName: node linkType: hard -"@babel/plugin-transform-export-namespace-from@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-export-namespace-from@npm:7.24.7" +"@babel/plugin-transform-export-namespace-from@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-export-namespace-from@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" "@babel/plugin-syntax-export-namespace-from": "npm:^7.8.3" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/4e144d7f1c57bc63b4899dbbbdfed0880f2daa75ea9c7251c7997f106e4b390dc362175ab7830f11358cb21f6b972ca10a43a2e56cd789065f7606b082674c0c + checksum: 10c0/ef61fc5d54c9c8b075cbd9db62beaf295e38e08a1edb1882995105d3e959763be1631f7d7f7cb7461b702ebd0b4a601f2eb2cd6521acaf061310a3a3305fa756 languageName: node linkType: hard -"@babel/plugin-transform-for-of@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-for-of@npm:7.24.7" +"@babel/plugin-transform-for-of@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-for-of@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/77629b1173e55d07416f05ba7353caa09d2c2149da2ca26721ab812209b63689d1be45116b68eadc011c49ced59daf5320835b15245eb7ae93ae0c5e8277cfc0 + checksum: 10c0/08a37a1742368a422d095c998ed76f60f6bf3f9cc060033be121d803fd2dddc08fe543e48ee49c022bdc9ed80893ca79d084958d83d30684178b088774754277 languageName: node linkType: hard -"@babel/plugin-transform-function-name@npm:^7.25.1": - version: 7.25.1 - resolution: "@babel/plugin-transform-function-name@npm:7.25.1" +"@babel/plugin-transform-function-name@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-function-name@npm:7.25.7" dependencies: - "@babel/helper-compilation-targets": "npm:^7.24.8" - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/traverse": "npm:^7.25.1" + "@babel/helper-compilation-targets": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/e74912174d5e33d1418b840443c2e226a7b76cc017c1ed20ee30a566e4f1794d4a123be03180da046241576e8b692731807ba1f52608922acf1cb2cb6957593f + checksum: 10c0/ca98e1116c0ada7211ed43e4b7f21ca15f95bbbdad70f2fbe1ec2d90a97daedf9f22fcb0a25c8b164a5e394f509f2e4d1f7609d26dc938a58d37c5ee9b80088a languageName: node linkType: hard -"@babel/plugin-transform-json-strings@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-json-strings@npm:7.24.7" +"@babel/plugin-transform-json-strings@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-json-strings@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" "@babel/plugin-syntax-json-strings": "npm:^7.8.3" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/17c72cd5bf3e90e722aabd333559275f3309e3fa0b9cea8c2944ab83ae01502c71a2be05da5101edc02b3fc8df15a8dbb9b861cbfcc8a52bf5e797cf01d3a40a + checksum: 10c0/aa6e5f65c8a5f2459d7daa9b5b4ff97ff43bab21f4a8513ed84d35300b0323ec542dc101c5f11622e442dfc93b3a229c7f41ebc7645370dfec6d066bda800a0b languageName: node linkType: hard -"@babel/plugin-transform-literals@npm:^7.25.2": - version: 7.25.2 - resolution: "@babel/plugin-transform-literals@npm:7.25.2" +"@babel/plugin-transform-literals@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-literals@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/0796883217b0885d37e7f6d350773be349e469a812b6bf11ccf862a6edf65103d3e7c849529d65381b441685c12e756751d8c2489a0fd3f8139bb5ef93185f58 + checksum: 10c0/c2c2488102f33e566f45becdcb632e53bd052ecfb2879deb07a614b3e9437e3b624c3b16d080096d50b0b622edebd03e438acbf9260bcc41167897963f64560e languageName: node linkType: hard -"@babel/plugin-transform-logical-assignment-operators@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.24.7" +"@babel/plugin-transform-logical-assignment-operators@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.10.4" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/dbe882eb9053931f2ab332c50fc7c2a10ef507d6421bd9831adbb4cb7c9f8e1e5fbac4fbd2e007f6a1bf1df1843547559434012f118084dc0bf42cda3b106272 + checksum: 10c0/d610a8a2c1be83e03cce2256f29519e705dc68289c09d67f1f362d1fd80f4b36eaf2affc05710abb53a272895041e24d9e95ec73a516a23a67cb907023fbe37b languageName: node linkType: hard -"@babel/plugin-transform-member-expression-literals@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-member-expression-literals@npm:7.24.7" +"@babel/plugin-transform-member-expression-literals@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-member-expression-literals@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/e789ae359bdf2d20e90bedef18dfdbd965c9ebae1cee398474a0c349590fda7c8b874e1a2ceee62e47e5e6ec1730e76b0f24e502164357571854271fc12cc684 + checksum: 10c0/d6936b98ae4d3daed850dc4e064042ea4375f815219ba9d8591373bf1fba4cfdb5be42623ae8882f2d666cc34af650a4855e2a5ad89e3c235d73a6f172f9969c languageName: node linkType: hard -"@babel/plugin-transform-modules-amd@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-modules-amd@npm:7.24.7" +"@babel/plugin-transform-modules-amd@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-modules-amd@npm:7.25.7" dependencies: - "@babel/helper-module-transforms": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-module-transforms": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/6df7de7fce34117ca4b2fa07949b12274c03668cbfe21481c4037b6300796d50ae40f4f170527b61b70a67f26db906747797e30dbd0d9809a441b6e220b5728f + checksum: 10c0/c0bc999206c3834c090e6559a6c8a55d7672d3573104e832223ebe7df99bd1b82fc850e15ba32f512c84b0db1cdb613b66fa60abe9abb9c7e8dcbff91649b356 languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.24.7, @babel/plugin-transform-modules-commonjs@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/plugin-transform-modules-commonjs@npm:7.24.8" +"@babel/plugin-transform-modules-commonjs@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.25.7" dependencies: - "@babel/helper-module-transforms": "npm:^7.24.8" - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/helper-simple-access": "npm:^7.24.7" + "@babel/helper-module-transforms": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-simple-access": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/f1cf552307ebfced20d3907c1dd8be941b277f0364aa655e2b5fee828c84c54065745183104dae86f1f93ea0406db970a463ef7ceaaed897623748e99640e5a7 + checksum: 10c0/2f1c945fc3c9b690b0ddcf2c80156b2e4fbf2cf15aac43ac8fe6e4b34125869528839a53d07c564e62e4aed394ebdc1d2c3b796b547374455522581c11b7599c languageName: node linkType: hard -"@babel/plugin-transform-modules-systemjs@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/plugin-transform-modules-systemjs@npm:7.25.0" +"@babel/plugin-transform-modules-systemjs@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-modules-systemjs@npm:7.25.7" dependencies: - "@babel/helper-module-transforms": "npm:^7.25.0" - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/helper-validator-identifier": "npm:^7.24.7" - "@babel/traverse": "npm:^7.25.0" + "@babel/helper-module-transforms": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-validator-identifier": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/fca6198da71237e4bb1274b3b67a0c81d56013c9535361242b6bfa87d70a9597854aadb45d4d8203369be4a655e158be2a5d20af0040b1f8d1bfc47db3ad7b68 + checksum: 10c0/95eaea7082636710c61e49e58b3907e85ec79db4327411d3784f28592509fbe94a53cc3d20a36a1cf245efc6d3f0017eae15b45ffd645c1ab949bb4e1670e6bb languageName: node linkType: hard -"@babel/plugin-transform-modules-umd@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-modules-umd@npm:7.24.7" +"@babel/plugin-transform-modules-umd@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-modules-umd@npm:7.25.7" dependencies: - "@babel/helper-module-transforms": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-module-transforms": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/7791d290121db210e4338b94b4a069a1a79e4c7a8d7638d8159a97b281851bbed3048dac87a4ae718ad963005e6c14a5d28e6db2eeb2b04e031cee92fb312f85 + checksum: 10c0/8849ab04eecdb73cd37e2d7289449fa5256331832b0304c220b2a6aaa12e2d2dd87684f2813412d1fc5bdb3d6b55cc08c6386d3273fe05a65177c09bee5b6769 languageName: node linkType: hard -"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.24.7" +"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.25.7" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-create-regexp-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/41a0b0f2d0886318237440aa3b489f6d0305361d8671121777d9ff89f9f6de9d0c02ce93625049061426c8994064ef64deae8b819d1b14c00374a6a2336fb5d9 + checksum: 10c0/eb55fec55dc930cd122911f3e4a421320fa8b1b4de85bfd7ef11b46c611ec69b0213c114a6e1c6bc224d6b954ff183a0caa7251267d5258ecc0f00d6d9ca1d52 languageName: node linkType: hard -"@babel/plugin-transform-new-target@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-new-target@npm:7.24.7" +"@babel/plugin-transform-new-target@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-new-target@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/2540808a35e1a978e537334c43dab439cf24c93e7beb213a2e71902f6710e60e0184316643790c0a6644e7a8021e52f7ab8165e6b3e2d6651be07bdf517b67df + checksum: 10c0/8e5dce6d027e0f3fd394578ea1af7f515de157793a15c23a5aad7034a6d8a4005ef280238e67a232bb4dd4fafd3a264fed462deb149128ddd9ce59ff6f575cff languageName: node linkType: hard -"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.22.3, @babel/plugin-transform-nullish-coalescing-operator@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.24.7" +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.22.3, @babel/plugin-transform-nullish-coalescing-operator@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/7243c8ff734ed5ef759dd8768773c4b443c12e792727e759a1aec2c7fa2bfdd24f1ecb42e292a7b3d8bd3d7f7b861cf256a8eb4ba144fc9cc463892c303083d9 + checksum: 10c0/b35a96a79ef4895b00e4f758d3185cb17e4fbfada311894ad5f0988a55fc2c21820dc789b26a3cb8fbd620434faa516e52acb6e2da105c2edbd29de8b6b0facf languageName: node linkType: hard -"@babel/plugin-transform-numeric-separator@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-numeric-separator@npm:7.24.7" +"@babel/plugin-transform-numeric-separator@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-numeric-separator@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" "@babel/plugin-syntax-numeric-separator": "npm:^7.10.4" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/e18e09ca5a6342645d00ede477731aa6e8714ff357efc9d7cda5934f1703b3b6fb7d3298dce3ce3ba53e9ff1158eab8f1aadc68874cc21a6099d33a1ca457789 + checksum: 10c0/c028ae89e6b4e1d757f8f1ebcb3b420e6559bb35002728f6f5651d5f669fbf73764adf6e3597908fa12adf8dbae683e5f74b3a7f68e8774a9663c18c0f999539 languageName: node linkType: hard -"@babel/plugin-transform-object-rest-spread@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-object-rest-spread@npm:7.24.7" +"@babel/plugin-transform-object-rest-spread@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-object-rest-spread@npm:7.25.7" dependencies: - "@babel/helper-compilation-targets": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-compilation-targets": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" "@babel/plugin-syntax-object-rest-spread": "npm:^7.8.3" - "@babel/plugin-transform-parameters": "npm:^7.24.7" + "@babel/plugin-transform-parameters": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/9ad64bc003f583030f9da50614b485852f8edac93f8faf5d1cd855201a4852f37c5255ae4daf70dd4375bdd4874e16e39b91f680d4668ec219ba05441ce286eb + checksum: 10c0/e8b978d9d1020452da0d5d92f80fe57e302761dac20137bb8bf863478a4779fcd63d314db89e796125d9d76da2a38f64f012d6e0c4913815951b3eb3fba2feb6 languageName: node linkType: hard -"@babel/plugin-transform-object-super@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-object-super@npm:7.24.7" +"@babel/plugin-transform-object-super@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-object-super@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/helper-replace-supers": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-replace-supers": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/770cebb4b4e1872c216b17069db9a13b87dfee747d359dc56d9fcdd66e7544f92dc6ab1861a4e7e0528196aaff2444e4f17dc84efd8eaf162d542b4ba0943869 + checksum: 10c0/7f2968d4da997101b63fd3b74445c9b16f56bd32cd8a0a16c368af9d3e983e7675c1b05d18601f32307cb06e7d884ee11d13ff18a1f6830c0db243a9a852afab languageName: node linkType: hard -"@babel/plugin-transform-optional-catch-binding@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.24.7" +"@babel/plugin-transform-optional-catch-binding@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/1e2f10a018f7d03b3bde6c0b70d063df8d5dd5209861d4467726cf834f5e3d354e2276079dc226aa8e6ece35f5c9b264d64b8229a8bb232829c01e561bcfb07a + checksum: 10c0/bb609e5103780be0825a255ffe1fefbb5335aead88a46eecc2257053279ea2c45ff66b0ef1fb54302c8c8c57146e88e52f3ecb62b4c6f619218d7b3843b352d9 languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:^7.24.7, @babel/plugin-transform-optional-chaining@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/plugin-transform-optional-chaining@npm:7.24.8" +"@babel/plugin-transform-optional-chaining@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.7" "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/4ffbe1aad7dec7c9aa2bf6ceb4b2f91f96815b2784f2879bde80e46934f59d64a12cb2c6262e40897c4754d77d2c35d8a5cfed63044fdebf94978b1ed3d14b17 + checksum: 10c0/887441ada6c2bc1b789984b7531d9bc585f335ece99642886d3d9fd8aee7e6b8d4f7ca61d76b5f23477f3aa607284d5056eadaa1eb17e7b39af6b0e834cbe878 languageName: node linkType: hard -"@babel/plugin-transform-parameters@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-parameters@npm:7.24.7" +"@babel/plugin-transform-parameters@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-parameters@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/53bf190d6926771545d5184f1f5f3f5144d0f04f170799ad46a43f683a01fab8d5fe4d2196cf246774530990c31fe1f2b9f0def39f0a5ddbb2340b924f5edf01 + checksum: 10c0/b40ba70278842ce1e800d7ab400df730994941550da547ef453780023bd61a9b8acf4b9fb8419c1b5bcbe09819a1146ff59369db11db07eb71870bef86a12422 languageName: node linkType: hard -"@babel/plugin-transform-private-methods@npm:^7.25.4": - version: 7.25.4 - resolution: "@babel/plugin-transform-private-methods@npm:7.25.4" +"@babel/plugin-transform-private-methods@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-private-methods@npm:7.25.7" dependencies: - "@babel/helper-create-class-features-plugin": "npm:^7.25.4" - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-create-class-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/7abdb427c3984a2c8a2e9d806297d8509b02f78a3501b7760e544be532446e9df328b876daa8fc38718f3dce7ccc45083016ee7aeaab169b81c142bc18700794 + checksum: 10c0/92e076f63f7c4696e1321dafdd56c4212eb41784cdadba0ebc39091f959a76d357c3df61a6c668be81d6b6ad8964ee458e85752ab0c6cfbbaf2066903edda732 languageName: node linkType: hard -"@babel/plugin-transform-private-property-in-object@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-private-property-in-object@npm:7.24.7" +"@babel/plugin-transform-private-property-in-object@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-private-property-in-object@npm:7.25.7" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/helper-create-class-features-plugin": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-annotate-as-pure": "npm:^7.25.7" + "@babel/helper-create-class-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/c6fa7defb90b1b0ed46f24ff94ff2e77f44c1f478d1090e81712f33cf992dda5ba347016f030082a2f770138bac6f4a9c2c1565e9f767a125901c77dd9c239ba + checksum: 10c0/5ad8832ba54e2079c1f558b8680e170265e3f376424e5fbb75b17b7f08696fb0af6c96d23d92f7df3dcc559f5971a02587281fcec38a853174aa95478565f5fc languageName: node linkType: hard -"@babel/plugin-transform-property-literals@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-property-literals@npm:7.24.7" +"@babel/plugin-transform-property-literals@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-property-literals@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/52564b58f3d111dc02d241d5892a4b01512e98dfdf6ef11b0ed62f8b11b0acacccef0fc229b44114fe8d1a57a8b70780b11bdd18b807d3754a781a07d8f57433 + checksum: 10c0/6d5bccdc772207906666ad5201bd91e4e132e1d806dbcf4163a1d08e18c57cc3795578c4e10596514bcd6afaf9696f478ea4f0dea890176d93b9cb077b9e5c55 languageName: node linkType: hard @@ -1116,244 +1116,245 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-display-name@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-react-display-name@npm:7.24.7" +"@babel/plugin-transform-react-display-name@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-react-display-name@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/c14a07a9e75723c96f1a0a306b8a8e899ff1c6a0cc3d62bcda79bb1b54e4319127b258651c513a1a47da152cdc22e16525525a30ae5933a2980c7036fd0b4d24 + checksum: 10c0/a0c537cc7c328ed7468d3b6a37bf0d9cb15d94afcdf3f2849ce6e5a68494fc61f0fa4fc529482a6b95b00f3c5c734f310bf18085293bff40702789f06c816f36 languageName: node linkType: hard "@babel/plugin-transform-react-inline-elements@npm:^7.21.0": - version: 7.24.7 - resolution: "@babel/plugin-transform-react-inline-elements@npm:7.24.7" + version: 7.25.7 + resolution: "@babel/plugin-transform-react-inline-elements@npm:7.25.7" dependencies: - "@babel/helper-builder-react-jsx": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-builder-react-jsx": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/affe44efc641e5dc4de077db74c80e3dee896a5dfea04491cbd8167ac40dcbb6eaa1ad0ba599e4a85071acdaa08732e7f5d9cf3236a2aa635406c232c8f08236 + checksum: 10c0/de85180c09002083cb330ef28d5b31b44e6ac6565c700b603be76e629f5a92c59ff69f79c08cc1dbd2dd1f271f44fe8d4c751deaf66c059ba721aa3cb43c881e languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-development@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-react-jsx-development@npm:7.24.7" +"@babel/plugin-transform-react-jsx-development@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-react-jsx-development@npm:7.25.7" dependencies: - "@babel/plugin-transform-react-jsx": "npm:^7.24.7" + "@babel/plugin-transform-react-jsx": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/fce647db50f90a5291681f0f97865d9dc76981262dff71d6d0332e724b85343de5860c26f9e9a79e448d61e1d70916b07ce91e8c7f2b80dceb4b16aee41794d8 + checksum: 10c0/a3dc14644d09a6d22875af7b5584393ab53e467e0531cd192fc6242504dacaffa421e89265ba7f84fd4edef2b7b100d2e2ebf092a4dce2b55cf9c5fe29390c18 languageName: node linkType: hard -"@babel/plugin-transform-react-jsx@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-react-jsx@npm:7.24.7" +"@babel/plugin-transform-react-jsx@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-react-jsx@npm:7.25.7" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/helper-module-imports": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/plugin-syntax-jsx": "npm:^7.24.7" - "@babel/types": "npm:^7.24.7" + "@babel/helper-annotate-as-pure": "npm:^7.25.7" + "@babel/helper-module-imports": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/plugin-syntax-jsx": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/5c46d2c1c06a30e6bde084839df9cc689bf9c9cb0292105d61c225ca731f64247990724caee7dfc7f817dc964c062e8319e7f05394209590c476b65d75373435 + checksum: 10c0/6766b0357b8bbfcb77fca5350f06cf822c89bbe75ddcaea24614601ef23957504da24e76597d743038ce8fa081373b0663c8ad0c86d7c7226e8185f0680b8b56 languageName: node linkType: hard -"@babel/plugin-transform-react-pure-annotations@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.24.7" +"@babel/plugin-transform-react-pure-annotations@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.25.7" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-annotate-as-pure": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/fae517d293d9c93b7b920458c3e4b91cb0400513889af41ba184a5f3acc8bfef27242cc262741bb8f87870df376f1733a0d0f52b966d342e2aaaf5607af8f73d + checksum: 10c0/d92c9b511850fb6dea71966a0d4f313d67e317db7fc3633a7ff2e27d6df2e95cbc91c4c25abdb6c8db651fcda842a0cb7433835a8a9d4a3fdc5d452068428101 languageName: node linkType: hard -"@babel/plugin-transform-regenerator@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-regenerator@npm:7.24.7" +"@babel/plugin-transform-regenerator@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-regenerator@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" regenerator-transform: "npm:^0.15.2" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/d2dc2c788fdae9d97217e70d46ba8ca9db0035c398dc3e161552b0c437113719a75c04f201f9c91ddc8d28a1da60d0b0853f616dead98a396abb9c845c44892b + checksum: 10c0/7ee3a57c4050bc908ef7ac392d810826b294970a7182f4ec34a8ca93dbe36deb21bc862616d46a6f3d881d6b5749930e1679e875b638a00866d844a4250df212 languageName: node linkType: hard -"@babel/plugin-transform-reserved-words@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-reserved-words@npm:7.24.7" +"@babel/plugin-transform-reserved-words@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-reserved-words@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/2229de2768615e7f5dc0bbc55bc121b5678fd6d2febd46c74a58e42bb894d74cd5955c805880f4e02d0e1cf94f6886270eda7fafc1be9305a1ec3b9fd1d063f5 + checksum: 10c0/920c98130daff6c1288fb13a9a2d2e45863bba93e619cb88d90e1f5b5cb358a3ee8880a425a3adb1b4bd5dbb6bd0500eea3370fc612633045eec851b08cc586c languageName: node linkType: hard "@babel/plugin-transform-runtime@npm:^7.22.4": - version: 7.25.4 - resolution: "@babel/plugin-transform-runtime@npm:7.25.4" + version: 7.25.7 + resolution: "@babel/plugin-transform-runtime@npm:7.25.7" dependencies: - "@babel/helper-module-imports": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-module-imports": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" babel-plugin-polyfill-corejs2: "npm:^0.4.10" babel-plugin-polyfill-corejs3: "npm:^0.10.6" babel-plugin-polyfill-regenerator: "npm:^0.6.1" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/c08698276596d58bf49e222ead3c414c35d099a7e5a6174b11e2db9b74420e94783ada596820437622c3eccc8852c0e750ad053bd8e775f0050839479ba76e6a + checksum: 10c0/9b2514e9079361ac8e7e500ffd522dad869d61a3894302da7e29bbac80de00276c8a1b4394d1dcf0b51c57b2c854919928df9648be336139fdf1d6ecd6d1bb32 languageName: node linkType: hard -"@babel/plugin-transform-shorthand-properties@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-shorthand-properties@npm:7.24.7" +"@babel/plugin-transform-shorthand-properties@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-shorthand-properties@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/41b155bdbb3be66618358488bf7731b3b2e8fff2de3dbfd541847720a9debfcec14db06a117abedd03c9cd786db20a79e2a86509a4f19513f6e1b610520905cf + checksum: 10c0/4250f89a0072f0f400be7a2e3515227b8e2518737899bd57d497e5173284a0e05d812e4a3c219ffcd484e9fa9a01c19fce5acd77bbb898f4d594512c56701eb4 languageName: node linkType: hard -"@babel/plugin-transform-spread@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-spread@npm:7.24.7" +"@babel/plugin-transform-spread@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-spread@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/facba1553035f76b0d2930d4ada89a8cd0f45b79579afd35baefbfaf12e3b86096995f4b0c402cf9ee23b3f2ea0a4460c3b1ec0c192d340962c948bb223d4e66 + checksum: 10c0/258bd1b52388cd7425d0ae25fa39538734f7540ea503a1d8a72211d33f6f214cb4e3b73d6cd03016cbcff5d41169f1e578b9ea331965ad224d223591983e90a7 languageName: node linkType: hard -"@babel/plugin-transform-sticky-regex@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-sticky-regex@npm:7.24.7" +"@babel/plugin-transform-sticky-regex@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-sticky-regex@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/5a74ed2ed0a3ab51c3d15fcaf09d9e2fe915823535c7a4d7b019813177d559b69677090e189ec3d5d08b619483eb5ad371fbcfbbff5ace2a76ba33ee566a1109 + checksum: 10c0/0e466cfc3ca1e0db4bb11eb630215b0e1f43066d7678325e5ddadcf5a118b2351a528f67205729c32ac5b78ab68ab7f40517dd33bcb1fb6b456509f5f54ce097 languageName: node linkType: hard -"@babel/plugin-transform-template-literals@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-template-literals@npm:7.24.7" +"@babel/plugin-transform-template-literals@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-template-literals@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/3630f966257bcace122f04d3157416a09d40768c44c3a800855da81146b009187daa21859d1c3b7d13f4e19e8888e60613964b175b2275d451200fb6d8d6cfe6 + checksum: 10c0/a3455303b6841cb536ac66d1a2d03c194b9f371519482d8d1e8edbd33bf5ca7cdd5db1586b2b0ea5f909ebf74a0eafacf0fb28d257e4905445282dcdccfa6139 languageName: node linkType: hard -"@babel/plugin-transform-typeof-symbol@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/plugin-transform-typeof-symbol@npm:7.24.8" +"@babel/plugin-transform-typeof-symbol@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-typeof-symbol@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/2f570a4fbbdc5fd85f48165a97452826560051e3b8efb48c3bb0a0a33ee8485633439e7b71bfe3ef705583a1df43f854f49125bd759abdedc195b2cf7e60012a + checksum: 10c0/ce1a0744a900b05de1372a70508c4148f17eb941c482da26eb369b9f0347570dce45470c8a86d907bc3a0443190344da1e18489ecfecb30388ab6178e8a9916b languageName: node linkType: hard -"@babel/plugin-transform-typescript@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-typescript@npm:7.24.7" +"@babel/plugin-transform-typescript@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-typescript@npm:7.25.7" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/helper-create-class-features-plugin": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/plugin-syntax-typescript": "npm:^7.24.7" + "@babel/helper-annotate-as-pure": "npm:^7.25.7" + "@babel/helper-create-class-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.7" + "@babel/plugin-syntax-typescript": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/e8dacdc153a4c4599014b66eb01b94e3dc933d58d4f0cc3039c1a8f432e77b9df14f34a61964e014b975bf466f3fefd8c4768b3e887d3da1be9dc942799bdfdf + checksum: 10c0/5fa839b9560221698edff5e00b5cccc658c7875efaa7971c66d478f5b026770f12dd47b1be024463a44f9e29b4e14e8ddddbf4a2b324b0b94f58370dd5ae7195 languageName: node linkType: hard -"@babel/plugin-transform-unicode-escapes@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-unicode-escapes@npm:7.24.7" +"@babel/plugin-transform-unicode-escapes@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-unicode-escapes@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/8b18e2e66af33471a6971289492beff5c240e56727331db1d34c4338a6a368a82a7ed6d57ec911001b6d65643aed76531e1e7cac93265fb3fb2717f54d845e69 + checksum: 10c0/8b1f71fda0a832c6e26ba4c00f99e9033e6f9b36ced542a512921f4ad861a70e2fec2bd54a91a5ca2efa46aaa8c8893e4c602635c4ef172bd3ed6eef3178c70b languageName: node linkType: hard -"@babel/plugin-transform-unicode-property-regex@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.24.7" +"@babel/plugin-transform-unicode-property-regex@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.25.7" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-create-regexp-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/bc57656eb94584d1b74a385d378818ac2b3fca642e3f649fead8da5fb3f9de22f8461185936915dfb33d5a9104e62e7a47828331248b09d28bb2d59e9276de3e + checksum: 10c0/b4bfcf7529138d00671bf5cdfe606603d52cfe57ec1be837da57683f404fc0b0c171834a02515eb03379e5c806121866d097b90e31cb437d21d0ea59368ad82b languageName: node linkType: hard -"@babel/plugin-transform-unicode-regex@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-unicode-regex@npm:7.24.7" +"@babel/plugin-transform-unicode-regex@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-unicode-regex@npm:7.25.7" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-create-regexp-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/83f72a345b751566b601dc4d07e9f2c8f1bc0e0c6f7abb56ceb3095b3c9d304de73f85f2f477a09f8cc7edd5e65afd0ff9e376cdbcbea33bc0c28f3705b38fd9 + checksum: 10c0/73ae34c02ea8b7ac7e4efa690f8c226089c074e3fef658d2a630ad898a93550d84146ce05e073c271c8b2bbba61cbbfd5a2002a7ea940dcad3274e5b5dcb6bcf languageName: node linkType: hard -"@babel/plugin-transform-unicode-sets-regex@npm:^7.25.4": - version: 7.25.4 - resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.25.4" +"@babel/plugin-transform-unicode-sets-regex@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.25.7" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.25.2" - "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-create-regexp-features-plugin": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/f65749835a98d8d6242e961f9276bdcdb09020e791d151ccc145acaca9a66f025b2c7cb761104f139180d35eb066a429596ee6edece81f5fd9244e0edb97d7ec + checksum: 10c0/39e45ae3db7adfc3457b1d6ba5608ffbace957ad019785967e5357a6639f261765bda12363f655d39265f5a2834af26327037751420191d0b73152ccc7ce3c35 languageName: node linkType: hard "@babel/preset-env@npm:^7.11.0, @babel/preset-env@npm:^7.12.1, @babel/preset-env@npm:^7.22.4": - version: 7.25.4 - resolution: "@babel/preset-env@npm:7.25.4" + version: 7.25.7 + resolution: "@babel/preset-env@npm:7.25.7" dependencies: - "@babel/compat-data": "npm:^7.25.4" - "@babel/helper-compilation-targets": "npm:^7.25.2" - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/helper-validator-option": "npm:^7.24.8" - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.25.3" - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "npm:^7.25.0" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.25.0" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.24.7" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.25.0" + "@babel/compat-data": "npm:^7.25.7" + "@babel/helper-compilation-targets": "npm:^7.25.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-validator-option": "npm:^7.25.7" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.25.7" + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "npm:^7.25.7" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.25.7" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.25.7" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.25.7" "@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2" "@babel/plugin-syntax-async-generators": "npm:^7.8.4" "@babel/plugin-syntax-class-properties": "npm:^7.12.13" "@babel/plugin-syntax-class-static-block": "npm:^7.14.5" "@babel/plugin-syntax-dynamic-import": "npm:^7.8.3" "@babel/plugin-syntax-export-namespace-from": "npm:^7.8.3" - "@babel/plugin-syntax-import-assertions": "npm:^7.24.7" - "@babel/plugin-syntax-import-attributes": "npm:^7.24.7" + "@babel/plugin-syntax-import-assertions": "npm:^7.25.7" + "@babel/plugin-syntax-import-attributes": "npm:^7.25.7" "@babel/plugin-syntax-import-meta": "npm:^7.10.4" "@babel/plugin-syntax-json-strings": "npm:^7.8.3" "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.10.4" @@ -1365,64 +1366,64 @@ __metadata: "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5" "@babel/plugin-syntax-top-level-await": "npm:^7.14.5" "@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6" - "@babel/plugin-transform-arrow-functions": "npm:^7.24.7" - "@babel/plugin-transform-async-generator-functions": "npm:^7.25.4" - "@babel/plugin-transform-async-to-generator": "npm:^7.24.7" - "@babel/plugin-transform-block-scoped-functions": "npm:^7.24.7" - "@babel/plugin-transform-block-scoping": "npm:^7.25.0" - "@babel/plugin-transform-class-properties": "npm:^7.25.4" - "@babel/plugin-transform-class-static-block": "npm:^7.24.7" - "@babel/plugin-transform-classes": "npm:^7.25.4" - "@babel/plugin-transform-computed-properties": "npm:^7.24.7" - "@babel/plugin-transform-destructuring": "npm:^7.24.8" - "@babel/plugin-transform-dotall-regex": "npm:^7.24.7" - "@babel/plugin-transform-duplicate-keys": "npm:^7.24.7" - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "npm:^7.25.0" - "@babel/plugin-transform-dynamic-import": "npm:^7.24.7" - "@babel/plugin-transform-exponentiation-operator": "npm:^7.24.7" - "@babel/plugin-transform-export-namespace-from": "npm:^7.24.7" - "@babel/plugin-transform-for-of": "npm:^7.24.7" - "@babel/plugin-transform-function-name": "npm:^7.25.1" - "@babel/plugin-transform-json-strings": "npm:^7.24.7" - "@babel/plugin-transform-literals": "npm:^7.25.2" - "@babel/plugin-transform-logical-assignment-operators": "npm:^7.24.7" - "@babel/plugin-transform-member-expression-literals": "npm:^7.24.7" - "@babel/plugin-transform-modules-amd": "npm:^7.24.7" - "@babel/plugin-transform-modules-commonjs": "npm:^7.24.8" - "@babel/plugin-transform-modules-systemjs": "npm:^7.25.0" - "@babel/plugin-transform-modules-umd": "npm:^7.24.7" - "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.24.7" - "@babel/plugin-transform-new-target": "npm:^7.24.7" - "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.24.7" - "@babel/plugin-transform-numeric-separator": "npm:^7.24.7" - "@babel/plugin-transform-object-rest-spread": "npm:^7.24.7" - "@babel/plugin-transform-object-super": "npm:^7.24.7" - "@babel/plugin-transform-optional-catch-binding": "npm:^7.24.7" - "@babel/plugin-transform-optional-chaining": "npm:^7.24.8" - "@babel/plugin-transform-parameters": "npm:^7.24.7" - "@babel/plugin-transform-private-methods": "npm:^7.25.4" - "@babel/plugin-transform-private-property-in-object": "npm:^7.24.7" - "@babel/plugin-transform-property-literals": "npm:^7.24.7" - "@babel/plugin-transform-regenerator": "npm:^7.24.7" - "@babel/plugin-transform-reserved-words": "npm:^7.24.7" - "@babel/plugin-transform-shorthand-properties": "npm:^7.24.7" - "@babel/plugin-transform-spread": "npm:^7.24.7" - "@babel/plugin-transform-sticky-regex": "npm:^7.24.7" - "@babel/plugin-transform-template-literals": "npm:^7.24.7" - "@babel/plugin-transform-typeof-symbol": "npm:^7.24.8" - "@babel/plugin-transform-unicode-escapes": "npm:^7.24.7" - "@babel/plugin-transform-unicode-property-regex": "npm:^7.24.7" - "@babel/plugin-transform-unicode-regex": "npm:^7.24.7" - "@babel/plugin-transform-unicode-sets-regex": "npm:^7.25.4" + "@babel/plugin-transform-arrow-functions": "npm:^7.25.7" + "@babel/plugin-transform-async-generator-functions": "npm:^7.25.7" + "@babel/plugin-transform-async-to-generator": "npm:^7.25.7" + "@babel/plugin-transform-block-scoped-functions": "npm:^7.25.7" + "@babel/plugin-transform-block-scoping": "npm:^7.25.7" + "@babel/plugin-transform-class-properties": "npm:^7.25.7" + "@babel/plugin-transform-class-static-block": "npm:^7.25.7" + "@babel/plugin-transform-classes": "npm:^7.25.7" + "@babel/plugin-transform-computed-properties": "npm:^7.25.7" + "@babel/plugin-transform-destructuring": "npm:^7.25.7" + "@babel/plugin-transform-dotall-regex": "npm:^7.25.7" + "@babel/plugin-transform-duplicate-keys": "npm:^7.25.7" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "npm:^7.25.7" + "@babel/plugin-transform-dynamic-import": "npm:^7.25.7" + "@babel/plugin-transform-exponentiation-operator": "npm:^7.25.7" + "@babel/plugin-transform-export-namespace-from": "npm:^7.25.7" + "@babel/plugin-transform-for-of": "npm:^7.25.7" + "@babel/plugin-transform-function-name": "npm:^7.25.7" + "@babel/plugin-transform-json-strings": "npm:^7.25.7" + "@babel/plugin-transform-literals": "npm:^7.25.7" + "@babel/plugin-transform-logical-assignment-operators": "npm:^7.25.7" + "@babel/plugin-transform-member-expression-literals": "npm:^7.25.7" + "@babel/plugin-transform-modules-amd": "npm:^7.25.7" + "@babel/plugin-transform-modules-commonjs": "npm:^7.25.7" + "@babel/plugin-transform-modules-systemjs": "npm:^7.25.7" + "@babel/plugin-transform-modules-umd": "npm:^7.25.7" + "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.25.7" + "@babel/plugin-transform-new-target": "npm:^7.25.7" + "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.25.7" + "@babel/plugin-transform-numeric-separator": "npm:^7.25.7" + "@babel/plugin-transform-object-rest-spread": "npm:^7.25.7" + "@babel/plugin-transform-object-super": "npm:^7.25.7" + "@babel/plugin-transform-optional-catch-binding": "npm:^7.25.7" + "@babel/plugin-transform-optional-chaining": "npm:^7.25.7" + "@babel/plugin-transform-parameters": "npm:^7.25.7" + "@babel/plugin-transform-private-methods": "npm:^7.25.7" + "@babel/plugin-transform-private-property-in-object": "npm:^7.25.7" + "@babel/plugin-transform-property-literals": "npm:^7.25.7" + "@babel/plugin-transform-regenerator": "npm:^7.25.7" + "@babel/plugin-transform-reserved-words": "npm:^7.25.7" + "@babel/plugin-transform-shorthand-properties": "npm:^7.25.7" + "@babel/plugin-transform-spread": "npm:^7.25.7" + "@babel/plugin-transform-sticky-regex": "npm:^7.25.7" + "@babel/plugin-transform-template-literals": "npm:^7.25.7" + "@babel/plugin-transform-typeof-symbol": "npm:^7.25.7" + "@babel/plugin-transform-unicode-escapes": "npm:^7.25.7" + "@babel/plugin-transform-unicode-property-regex": "npm:^7.25.7" + "@babel/plugin-transform-unicode-regex": "npm:^7.25.7" + "@babel/plugin-transform-unicode-sets-regex": "npm:^7.25.7" "@babel/preset-modules": "npm:0.1.6-no-external-plugins" babel-plugin-polyfill-corejs2: "npm:^0.4.10" babel-plugin-polyfill-corejs3: "npm:^0.10.6" babel-plugin-polyfill-regenerator: "npm:^0.6.1" - core-js-compat: "npm:^3.37.1" + core-js-compat: "npm:^3.38.1" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/ed210a1974b5a1e7f80a933c87253907ec869457cea900bc97892642fa9a690c47627a9bac08a7c9495deb992a2b15f308ffca2741e1876ba47172c96fa27e14 + checksum: 10c0/bf704a06a69420250c1de2b126cd5c859a851002c2fb2cce0910cd85a8e6755b9b31577021e94feb7e1e53519923726349aaf07580923928791583db61438fb8 languageName: node linkType: hard @@ -1440,40 +1441,33 @@ __metadata: linkType: hard "@babel/preset-react@npm:^7.12.5, @babel/preset-react@npm:^7.22.3": - version: 7.24.7 - resolution: "@babel/preset-react@npm:7.24.7" + version: 7.25.7 + resolution: "@babel/preset-react@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/helper-validator-option": "npm:^7.24.7" - "@babel/plugin-transform-react-display-name": "npm:^7.24.7" - "@babel/plugin-transform-react-jsx": "npm:^7.24.7" - "@babel/plugin-transform-react-jsx-development": "npm:^7.24.7" - "@babel/plugin-transform-react-pure-annotations": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-validator-option": "npm:^7.25.7" + "@babel/plugin-transform-react-display-name": "npm:^7.25.7" + "@babel/plugin-transform-react-jsx": "npm:^7.25.7" + "@babel/plugin-transform-react-jsx-development": "npm:^7.25.7" + "@babel/plugin-transform-react-pure-annotations": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/9658b685b25cedaadd0b65c4e663fbc7f57394b5036ddb4c99b1a75b0711fb83292c1c625d605c05b73413fc7a6dc20e532627f6a39b6dc8d4e00415479b054c + checksum: 10c0/b133b1a2f46c70a337d8b1ef442e09e3dbdaecb0d6bed8f1cb64dfddc31c16e248b017385ab909caeebd8462111c9c0e1c5409deb10f2be5cb5bcfdaa4d27718 languageName: node linkType: hard "@babel/preset-typescript@npm:^7.21.5": - version: 7.24.7 - resolution: "@babel/preset-typescript@npm:7.24.7" + version: 7.25.7 + resolution: "@babel/preset-typescript@npm:7.25.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/helper-validator-option": "npm:^7.24.7" - "@babel/plugin-syntax-jsx": "npm:^7.24.7" - "@babel/plugin-transform-modules-commonjs": "npm:^7.24.7" - "@babel/plugin-transform-typescript": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.25.7" + "@babel/helper-validator-option": "npm:^7.25.7" + "@babel/plugin-syntax-jsx": "npm:^7.25.7" + "@babel/plugin-transform-modules-commonjs": "npm:^7.25.7" + "@babel/plugin-transform-typescript": "npm:^7.25.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/986bc0978eedb4da33aba8e1e13a3426dd1829515313b7e8f4ba5d8c18aff1663b468939d471814e7acf4045d326ae6cff37239878d169ac3fe53a8fde71f8ee - languageName: node - linkType: hard - -"@babel/regjsgen@npm:^0.8.0": - version: 0.8.0 - resolution: "@babel/regjsgen@npm:0.8.0" - checksum: 10c0/4f3ddd8c7c96d447e05c8304c1d5ba3a83fcabd8a716bc1091c2f31595cdd43a3a055fff7cb5d3042b8cb7d402d78820fcb4e05d896c605a7d8bcf30f2424c4a + checksum: 10c0/8dc1258e3c5230bbe42ff9811f08924509238e6bd32fa0b7b0c0a6c5e1419512a8e1f733e1b114454d367b7c164beca2cf33acf2ed9e0d99be010c1c5cdbef0c languageName: node linkType: hard @@ -1487,48 +1481,48 @@ __metadata: linkType: hard "@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.22.3, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": - version: 7.25.6 - resolution: "@babel/runtime@npm:7.25.6" + version: 7.25.7 + resolution: "@babel/runtime@npm:7.25.7" dependencies: regenerator-runtime: "npm:^0.14.0" - checksum: 10c0/d6143adf5aa1ce79ed374e33fdfd74fa975055a80bc6e479672ab1eadc4e4bfd7484444e17dd063a1d180e051f3ec62b357c7a2b817e7657687b47313158c3d2 + checksum: 10c0/86b7829d2fc9343714a9afe92757cf96c4dc799006ca61d73cda62f4b9e29bfa1ce36794955bc6cb4c188f5b10db832c949339895e1bbe81a69022d9d578ce29 languageName: node linkType: hard -"@babel/template@npm:^7.24.7, @babel/template@npm:^7.25.0, @babel/template@npm:^7.3.3": - version: 7.25.0 - resolution: "@babel/template@npm:7.25.0" +"@babel/template@npm:^7.25.7, @babel/template@npm:^7.3.3": + version: 7.25.7 + resolution: "@babel/template@npm:7.25.7" dependencies: - "@babel/code-frame": "npm:^7.24.7" - "@babel/parser": "npm:^7.25.0" - "@babel/types": "npm:^7.25.0" - checksum: 10c0/4e31afd873215744c016e02b04f43b9fa23205d6d0766fb2e93eb4091c60c1b88897936adb895fb04e3c23de98dfdcbe31bc98daaa1a4e0133f78bb948e1209b + "@babel/code-frame": "npm:^7.25.7" + "@babel/parser": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/8ae9e36e4330ee83d4832531d1d9bec7dc2ef6a2a8afa1ef1229506fd60667abcb17f306d1c3d7e582251270597022990c845d5d69e7add70a5aea66720decb9 languageName: node linkType: hard -"@babel/traverse@npm:7, @babel/traverse@npm:^7.24.7, @babel/traverse@npm:^7.24.8, @babel/traverse@npm:^7.25.0, @babel/traverse@npm:^7.25.1, @babel/traverse@npm:^7.25.2, @babel/traverse@npm:^7.25.3, @babel/traverse@npm:^7.25.4": - version: 7.25.4 - resolution: "@babel/traverse@npm:7.25.4" +"@babel/traverse@npm:7, @babel/traverse@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/traverse@npm:7.25.7" dependencies: - "@babel/code-frame": "npm:^7.24.7" - "@babel/generator": "npm:^7.25.4" - "@babel/parser": "npm:^7.25.4" - "@babel/template": "npm:^7.25.0" - "@babel/types": "npm:^7.25.4" + "@babel/code-frame": "npm:^7.25.7" + "@babel/generator": "npm:^7.25.7" + "@babel/parser": "npm:^7.25.7" + "@babel/template": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" debug: "npm:^4.3.1" globals: "npm:^11.1.0" - checksum: 10c0/37c9b49b277e051fe499ef5f6f217370c4f648d6370564d70b5e6beb2da75bfda6d7dab1d39504d89e9245448f8959bc1a5880d2238840cdc3979b35338ed0f5 + checksum: 10c0/75d73e52c507a7a7a4c7971d6bf4f8f26fdd094e0d3a0193d77edf6a5efa36fc3db91ec5cc48e8b94e6eb5d5ad21af0a1040e71309172851209415fd105efb1a languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.0.0-beta.49, @babel/types@npm:^7.12.11, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.24.7, @babel/types@npm:^7.24.8, @babel/types@npm:^7.25.0, @babel/types@npm:^7.25.2, @babel/types@npm:^7.25.4, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": - version: 7.25.4 - resolution: "@babel/types@npm:7.25.4" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.0.0-beta.49, @babel/types@npm:^7.12.11, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.25.7, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": + version: 7.25.7 + resolution: "@babel/types@npm:7.25.7" dependencies: - "@babel/helper-string-parser": "npm:^7.24.8" - "@babel/helper-validator-identifier": "npm:^7.24.7" + "@babel/helper-string-parser": "npm:^7.25.7" + "@babel/helper-validator-identifier": "npm:^7.25.7" to-fast-properties: "npm:^2.0.0" - checksum: 10c0/9aa25dfcd89cc4e4dde3188091c34398a005a49e2c2b069d0367b41e1122c91e80fd92998c52a90f2fb500f7e897b6090ec8be263d9cb53d0d75c756f44419f2 + checksum: 10c0/e03e1e2e08600fa1e8eb90632ac9c253dd748176c8d670d85f85b0dc83a0573b26ae748a1cbcb81f401903a3d95f43c3f4f8d516a5ed779929db27de56289633 languageName: node linkType: hard @@ -5687,17 +5681,17 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.0.0, browserslist@npm:^4.23.0, browserslist@npm:^4.23.1, browserslist@npm:^4.23.3": - version: 4.23.3 - resolution: "browserslist@npm:4.23.3" +"browserslist@npm:^4.0.0, browserslist@npm:^4.23.0, browserslist@npm:^4.23.1, browserslist@npm:^4.23.3, browserslist@npm:^4.24.0": + version: 4.24.0 + resolution: "browserslist@npm:4.24.0" dependencies: - caniuse-lite: "npm:^1.0.30001646" - electron-to-chromium: "npm:^1.5.4" + caniuse-lite: "npm:^1.0.30001663" + electron-to-chromium: "npm:^1.5.28" node-releases: "npm:^2.0.18" update-browserslist-db: "npm:^1.1.0" bin: browserslist: cli.js - checksum: 10c0/3063bfdf812815346447f4796c8f04601bf5d62003374305fd323c2a463e42776475bcc5309264e39bcf9a8605851e53560695991a623be988138b3ff8c66642 + checksum: 10c0/95e76ad522753c4c470427f6e3c8a4bb5478ff448841e22b3d3e53f89ecaf17b6984666d6c7e715c370f1e7fa0cf684f42e34e554236a8b2fab38ea76b9e4c52 languageName: node linkType: hard @@ -5899,10 +5893,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001599, caniuse-lite@npm:^1.0.30001646": - version: 1.0.30001651 - resolution: "caniuse-lite@npm:1.0.30001651" - checksum: 10c0/7821278952a6dbd17358e5d08083d258f092e2a530f5bc1840657cb140fbbc5ec44293bc888258c44a18a9570cde149ed05819ac8320b9710cf22f699891e6ad +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001599, caniuse-lite@npm:^1.0.30001663": + version: 1.0.30001666 + resolution: "caniuse-lite@npm:1.0.30001666" + checksum: 10c0/2d49e9be676233c24717f12aad3d01b3e5f902b457fe1deefaa8d82e64786788a8f79381ae437c61b50e15c9aea8aeb59871b1d54cb4c28b9190d53d292e2339 languageName: node linkType: hard @@ -6412,7 +6406,7 @@ __metadata: languageName: node linkType: hard -"core-js-compat@npm:^3.37.1, core-js-compat@npm:^3.38.0": +"core-js-compat@npm:^3.38.0, core-js-compat@npm:^3.38.1": version: 3.38.1 resolution: "core-js-compat@npm:3.38.1" dependencies: @@ -7474,10 +7468,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.5.4": - version: 1.5.7 - resolution: "electron-to-chromium@npm:1.5.7" - checksum: 10c0/be4460bbe3d2186a16d53a03da67fde6fd06ad41943553ce517a45d52e03424732a982f75528e8a2d5fb042d6afde64186aa482caec0fb925daa5a74cf5ef060 +"electron-to-chromium@npm:^1.5.28": + version: 1.5.31 + resolution: "electron-to-chromium@npm:1.5.31" + checksum: 10c0/e8aecd88c4c6d50a9d459b4b222865b855bab8f1b52e82913804e18b7884f2887bd76c61b3aa08c2ccbdcda098dd8486443f75bf770f0138f21dd9e63548fca7 languageName: node linkType: hard @@ -11190,21 +11184,12 @@ __metadata: languageName: node linkType: hard -"jsesc@npm:^2.5.1": - version: 2.5.2 - resolution: "jsesc@npm:2.5.2" +"jsesc@npm:^3.0.2, jsesc@npm:~3.0.2": + version: 3.0.2 + resolution: "jsesc@npm:3.0.2" bin: jsesc: bin/jsesc - checksum: 10c0/dbf59312e0ebf2b4405ef413ec2b25abb5f8f4d9bc5fb8d9f90381622ebca5f2af6a6aa9a8578f65903f9e33990a6dc798edd0ce5586894bf0e9e31803a1de88 - languageName: node - linkType: hard - -"jsesc@npm:~0.5.0": - version: 0.5.0 - resolution: "jsesc@npm:0.5.0" - bin: - jsesc: bin/jsesc - checksum: 10c0/f93792440ae1d80f091b65f8ceddf8e55c4bb7f1a09dee5dcbdb0db5612c55c0f6045625aa6b7e8edb2e0a4feabd80ee48616dbe2d37055573a84db3d24f96d9 + checksum: 10c0/ef22148f9e793180b14d8a145ee6f9f60f301abf443288117b4b6c53d0ecd58354898dc506ccbb553a5f7827965cd38bc5fb726575aae93c5e8915e2de8290e1 languageName: node linkType: hard @@ -15042,12 +15027,12 @@ __metadata: languageName: node linkType: hard -"regenerate-unicode-properties@npm:^10.1.0": - version: 10.1.1 - resolution: "regenerate-unicode-properties@npm:10.1.1" +"regenerate-unicode-properties@npm:^10.2.0": + version: 10.2.0 + resolution: "regenerate-unicode-properties@npm:10.2.0" dependencies: regenerate: "npm:^1.4.2" - checksum: 10c0/89adb5ee5ba081380c78f9057c02e156a8181969f6fcca72451efc45612e0c3df767b4333f8d8479c274d9c6fe52ec4854f0d8a22ef95dccbe87da8e5f2ac77d + checksum: 10c0/5510785eeaf56bbfdf4e663d6753f125c08d2a372d4107bc1b756b7bf142e2ed80c2733a8b54e68fb309ba37690e66a0362699b0e21d5c1f0255dea1b00e6460 languageName: node linkType: hard @@ -15110,28 +15095,35 @@ __metadata: languageName: node linkType: hard -"regexpu-core@npm:^5.3.1": - version: 5.3.2 - resolution: "regexpu-core@npm:5.3.2" +"regexpu-core@npm:^6.1.1": + version: 6.1.1 + resolution: "regexpu-core@npm:6.1.1" dependencies: - "@babel/regjsgen": "npm:^0.8.0" regenerate: "npm:^1.4.2" - regenerate-unicode-properties: "npm:^10.1.0" - regjsparser: "npm:^0.9.1" + regenerate-unicode-properties: "npm:^10.2.0" + regjsgen: "npm:^0.8.0" + regjsparser: "npm:^0.11.0" unicode-match-property-ecmascript: "npm:^2.0.0" unicode-match-property-value-ecmascript: "npm:^2.1.0" - checksum: 10c0/7945d5ab10c8bbed3ca383d4274687ea825aee4ab93a9c51c6e31e1365edd5ea807f6908f800ba017b66c462944ba68011164e7055207747ab651f8111ef3770 + checksum: 10c0/07d49697e20f9b65977535abba4858b7f5171c13f7c366be53ec1886d3d5f69f1b98cc6a6e63cf271adda077c3366a4c851c7473c28bbd69cf5a6b6b008efc3e languageName: node linkType: hard -"regjsparser@npm:^0.9.1": - version: 0.9.1 - resolution: "regjsparser@npm:0.9.1" +"regjsgen@npm:^0.8.0": + version: 0.8.0 + resolution: "regjsgen@npm:0.8.0" + checksum: 10c0/44f526c4fdbf0b29286101a282189e4dbb303f4013cf3fea058668d96d113b9180d3d03d1e13f6d4cbde38b7728bf951aecd9dc199938c080093a9a6f0d7a6bd + languageName: node + linkType: hard + +"regjsparser@npm:^0.11.0": + version: 0.11.0 + resolution: "regjsparser@npm:0.11.0" dependencies: - jsesc: "npm:~0.5.0" + jsesc: "npm:~3.0.2" bin: regjsparser: bin/parser - checksum: 10c0/fe44fcf19a99fe4f92809b0b6179530e5ef313ff7f87df143b08ce9a2eb3c4b6189b43735d645be6e8f4033bfb015ed1ca54f0583bc7561bed53fd379feb8225 + checksum: 10c0/155143a8f2c95e3170df4fff10ddf3f16a351b5d2b8cbb257e9f4a50abb9a980a28af0936b5bf850fee767537ffa8eb77c6b211fe8be19834dbe584dfd950c62 languageName: node linkType: hard From fe3f5375e3c0a2f138558947db69267813c0e726 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Oct 2024 11:15:31 +0200 Subject: [PATCH 058/150] New Crowdin Translations (automated) (#32233) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/de.json | 4 +- app/javascript/mastodon/locales/nl.json | 10 +- app/javascript/mastodon/locales/sc.json | 124 ++++++++++++++++++++++++ app/javascript/mastodon/locales/tr.json | 4 +- app/javascript/mastodon/locales/uk.json | 5 + config/locales/de.yml | 2 +- config/locales/sc.yml | 43 ++++++++ config/locales/tr.yml | 2 +- 8 files changed, 183 insertions(+), 11 deletions(-) diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 6f45d4fe53..0b541b2e48 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -41,7 +41,7 @@ "account.go_to_profile": "Profil aufrufen", "account.hide_reblogs": "Geteilte Beiträge von @{name} ausblenden", "account.in_memoriam": "Zum Andenken.", - "account.joined_short": "Beigetreten", + "account.joined_short": "Mitglied seit", "account.languages": "Ausgewählte Sprachen ändern", "account.link_verified_on": "Das Profil mit dieser E-Mail-Adresse wurde bereits am {date} bestätigt", "account.locked_info": "Die Privatsphäre dieses Kontos wurde auf „geschützt“ gesetzt. Die Person bestimmt manuell, wer ihrem Profil folgen darf.", @@ -534,7 +534,7 @@ "notification.relationships_severance_event.domain_block": "Ein Admin von {from} hat {target} blockiert – darunter {followersCount} deiner Follower und {followingCount, plural, one {# Konto, dem} other {# Konten, denen}} du folgst.", "notification.relationships_severance_event.learn_more": "Mehr erfahren", "notification.relationships_severance_event.user_domain_block": "Du hast {target} blockiert – {followersCount} deiner Follower und {followingCount, plural, one {# Konto, dem} other {# Konten, denen}} du folgst, wurden entfernt.", - "notification.status": "{name} hat gerade etwas gepostet", + "notification.status": "{name} veröffentlichte gerade", "notification.update": "{name} bearbeitete einen Beitrag", "notification_requests.accept": "Genehmigen", "notification_requests.accept_multiple": "{count, plural, one {# Anfrage genehmigen …} other {# Anfragen genehmigen …}}", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index 1c31574dea..71523b37d8 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -504,13 +504,13 @@ "notification.admin.report_statuses": "{name} rapporteerde {target} voor {category}", "notification.admin.report_statuses_other": "{name} rapporteerde {target}", "notification.admin.sign_up": "{name} heeft zich geregistreerd", - "notification.admin.sign_up.name_and_others": "{name} en {count, plural, one {# ander} other {# anderen}} hebben zich geregistreerd", + "notification.admin.sign_up.name_and_others": "{name} en {count, plural, one {# ander persoon} other {# andere personen}} hebben zich geregistreerd", "notification.favourite": "{name} markeerde jouw bericht als favoriet", - "notification.favourite.name_and_others_with_link": "{name} en {count, plural, one {# ander} other {# anderen}} hebben jouw bericht als favoriet gemarkeerd", + "notification.favourite.name_and_others_with_link": "{name} en {count, plural, one {# ander persoon} other {# andere personen}} hebben jouw bericht als favoriet gemarkeerd", "notification.follow": "{name} volgt jou nu", - "notification.follow.name_and_others": "{name} en {count, plural, one {# ander} other {# anderen}} hebben je gevolgd", + "notification.follow.name_and_others": "{name} en {count, plural, one {# ander persoon} other {# andere personen}} hebben je gevolgd", "notification.follow_request": "{name} wil jou graag volgen", - "notification.follow_request.name_and_others": "{name} en {count, plural, one {# ander} other {# anderen}} hebben gevraagd om je te volgen", + "notification.follow_request.name_and_others": "{name} en {count, plural, one {# ander persoon} other {# andere personen}} hebben gevraagd om je te volgen", "notification.label.mention": "Vermelding", "notification.label.private_mention": "Privébericht", "notification.label.private_reply": "Privéreactie", @@ -528,7 +528,7 @@ "notification.own_poll": "Jouw peiling is beëindigd", "notification.poll": "Een peiling waaraan jij hebt meegedaan is beëindigd", "notification.reblog": "{name} boostte jouw bericht", - "notification.reblog.name_and_others_with_link": "{name} en {count, plural, one {# ander} other {# anderen}} hebben jouw bericht geboost", + "notification.reblog.name_and_others_with_link": "{name} en {count, plural, one {# ander persoon} other {# andere personen}} hebben jouw bericht geboost", "notification.relationships_severance_event": "Verloren verbindingen met {name}", "notification.relationships_severance_event.account_suspension": "Een beheerder van {from} heeft {target} geschorst, wat betekent dat je geen updates meer van hen kunt ontvangen of met hen kunt communiceren.", "notification.relationships_severance_event.domain_block": "Een beheerder van {from} heeft {target} geblokkeerd, inclusief {followersCount} van jouw volgers en {followingCount, plural, one {# account} other {# accounts}} die jij volgt.", diff --git a/app/javascript/mastodon/locales/sc.json b/app/javascript/mastodon/locales/sc.json index bb7d062b95..227a7483a7 100644 --- a/app/javascript/mastodon/locales/sc.json +++ b/app/javascript/mastodon/locales/sc.json @@ -85,6 +85,7 @@ "alert.rate_limited.title": "Màssimu de rechestas barigadu", "alert.unexpected.message": "Ddoe est istada una faddina.", "alert.unexpected.title": "Oh!", + "alt_text_badge.title": "Testu alternativu", "announcement.announcement": "Annùntziu", "attachments_list.unprocessed": "(non protzessadu)", "audio.hide": "Cua s'àudio", @@ -97,6 +98,8 @@ "block_modal.title": "Boles blocare s'utente?", "block_modal.you_wont_see_mentions": "No as a bìdere is publicatziones chi mèntovent custa persone.", "boost_modal.combo": "Podes incarcare {combo} pro brincare custu sa borta chi benit", + "boost_modal.reblog": "Boles potentziare sa publicatzione?", + "boost_modal.undo_reblog": "Boles tzessare de potentziare sa publicatzione?", "bundle_column_error.copy_stacktrace": "Còpia s'informe de faddina", "bundle_column_error.error.body": "Sa pàgina pedida non faghiat a dda renderizare. Diat pòdere èssere pro neghe de una faddina in su còdighe nostru, o de unu problema de cumpatibilidade de su navigadore.", "bundle_column_error.error.title": "Oh, no!", @@ -104,11 +107,15 @@ "bundle_column_error.network.title": "Faddina de connessione", "bundle_column_error.retry": "Torra·bi a proare", "bundle_column_error.return": "Torra a sa pàgina printzipale", + "bundle_column_error.routing.body": "Impossìbile agatare sa pàgina rechesta. Seguru chi s'URL in sa barra de indiritzos est curretu?", "bundle_column_error.routing.title": "404", "bundle_modal_error.close": "Serra", "bundle_modal_error.message": "Faddina in su carrigamentu de custu cumponente.", "bundle_modal_error.retry": "Torra·bi a proare", + "closed_registrations.other_server_instructions": "Dae chi Mastodon est detzentralizadu, podes creare unu contu in un'àteru serbidore e interagire cun custu.", + "closed_registrations_modal.description": "Sa creatzione de contos in {domain} no est possìbile in custu momentu, però tene in cunsideru chi non tenes bisòngiu de unu contu ispetzìficu in {domain} pro impreare Mastodon.", "closed_registrations_modal.find_another_server": "Agata un'àteru serbidore", + "closed_registrations_modal.title": "Su registru a Mastodon", "column.about": "Informatziones", "column.blocks": "Persones blocadas", "column.bookmarks": "Sinnalibros", @@ -142,6 +149,7 @@ "compose.published.open": "Aberi", "compose.saved.body": "Publicatzione sarvada.", "compose_form.direct_message_warning_learn_more": "Àteras informatziones", + "compose_form.encryption_warning": "Is publicatziones a Mastodon no sunt critografados a nodu terminale. Non cumpartzas informatziones delicadas in Mastodon.", "compose_form.hashtag_warning": "Custa publicatzione no at a èssere ammustrada in peruna eticheta, dae chi no est pùblica. Isceti is publicatziones pùblicas podent èssere chircadas cun etichetas.", "compose_form.lock_disclaimer": "Su contu tuo no est {locked}. Cale si siat persone ti podet sighire pro bìdere is messàgios tuos chi imbies a sa gente chi ti sighit.", "compose_form.lock_disclaimer.lock": "blocadu", @@ -171,15 +179,23 @@ "confirmations.discard_edit_media.confirm": "Iscarta", "confirmations.discard_edit_media.message": "Tenes modìficas non sarvadas a is descritziones o a is anteprimas de is cuntenutos, ddas boles iscartare su matessi?", "confirmations.edit.confirm": "Modìfica", + "confirmations.edit.message": "Modifichende immoe as a subrascrìere su messàgiu chi ses iscriende. Seguru chi boles sighire?", + "confirmations.edit.title": "Boles subraiscrìere sa publicatzione?", "confirmations.logout.confirm": "Essi·nche", "confirmations.logout.message": "Seguru chi boles essire?", + "confirmations.logout.title": "Boles serrare sa sessione?", "confirmations.mute.confirm": "A sa muda", "confirmations.redraft.confirm": "Cantzella e torra a fàghere", "confirmations.redraft.message": "Seguru chi boles cantzellare e torrare a fàghere custa publicatzione? As a pèrdere is preferidos e is cumpartziduras, e is rispostas a su messàgiu originale ant a abarrare òrfanas.", + "confirmations.redraft.title": "Boles cantzellare e torrare a iscrìere sa publicatzione?", "confirmations.reply.confirm": "Risponde", "confirmations.reply.message": "Rispondende immoe as a subrascrìere su messàgiu chi ses iscriende. Seguru chi boles sighire?", + "confirmations.reply.title": "Boles subraiscrìere sa publicatzione?", "confirmations.unfollow.confirm": "Non sigas prus", "confirmations.unfollow.message": "Seguru chi non boles sighire prus a {name}?", + "confirmations.unfollow.title": "Boles tzessare de sighire s'utente?", + "content_warning.hide": "Cua sa publicatzione", + "content_warning.show": "Ammustra·dda su pròpiu", "conversation.delete": "Cantzella arresonada", "conversation.mark_as_read": "Signala comente lèghidu", "conversation.open": "Ammustra arresonada", @@ -193,7 +209,10 @@ "directory.recently_active": "Cun atividade dae pagu", "disabled_account_banner.account_settings": "Cunfiguratziones de su contu", "disabled_account_banner.text": "Su contu tuo {disabledAccount} no est ativu.", + "dismissable_banner.community_timeline": "Custas sunt is publicatziones pùblicas prus reghentes dae gente cun contu in {domain}.", "dismissable_banner.dismiss": "Iscarta", + "dismissable_banner.explore_links": "Custas sunt is istòrias de noas prus cumpartzidas in sa rete oe. Is istòrias prus noas publicadas dae gente prus diversa ant a èssere priorizadas.", + "dismissable_banner.explore_statuses": "Custas sunt publicatziones dae sa rete detzentralizada chi sunt retzende atentzione oe. Is publicatziones prus noas cun prus cumpartziduras e preferèntzias ant a èssere priorizadas.", "domain_block_modal.block": "Bloca su serbidore", "domain_block_modal.block_account_instead": "Bloca imbetzes a @{name}", "domain_block_modal.they_can_interact_with_old_posts": "Is persones de custu serbidore podent ancora interagire cun is publicatziones betzas tuas.", @@ -207,6 +226,7 @@ "domain_pill.their_handle": "S'identificadore suo:", "domain_pill.their_server": "Sa domo digitale sua, in ue istant totu is publicatziones suas.", "domain_pill.username": "Nòmine de utente", + "domain_pill.whats_in_a_handle": "Ite est un'identificadore?", "domain_pill.your_handle": "S'identificadore tuo:", "domain_pill.your_server": "Sa domo digitale tua, in ue istant totu is publicatziones tuas. Custa non t'agradat? Tràmuda serbidore in cale si siat momentu e bati·ti fintzas in fatu is sighidores tuos.", "domain_pill.your_username": "S'identificadore ùnicu tuo in custu serbidore. Si podent agatare utentes cun su matessi nòmine de utente in àteros serbidores.", @@ -254,6 +274,7 @@ "explore.trending_links": "Noas", "explore.trending_statuses": "Publicatziones", "explore.trending_tags": "Etichetas", + "filter_modal.added.context_mismatch_title": "Su cuntestu non currispondet.", "filter_modal.added.expired_title": "Filtru iscadidu.", "filter_modal.added.review_and_configure_title": "Cunfiguratziones de filtru", "filter_modal.added.settings_link": "pàgina de cunfiguratzione", @@ -277,7 +298,13 @@ "follow_suggestions.featured_longer": "Seberadu a manu dae s'iscuadra de {domain}", "follow_suggestions.friends_of_friends_longer": "Populare intre persones chi sighis", "follow_suggestions.hints.featured": "Custu profilu est istadu seberadu a manu dae s'iscuadra {domain}.", + "follow_suggestions.personalized_suggestion": "Cussìgiu personalizadu", + "follow_suggestions.popular_suggestion": "Cussìgiu populare", + "follow_suggestions.popular_suggestion_longer": "Populare a {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Profilos sìmiles a is chi as sighidu de reghente", "follow_suggestions.view_all": "Ammustra totu", + "follow_suggestions.who_to_follow": "Chie sighire", + "followed_tags": "Etichetas sighidas", "footer.about": "Informatziones", "footer.directory": "Diretòriu de profilos", "footer.get_app": "Otene s'aplicatzione", @@ -302,6 +329,11 @@ "hashtag.counter_by_uses_today": "{count, plural, one {{counter} publicatzione} other {{counter} publicatziones}} oe", "hashtag.follow": "Sighi su hashtag", "hashtag.unfollow": "Non sigas prus s'eticheta", + "hashtags.and_other": "… e {count, plural, one {un'àteru} other {àteros #}}", + "hints.profiles.posts_may_be_missing": "Podet èssere chi ammanchent tzertas publicatziones de custu profilu.", + "hints.profiles.see_more_posts": "Bide prus publicatziones a {domain}", + "hints.threads.replies_may_be_missing": "Podet èssere chi ammanchent rispostas dae àteros serbidores.", + "hints.threads.see_more": "Bide prus rispostas a {domain}", "home.column_settings.show_reblogs": "Ammustra is cumpartziduras", "home.column_settings.show_replies": "Ammustra rispostas", "home.hide_announcements": "Cua annùntzios", @@ -309,7 +341,14 @@ "home.pending_critical_update.link": "Ammustra is atualizatziones", "home.pending_critical_update.title": "Atualizatzione de seguresa crìtica a disponimentu.", "home.show_announcements": "Ammustra annùntzios", + "ignore_notifications_modal.disclaimer": "Mastodon non podet informare is utentes chi as innioradu is notìficas issoro. Inniorare notìficas no at a evitare chi s'imbient is messàgios.", + "ignore_notifications_modal.filter_instead": "Opuru filtra", + "ignore_notifications_modal.filter_to_act_users": "As a pòdere ancora atzetare, refudare o sinnalare a utentes", + "ignore_notifications_modal.filter_to_avoid_confusion": "Filtrare agiudat a evitare possìbiles confusiones", "interaction_modal.description.reply": "Podes rispòndere a custa publicatzione cun unu contu de Mastodon.", + "interaction_modal.login.action": "Torra a sa pàgina printzipale", + "interaction_modal.login.prompt": "Su domìniu de su serbidore domèsticu tuo, pro esempru mastodon.social", + "interaction_modal.no_account_yet": "Non ses in Mastodon?", "interaction_modal.on_this_server": "In custu serbidore", "interaction_modal.title.follow": "Sighi a {name}", "interaction_modal.title.reply": "Risponde a sa publicatzione de {name}", @@ -353,11 +392,13 @@ "lightbox.next": "Imbeniente", "lightbox.previous": "Pretzedente", "limited_account_hint.title": "Custu profilu est istadu cuadu dae sa moderatzione de {domain}.", + "link_preview.shares": "{count, plural, one {{counter} publicatzione} other {{counter} publicatziones}}", "lists.account.add": "Agiunghe a sa lista", "lists.account.remove": "Boga dae sa lista", "lists.delete": "Cantzella sa lista", "lists.edit": "Modìfica sa lista", "lists.edit.submit": "Muda su tìtulu", + "lists.exclusive": "Cua custas publicatziones dae sa pàgina printzipale", "lists.new.create": "Agiunghe lista", "lists.new.title_placeholder": "Tìtulu de sa lista noa", "lists.replies_policy.followed": "Cale si siat persone chi sighis", @@ -368,7 +409,20 @@ "lists.subheading": "Is listas tuas", "load_pending": "{count, plural, one {# elementu nou} other {# elementos noos}}", "loading_indicator.label": "Carrighende…", + "media_gallery.hide": "Cua", + "moved_to_account_banner.text": "Su contu tuo {disabledAccount} est disativadu in custu momentu ca est istadu tramudadu a {movedToAccount}.", + "mute_modal.hide_from_notifications": "Cua dae is notìficas", + "mute_modal.hide_options": "Cua is optziones", + "mute_modal.indefinite": "Fintzas a cando no apo a torrare a ativare is notìficas", + "mute_modal.show_options": "Ammustra is optziones", + "mute_modal.they_can_mention_and_follow": "Ti podent mentovare e sighire, però no ddos as a bìdere.", + "mute_modal.they_wont_know": "No ant a ischire chi ddos as postu a sa muda.", + "mute_modal.title": "Boles pònnere a custu contu a sa muda?", + "mute_modal.you_wont_see_mentions": "No as a bìdere is publicatziones chi mèntovent a custa persone.", + "mute_modal.you_wont_see_posts": "At a pòdere bìdere is publicatziones tuas, però tue no as a bìdere cussas suas.", "navigation_bar.about": "Informatziones", + "navigation_bar.administration": "Amministratzione", + "navigation_bar.advanced_interface": "Aberi s'interfache web avantzada", "navigation_bar.blocks": "Persones blocadas", "navigation_bar.bookmarks": "Sinnalibros", "navigation_bar.community_timeline": "Lìnia de tempus locale", @@ -380,10 +434,13 @@ "navigation_bar.favourites": "Preferidos", "navigation_bar.filters": "Faeddos a sa muda", "navigation_bar.follow_requests": "Rechestas de sighidura", + "navigation_bar.followed_tags": "Etichetas sighidas", "navigation_bar.follows_and_followers": "Gente chi sighis e sighiduras", "navigation_bar.lists": "Listas", "navigation_bar.logout": "Essi", + "navigation_bar.moderation": "Moderatzione", "navigation_bar.mutes": "Persones a sa muda", + "navigation_bar.opened_in_classic_interface": "Publicatziones, contos e àteras pàginas ispetzìficas sunt abertas in manera predefinida in s'interfache web clàssica.", "navigation_bar.personal": "Informatziones personales", "navigation_bar.pins": "Publicatziones apicadas", "navigation_bar.preferences": "Preferèntzias", @@ -391,10 +448,24 @@ "navigation_bar.search": "Chirca", "navigation_bar.security": "Seguresa", "not_signed_in_indicator.not_signed_in": "Ti depes identificare pro atzèdere a custa resursa.", + "notification.admin.report": "{name} at sinnaladu a {target}", + "notification.admin.report_account": "{name} at sinnaladu {count, plural, one {una publicatzione} other {# publicatziones}} dae {target} pro {category}", + "notification.admin.report_account_other": "{name} at sinnaladu {count, plural, one {una publicatzione} other {# publicatziones}} dae {target}", + "notification.admin.report_statuses": "{name} at sinnaladu a {target} pro {category}", + "notification.admin.report_statuses_other": "{name} at sinnaladu a {target}", "notification.admin.sign_up": "{name} at aderidu", + "notification.admin.sign_up.name_and_others": "{name} e {count, plural, one {un'àtera persone} other {àteras # persones}} si sunt registradas", "notification.favourite": "{name} at marcadu comente a preferidu s'istadu tuo", + "notification.favourite.name_and_others_with_link": "{name} e {count, plural, one {un'àtera persone} other {àteras # persones}} ant marcadu sa publicatzione tua comente preferida", "notification.follow": "{name} ti sighit", + "notification.follow.name_and_others": "{name} e {count, plural, one {un'àtera persone} other {àteras # persones}} ti sighint", "notification.follow_request": "{name} at dimandadu de ti sighire", + "notification.follow_request.name_and_others": "{name} e {count, plural, one {un'àtera persone} other {àteras # persones}} ant pedidu de ti sighire", + "notification.label.mention": "Mèntovu", + "notification.label.private_mention": "Mèntovu privadu", + "notification.label.private_reply": "Risposta privada", + "notification.label.reply": "Risposta", + "notification.mention": "Mèntovu", "notification.moderation-warning.learn_more": "Àteras informatziones", "notification.moderation_warning": "T'ant imbiadu un'avisu de moderatzione", "notification.moderation_warning.action_delete_statuses": "Unas cantas de is publicatziones tuas sunt istadas cantzelladas.", @@ -407,12 +478,30 @@ "notification.own_poll": "Sondàgiu acabbadu", "notification.poll": "Unu sondàgiu in su chi as votadu est acabbadu", "notification.reblog": "{name} at cumpartzidu sa publicatzione tua", + "notification.reblog.name_and_others_with_link": "{name} e {count, plural, one {un'àtera persone} other {àteras # persones}} ant potentziadu sa publicatzione tua", "notification.relationships_severance_event": "Connessiones pèrdidas cun {name}", + "notification.relationships_severance_event.account_suspension": "S'amministratzione de {from} at suspèndidu a {target}; custu bolet nàrrere chi non podes prus retzire atualizatziones dae in cue o interagire cun cussos contos.", + "notification.relationships_severance_event.domain_block": "S'amministratzione de {from} at blocadu a {target}, incluende {followersCount} sighiduras tuas e {followingCount, plural, one {un'àteru contu} other {àteros # contos}} chi sighis.", "notification.relationships_severance_event.learn_more": "Àteras informatziones", + "notification.relationships_severance_event.user_domain_block": "As blocadu a {target}, bogadu a {followersCount} contos chi ti sighint e {followingCount, plural, one {un'àteru contu} other {àteros # contos}} chi sighis.", "notification.status": "{name} at publicadu cosa", "notification.update": "{name} at modificadu una publicatzione", "notification_requests.accept": "Atzeta", + "notification_requests.accept_multiple": "{count, plural, one {Atzeta una rechesta…} other {Atzeta # rechestas…}}", + "notification_requests.confirm_accept_multiple.button": "{count, plural, one {Atzeta sa rechesta} other {Atzeta is rechestas}}", + "notification_requests.confirm_accept_multiple.message": "Ses atzetende {count, plural, one {una rechesta de notìfica} other {# rechestas de notìfica}}. Seguru chi boles sighire?", + "notification_requests.confirm_accept_multiple.title": "Boles atzetare is rechestas de notìfica?", + "notification_requests.confirm_dismiss_multiple.button": "{count, plural, one {Iscarta sa rechesta} other {Iscarta is rechestas}}", + "notification_requests.confirm_dismiss_multiple.message": "Ses acanta de iscartare {count, plural, one {una rechesta de notìfica} other {# rechestas de notìfica}}. No nche {count, plural, one {} other {}} as a pòdere prus atzèdere in manera sèmplitze. Seguru chi boles sighire?", + "notification_requests.confirm_dismiss_multiple.title": "Boles iscartare is rechestas de notìfica?", "notification_requests.dismiss": "Iscarta", + "notification_requests.dismiss_multiple": "{count, plural, one {Iscarta una rechesta…} other {Iscarta # rechestas…}}", + "notification_requests.edit_selection": "Modifica", + "notification_requests.exit_selection": "Fatu", + "notification_requests.explainer_for_limited_account": "Is notìficas de custu contu sunt istadas filtradas, ca su contu est istadu limitadu dae sa moderatzione.", + "notification_requests.explainer_for_limited_remote_account": "Is notìficas de custu contu sunt istadas filtradas, ca su contu o su serbidore suo est istadu limitadu dae sa moderatzione.", + "notification_requests.maximize": "Ismànnia", + "notification_requests.minimize_banner": "Mìnima su bànner de notìficas filtradas", "notification_requests.notifications_from": "Notìficas dae {name}", "notification_requests.title": "Notìficas filtradas", "notifications.clear": "Lìmpia notìficas", @@ -472,6 +561,11 @@ "poll_button.add_poll": "Agiunghe unu sondàgiu", "poll_button.remove_poll": "Cantzella su sondàgiu", "privacy.change": "Modìfica s'istadu de riservadesa", + "privacy.direct.long": "Totu is utentes mentovados in sa publicatzione", + "privacy.direct.short": "Persones ispetzìficas", + "privacy.private.long": "Isceti chie ti sighit", + "privacy.private.short": "Sighiduras", + "privacy.public.long": "Cale si siat persone a intro o a foras de Mastodon", "privacy.public.short": "Pùblicu", "privacy_policy.last_updated": "Ùrtima atualizatzione: {date}", "privacy_policy.title": "Polìtica de riservadesa", @@ -497,34 +591,64 @@ "report.categories.legal": "Giurìdicu", "report.categories.other": "Àteru", "report.categories.spam": "Àliga", + "report.category.subtitle": "Sèbera sa currispondèntzia prus arta", + "report.category.title": "Nara·nos ite sutzedet cun custu {type}", "report.category.title_account": "profilu", "report.category.title_status": "publicatzione", "report.close": "Fatu", + "report.comment.title": "Nch'at àteru chi depamus ischire?", "report.forward": "Torra a imbiare a {target}", "report.forward_hint": "Custu contu est de un'àteru serbidore. Ddi boles imbiare puru una còpia anònima de custu informe?", "report.mute": "A sa muda", + "report.mute_explanation": "No as a bìdere is publicatziones suas. Ti podet ancora sighire e bìdere is publicatziones, ma no at a ischire chi dd'as postu a sa muda.", "report.next": "Imbeniente", "report.placeholder": "Cummentos additzionales", "report.reasons.dislike": "Non mi praghet", "report.reasons.dislike_description": "Est una cosa chi non boles bìdere", "report.reasons.legal": "Illegale", "report.reasons.other": "Un'àtera cosa", + "report.reasons.other_description": "Su problema non currispondet a is àteras categorias", "report.reasons.spam": "Est àliga", + "report.rules.subtitle": "Seletziona totu is chi àplichent", + "report.statuses.subtitle": "Seletziona totu is chi àplichent", "report.submit": "Imbia", "report.target": "Informende de {target}", + "report.thanks.title": "Non boles bìdere custu?", + "report.thanks.title_actionable": "Gràtzias de sa sinnalatzione, dd'amus a averiguare.", "report.unfollow": "Non sigas prus a @{name}", + "report.unfollow_explanation": "Ses sighende custu contu. Si non boles bìdere is publicatziones suas in sa pàgina printzipale tua, no ddu sigas prus.", "report_notification.attached_statuses": "{count, plural, one {# post} other {# posts}} attached", "report_notification.categories.legal": "Giurìdicu", "report_notification.categories.legal_sentence": "cuntenutu illegale", "report_notification.categories.other": "Àteru", "report_notification.categories.other_sentence": "àteru", "report_notification.categories.spam": "Àliga", + "report_notification.categories.spam_sentence": "àliga", + "report_notification.open": "Aberi una sinnalatzione", + "search.no_recent_searches": "Nissuna chirca reghente", "search.placeholder": "Chirca", + "search.quick_action.account_search": "Profilos chi currispondent cun {x}", + "search.quick_action.go_to_account": "Bae a su profilu {x}", + "search.quick_action.go_to_hashtag": "Bae a s'eticheta {x}", + "search.quick_action.open_url": "Aberi s'URL in Mastodon", + "search.quick_action.status_search": "Publicatziones chi currispondent cun {x}", + "search.search_or_paste": "Chirca o incolla un'URL", + "search_popout.full_text_search_disabled_message": "No a disponimentu a {domain}.", + "search_popout.full_text_search_logged_out_message": "Isceti a disponimentu cun sa sessione aberta.", + "search_popout.language_code": "Còdighe de limba ISO", + "search_popout.options": "Optziones de chirca", + "search_popout.quick_actions": "Atziones lestras", + "search_popout.recent": "Chircas reghentes", + "search_popout.specific_date": "data ispetzìfica", "search_popout.user": "utente", "search_results.accounts": "Profilos", "search_results.all": "Totus", "search_results.hashtags": "Etichetas", + "search_results.nothing_found": "Impossìbile agatare currispondèntzias pro custos tèrmines de chirca", + "search_results.see_all": "Bide totu", "search_results.statuses": "Publicatziones", + "search_results.title": "Chirca {q}", + "server_banner.about_active_users": "Gente chi at impreadu custu serbidore is ùrtimas 30 dies (Utentes cun Atividade a su Mese)", "server_banner.active_users": "utentes ativos", "server_banner.administered_by": "Amministradu dae:", "server_banner.server_stats": "Istatìsticas de su serbidore:", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 2d9c7321d0..36c0b68f00 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -124,7 +124,7 @@ "column.direct": "Özel değinmeler", "column.directory": "Profillere göz at", "column.domain_blocks": "Engellenen alan adları", - "column.favourites": "Favorilerin", + "column.favourites": "Gözdelerin", "column.firehose": "Anlık Akışlar", "column.follow_requests": "Takip istekleri", "column.home": "Anasayfa", @@ -812,7 +812,7 @@ "status.reblogged_by": "{name} yeniden paylaştı", "status.reblogs": "{count, plural, one {yeniden paylaşım} other {yeniden paylaşım}}", "status.reblogs.empty": "Henüz hiç kimse bu gönderiyi yeniden paylaşmadı. Herhangi bir kullanıcı yeniden paylaştığında burada görüntülenecek.", - "status.redraft": "Sil,Düzenle ve Yeniden paylaş", + "status.redraft": "Sil,Düzenle ve yeniden-paylaş", "status.remove_bookmark": "Yer işaretini kaldır", "status.replied_in_thread": "Akışta yanıtlandı", "status.replied_to": "{name} kullanıcısına yanıt verdi", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index 1753d0bebe..a48b071f54 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -852,6 +852,11 @@ "upload_error.poll": "Не можна завантажувати файли до опитувань.", "upload_form.audio_description": "Опишіть для людей із вадами слуху", "upload_form.description": "Опишіть для людей з вадами зору", + "upload_form.drag_and_drop.instructions": "Щоб вибрати медіавкладення, натисніть пробіл або Enter. Під час перетягування, використайте клавіші зі стрілками для переміщення вкладення в будь-якому напрямку. Натисніть пробіл або Enter знову, щоб залишити медіавкладення в новому положенні, або натисніть клавішу Escape, щоб скасувати.", + "upload_form.drag_and_drop.on_drag_cancel": "Перетягування скасовано. Медіавкладення {item} прибрано.", + "upload_form.drag_and_drop.on_drag_end": "Медіавкладення {item} прибрано.", + "upload_form.drag_and_drop.on_drag_over": "Медіавкладення {item} переміщено.", + "upload_form.drag_and_drop.on_drag_start": "Медіавкладення {item} вибрано.", "upload_form.edit": "Змінити", "upload_form.thumbnail": "Змінити мініатюру", "upload_form.video_description": "Опишіть для людей із вадами слуху або зору", diff --git a/config/locales/de.yml b/config/locales/de.yml index c82e65282f..7a8469df61 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -79,7 +79,7 @@ de: invite_request_text: Begründung für das Beitreten invited_by: Eingeladen von ip: IP-Adresse - joined: Beigetreten + joined: Mitglied seit location: all: Alle local: Lokal diff --git a/config/locales/sc.yml b/config/locales/sc.yml index 306e670b71..9ab62cea71 100644 --- a/config/locales/sc.yml +++ b/config/locales/sc.yml @@ -30,17 +30,25 @@ sc: created_msg: As creadu una nota de moderatzione. destroyed_msg: As cantzelladu una nota de moderatzione. accounts: + add_email_domain_block: Bloca domìniu de posta eletrònica approve: Aprova approved_msg: Sa dimanda de registru de %{username} est istada aprovada are_you_sure: Seguru? avatar: Immàgine de profilu by_domain: Domìniu change_email: + changed_msg: Indiritzu eletrònicu de su contu modificadu! current_email: Indiritzu eletrònicu atuale label: Muda s'indiritzu eletrònicu new_email: Indiritzu eletrònicu nou submit: Muda s'indiritzu eletrònicu title: Muda s'indiritzu eletrònicu de %{username} + change_role: + changed_msg: Ruolu modificadu. + edit_roles: Gesti is ruolos de utente + label: Modifica su ruolu + no_role: Nissunu ruolu + title: Modifica su ruolu de %{username} confirm: Cunfirma confirmed: Cunfirmadu confirming: Cunfirmende @@ -91,6 +99,7 @@ sc: most_recent_ip: IP prus reghente no_account_selected: Perunu contu est istadu mudadu, dae chi non nd'as seletzionadu no_limits_imposed: Sena lìmites + no_role_assigned: Nissunu ruolu assignadu not_subscribed: Sena sutiscritzione pending: De revisionare perform_full_suspension: Suspèndidu @@ -108,12 +117,19 @@ sc: removed_header_msg: S'immàgine de intestatzione de %{username} est istada bogada resend_confirmation: already_confirmed: Custa persone est giai cunfirmada + send: Torra a imbiare su ligòngiu de cunfirmatzione + success: Ligòngiu de cunfirmatzione imbiadu. reset: Reseta reset_password: Reseta sa crae resubscribe: Torra a sutascrìere + role: Ruolu search: Chirca + search_same_email_domain: Àteras persones cun su pròpiu domìniu de posta search_same_ip: Àteras persones cun sa pròpiu IP security: Seguresa + security_measures: + only_password: Crae isceti + password_and_2fa: Crae e 2FA sensitive: Sensìbile sensitized: Marcadu comente sensìbile shared_inbox_url: URL de intrada cumpartzida @@ -129,6 +145,8 @@ sc: suspension_irreversible: Is datos de custu contu sunt istados cantzellados in manera irreversìbile. Podes bogare sa suspensione a su contu pro chi si potzat impreare, ma no at a recuperare datu perunu de is chi teniat in antis. suspension_reversible_hint_html: Su contu est istadu suspèndidu, e is datos ant a èssere cantzelladu de su totu su %{date}. Finas a tando, su contu si podet ripristinare sena efetu malu perunu. Si boles cantzellare totu is datos de su contu immediatamente ddu podes fàghere inoghe in bassu. title: Contos + unblock_email: Isbloca s'indiritzu de posta eletrònica + unblocked_email_msg: Posta eletrònica de %{username} isblocada unconfirmed_email: Posta eletrònica sena cunfirmare undo_sensitized: Boga sa marcadura comente sensìbile undo_silenced: Non pòngias a sa muda @@ -143,21 +161,31 @@ sc: whitelisted: Federatzione permìtida action_logs: action_types: + approve_user: Aprova s'utente assigned_to_self_report: Assigna s'informe + change_email_user: Muda s'indiritzu eletrònicu pro s'utente + change_role_user: Muda su ruolu de s'utente confirm_user: Cunfirma s'utente create_account_warning: Crea un'avisu create_announcement: Crea un'annùntziu + create_canonical_email_block: Crea unu blocu de posta eletrònica create_custom_emoji: Crea un'emoji personalizadu create_domain_allow: Crea unu domìniu permìtidu create_domain_block: Crea unu blocu de domìniu + create_email_domain_block: Crea unu blocu de domìniu de posta eletrònica create_ip_block: Crea una règula IP + create_unavailable_domain: Crea unu domìniu no a disponimentu + create_user_role: Crea unu ruolu demote_user: Degrada s'utente destroy_announcement: Cantzella s'annùntziu + destroy_canonical_email_block: Cantzella su blocu de posta eletrònica destroy_custom_emoji: Cantzella s'emoji personalizadu destroy_domain_allow: Cantzella su domìniu permìtidu destroy_domain_block: Cantzella su blocu de domìniu + destroy_email_domain_block: Cantzella su blocu de domìniu de posta eletrònica destroy_ip_block: Cantzella sa règula IP destroy_status: Cantzella s'istadu + destroy_unavailable_domain: Cantzella su domìniu no a disponimentu disable_2fa_user: Disativa 2FA disable_custom_emoji: Disativa s'emoji personalizadu disable_user: Disativa utente @@ -165,23 +193,33 @@ sc: enable_user: Ativa utente memorialize_account: Torra in unu contu de regordu promote_user: Promove utente + reject_user: Refuda s'utente remove_avatar_user: Cantzella immàgine de profilu reopen_report: Torra a abèrrere s'informe + resend_user: Torra a imbiare messàgiu eletrònicu de cunfirmatzione reset_password_user: Reseta sa crae resolve_report: Isorve s'informe sensitive_account: Marca is cuntenutos multimediales in su contu tuo comente sensìbiles silence_account: Pone custu contu a sa muda suspend_account: Suspende custu contu unassigned_report: Boga s'assignatzione de custu informe + unblock_email_account: Isbloca s'indiritzu de posta eletrònica unsensitive_account: Boga sa marcadura "sensìbiles" a is elementos multimediales in su contu tuo unsilence_account: Boga custu contu de is contos a sa muda unsuspend_account: Boga custu contu de is contos suspèndidos update_announcement: Atualiza s'annùntziu update_custom_emoji: Atualiza s'emoji personalizadu update_domain_block: Atualiza blocu de domìniu + update_ip_block: Atualiza sa règula IP + update_report: Atualiza s'informe update_status: Atualiza s'istadu + update_user_role: Atualiza su ruolu actions: + approve_user_html: "%{name} at aprovadu su registru de %{target}" assigned_to_self_report_html: "%{name} s'est auto-assignadu s'informe %{target}" + change_email_user_html: "%{name} at mudadu s'indiritzu de posta eletrònica de s'utente %{target}" + change_role_user_html: "%{name} at mudadu su ruolu de %{target}" + confirm_user_html: "%{name} at cunfirmadu s'indiritzu de posta eletrònica de s'utente %{target}" create_account_warning_html: "%{name} at imbiadu un'avisu a %{target}" create_announcement_html: "%{name} at creadu un'annùntziu nou %{target}" create_custom_emoji_html: "%{name} at carrigadu un'emoji nou %{target}" @@ -291,6 +329,8 @@ sc: confirm_suspension: cancel: Annulla confirm: Suspende + remove_all_data: Custu at a cantzellare totu su cuntenutu, elementos multimediales e datos de profilu pro is contos de custu domìniu dae su serbidore tuo. + stop_communication: Su serbidore tuo at a tzessare sa comunicatzione cun custos serbidores. title: Cunfirma su blocu de domìniu de %{domain} created_msg: Protzessende su blocu de domìniu destroyed_msg: Su blocu de domìniu est istadu iscontzadu @@ -361,9 +401,12 @@ sc: dashboard: instance_accounts_dimension: Contos prus sighidos instance_accounts_measure: contos sarvados + instance_languages_dimension: Limbas printzipales instance_reports_measure: informes a subra de àtere + instance_statuses_measure: publicatziones sarvadas delivery: all: Totus + unavailable: No a disponimentu delivery_available: Sa cunsigna est a disponimentu empty: Perunu domìniu agatadu. known_accounts: diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 7382631911..f1e0983705 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -1,7 +1,7 @@ --- tr: about: - about_mastodon_html: Mastodon ücretsiz ve açık kaynaklı bir sosyal ağdır. Merkezileştirilmemiş yapısı sayesinde diğer ticari sosyal platformların aksine iletişimininizin tek bir firmada tutulmasının/yönetilmesinin önüne geçer. Güvendiğiniz bir sunucuyu seçerek oradaki kişilerle etkileşimde bulunabilirsiniz. Herkes kendi Mastodon sunucusunu kurabilir ve sorunsuz bir şekilde Mastodon sosyal ağına dahil edebilir. + about_mastodon_html: Mastodon ücretsiz ve açık kaynaklı bir sosyal ağdır. Merkezi olmayan yapısı sayesinde diğer ticari sosyal platformların aksine iletişimininizin tek bir firmada tutulmasının/yönetilmesinin önüne geçer. Güvendiğiniz bir sunucuyu seçerek oradaki kişilerle etkileşimde bulunabilirsiniz. Herkes kendi Mastodon sunucusunu kurabilir ve sorunsuz bir şekilde Mastodon sosyal ağına dahil edebilir! contact_missing: Ayarlanmadı contact_unavailable: Bulunamadı hosted_on: Mastodon %{domain} üzerinde barındırılıyor From 1db91ab8d9b26ba0103bdc51bc9c79411a3cf6dd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Oct 2024 11:34:04 +0200 Subject: [PATCH 059/150] Update dependency typescript to v5.6.2 (#32165) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index 0a7f89990c..9aeb2b02a8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17382,22 +17382,22 @@ __metadata: linkType: hard "typescript@npm:5, typescript@npm:^5.0.4": - version: 5.5.4 - resolution: "typescript@npm:5.5.4" + version: 5.6.2 + resolution: "typescript@npm:5.6.2" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/422be60f89e661eab29ac488c974b6cc0a660fb2228003b297c3d10c32c90f3bcffc1009b43876a082515a3c376b1eefcce823d6e78982e6878408b9a923199c + checksum: 10c0/3ed8297a8c7c56b7fec282532503d1ac795239d06e7c4966b42d4330c6cf433a170b53bcf93a130a7f14ccc5235de5560df4f1045eb7f3550b46ebed16d3c5e5 languageName: node linkType: hard "typescript@patch:typescript@npm%3A5#optional!builtin, typescript@patch:typescript@npm%3A^5.0.4#optional!builtin": - version: 5.5.4 - resolution: "typescript@patch:typescript@npm%3A5.5.4#optional!builtin::version=5.5.4&hash=379a07" + version: 5.6.2 + resolution: "typescript@patch:typescript@npm%3A5.6.2#optional!builtin::version=5.6.2&hash=8c6c40" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/73409d7b9196a5a1217b3aaad929bf76294d3ce7d6e9766dd880ece296ee91cf7d7db6b16c6c6c630ee5096eccde726c0ef17c7dfa52b01a243e57ae1f09ef07 + checksum: 10c0/94eb47e130d3edd964b76da85975601dcb3604b0c848a36f63ac448d0104e93819d94c8bdf6b07c00120f2ce9c05256b8b6092d23cf5cf1c6fa911159e4d572f languageName: node linkType: hard From 52afa94f1c277f7387c5bb3d1eb85fb555126a2a Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 3 Oct 2024 08:13:54 -0400 Subject: [PATCH 060/150] Use `print_table` to wrap storage output CLI (#32230) --- lib/mastodon/cli/media.rb | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/lib/mastodon/cli/media.rb b/lib/mastodon/cli/media.rb index 70c11ee1a1..37f110d898 100644 --- a/lib/mastodon/cli/media.rb +++ b/lib/mastodon/cli/media.rb @@ -278,14 +278,10 @@ module Mastodon::CLI desc 'usage', 'Calculate disk space consumed by Mastodon' def usage - say("Attachments:\t#{number_to_human_size(media_attachment_storage_size)} (#{number_to_human_size(local_media_attachment_storage_size)} local)") - say("Custom emoji:\t#{number_to_human_size(CustomEmoji.sum(:image_file_size))} (#{number_to_human_size(CustomEmoji.local.sum(:image_file_size))} local)") - say("Preview cards:\t#{number_to_human_size(PreviewCard.sum(:image_file_size))}") - say("Avatars:\t#{number_to_human_size(Account.sum(:avatar_file_size))} (#{number_to_human_size(Account.local.sum(:avatar_file_size))} local)") - say("Headers:\t#{number_to_human_size(Account.sum(:header_file_size))} (#{number_to_human_size(Account.local.sum(:header_file_size))} local)") - say("Backups:\t#{number_to_human_size(Backup.sum(:dump_file_size))}") - say("Imports:\t#{number_to_human_size(Import.sum(:data_file_size))}") - say("Settings:\t#{number_to_human_size(SiteUpload.sum(:file_file_size))}") + print_table [ + %w(Object Total Local), + *object_storage_summary, + ] end desc 'lookup URL', 'Lookup where media is displayed by passing a media URL' @@ -318,20 +314,23 @@ module Mastodon::CLI private - def media_attachment_storage_size - MediaAttachment.sum(file_and_thumbnail_size_sql) + def object_storage_summary + [ + [:attachments, MediaAttachment.sum(combined_media_sum), MediaAttachment.where(account: Account.local).sum(combined_media_sum)], + [:custom_emoji, CustomEmoji.sum(:image_file_size), CustomEmoji.local.sum(:image_file_size)], + [:avatars, Account.sum(:avatar_file_size), Account.local.sum(:avatar_file_size)], + [:headers, Account.sum(:header_file_size), Account.local.sum(:header_file_size)], + [:preview_cards, PreviewCard.sum(:image_file_size), nil], + [:backups, Backup.sum(:dump_file_size), nil], + [:imports, Import.sum(:data_file_size), nil], + [:settings, SiteUpload.sum(:file_file_size), nil], + ].map { |label, total, local| [label.to_s.titleize, number_to_human_size(total), local.present? ? number_to_human_size(local) : nil] } end - def local_media_attachment_storage_size - MediaAttachment.where(account: Account.local).sum(file_and_thumbnail_size_sql) - end - - def file_and_thumbnail_size_sql - Arel.sql( - <<~SQL.squish - COALESCE(file_file_size, 0) + COALESCE(thumbnail_file_size, 0) - SQL - ) + def combined_media_sum + Arel.sql(<<~SQL.squish) + COALESCE(file_file_size, 0) + COALESCE(thumbnail_file_size, 0) + SQL end PRELOAD_MODEL_WHITELIST = %w( From d95f6f4410c28b2f7b9f736c9477936587bd700b Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 3 Oct 2024 09:09:58 -0400 Subject: [PATCH 061/150] Extract `ExportSummary` class for account object counts (#32227) --- .../settings/exports_controller.rb | 13 ++- app/models/export.rb | 36 -------- app/presenters/export_summary.rb | 70 +++++++++++++++ app/views/settings/exports/show.html.haml | 18 ++-- spec/models/export_spec.rb | 71 --------------- spec/presenters/export_summary_spec.rb | 86 +++++++++++++++++++ 6 files changed, 177 insertions(+), 117 deletions(-) create mode 100644 app/presenters/export_summary.rb create mode 100644 spec/presenters/export_summary_spec.rb diff --git a/app/controllers/settings/exports_controller.rb b/app/controllers/settings/exports_controller.rb index 076ed5dadb..263d20eaea 100644 --- a/app/controllers/settings/exports_controller.rb +++ b/app/controllers/settings/exports_controller.rb @@ -9,7 +9,7 @@ class Settings::ExportsController < Settings::BaseController skip_before_action :require_functional! def show - @export = Export.new(current_account) + @export_summary = ExportSummary.new(preloaded_account) @backups = current_user.backups end @@ -25,4 +25,15 @@ class Settings::ExportsController < Settings::BaseController redirect_to settings_export_path end + + private + + def preloaded_account + current_account.tap do |account| + ActiveRecord::Associations::Preloader.new( + records: [account], + associations: :account_stat + ).call + end + end end diff --git a/app/models/export.rb b/app/models/export.rb index 2457dcc156..6ed9f60c7c 100644 --- a/app/models/export.rb +++ b/app/models/export.rb @@ -55,42 +55,6 @@ class Export end end - def total_storage - account.media_attachments.sum(:file_file_size) - end - - def total_statuses - account.statuses_count - end - - def total_bookmarks - account.bookmarks.count - end - - def total_follows - account.following_count - end - - def total_lists - account.owned_lists.count - end - - def total_followers - account.followers_count - end - - def total_blocks - account.blocking.count - end - - def total_mutes - account.muting.count - end - - def total_domain_blocks - account.domain_blocks.count - end - private def to_csv(accounts) diff --git a/app/presenters/export_summary.rb b/app/presenters/export_summary.rb new file mode 100644 index 0000000000..8e45aadf67 --- /dev/null +++ b/app/presenters/export_summary.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +class ExportSummary + attr_reader :account, :counts + + delegate( + :blocking, + :bookmarks, + :domain_blocks, + :owned_lists, + :media_attachments, + :muting, + to: :account, + prefix: true + ) + + def initialize(account) + @account = account + @counts = populate_counts + end + + def total_blocks + counts[:blocks].value + end + + def total_bookmarks + counts[:bookmarks].value + end + + def total_domain_blocks + counts[:domain_blocks].value + end + + def total_followers + account.followers_count + end + + def total_follows + account.following_count + end + + def total_lists + counts[:owned_lists].value + end + + def total_mutes + counts[:muting].value + end + + def total_statuses + account.statuses_count + end + + def total_storage + counts[:storage].value + end + + private + + def populate_counts + { + blocks: account_blocking.async_count, + bookmarks: account_bookmarks.async_count, + domain_blocks: account_domain_blocks.async_count, + owned_lists: account_owned_lists.async_count, + muting: account_muting.async_count, + storage: account_media_attachments.async_sum(:file_file_size), + } + end +end diff --git a/app/views/settings/exports/show.html.haml b/app/views/settings/exports/show.html.haml index 61d55350c2..b36e395e35 100644 --- a/app/views/settings/exports/show.html.haml +++ b/app/views/settings/exports/show.html.haml @@ -6,39 +6,39 @@ %tbody %tr %th= t('exports.storage') - %td= number_to_human_size @export.total_storage + %td= number_to_human_size @export_summary.total_storage %td %tr %th= t('accounts.posts_tab_heading') - %td= number_with_delimiter @export.total_statuses + %td= number_with_delimiter @export_summary.total_statuses %td %tr %th= t('admin.accounts.follows') - %td= number_with_delimiter @export.total_follows + %td= number_with_delimiter @export_summary.total_follows %td= table_link_to 'download', t('exports.csv'), settings_exports_follows_path(format: :csv) %tr %th= t('exports.lists') - %td= number_with_delimiter @export.total_lists + %td= number_with_delimiter @export_summary.total_lists %td= table_link_to 'download', t('exports.csv'), settings_exports_lists_path(format: :csv) %tr %th= t('admin.accounts.followers') - %td= number_with_delimiter @export.total_followers + %td= number_with_delimiter @export_summary.total_followers %td %tr %th= t('exports.mutes') - %td= number_with_delimiter @export.total_mutes + %td= number_with_delimiter @export_summary.total_mutes %td= table_link_to 'download', t('exports.csv'), settings_exports_mutes_path(format: :csv) %tr %th= t('exports.blocks') - %td= number_with_delimiter @export.total_blocks + %td= number_with_delimiter @export_summary.total_blocks %td= table_link_to 'download', t('exports.csv'), settings_exports_blocks_path(format: :csv) %tr %th= t('exports.domain_blocks') - %td= number_with_delimiter @export.total_domain_blocks + %td= number_with_delimiter @export_summary.total_domain_blocks %td= table_link_to 'download', t('exports.csv'), settings_exports_domain_blocks_path(format: :csv) %tr %th= t('exports.bookmarks') - %td= number_with_delimiter @export.total_bookmarks + %td= number_with_delimiter @export_summary.total_bookmarks %td= table_link_to 'download', t('exports.csv'), settings_exports_bookmarks_path(format: :csv) %hr.spacer/ diff --git a/spec/models/export_spec.rb b/spec/models/export_spec.rb index 48e78830dd..81aaf88585 100644 --- a/spec/models/export_spec.rb +++ b/spec/models/export_spec.rb @@ -103,75 +103,4 @@ RSpec.describe Export do ) end end - - describe '#total_storage' do - it 'returns the total size of the media attachments' do - media_attachment = Fabricate(:media_attachment, account: account) - expect(subject.total_storage).to eq media_attachment.file_file_size || 0 - end - end - - describe '#total_statuses' do - before { Fabricate.times(2, :status, account: account) } - - it 'returns the total number of statuses' do - expect(subject.total_statuses).to eq(2) - end - end - - describe '#total_bookmarks' do - before { Fabricate.times(2, :bookmark, account: account) } - - it 'returns the total number of bookmarks' do - expect(subject.total_bookmarks).to eq(2) - end - end - - describe '#total_follows' do - before { target_accounts.each { |target_account| account.follow!(target_account) } } - - it 'returns the total number of the followed accounts' do - expect(subject.total_follows).to eq(2) - end - end - - describe '#total_lists' do - before { Fabricate.times(2, :list, account: account) } - - it 'returns the total number of lists' do - expect(subject.total_lists).to eq(2) - end - end - - describe '#total_followers' do - before { target_accounts.each { |target_account| target_account.follow!(account) } } - - it 'returns the total number of the follower accounts' do - expect(subject.total_followers).to eq(2) - end - end - - describe '#total_blocks' do - before { target_accounts.each { |target_account| account.block!(target_account) } } - - it 'returns the total number of the blocked accounts' do - expect(subject.total_blocks).to eq(2) - end - end - - describe '#total_mutes' do - before { target_accounts.each { |target_account| account.mute!(target_account) } } - - it 'returns the total number of the muted accounts' do - expect(subject.total_mutes).to eq(2) - end - end - - describe '#total_domain_blocks' do - before { Fabricate.times(2, :account_domain_block, account: account) } - - it 'returns the total number of account domain blocks' do - expect(subject.total_domain_blocks).to eq(2) - end - end end diff --git a/spec/presenters/export_summary_spec.rb b/spec/presenters/export_summary_spec.rb new file mode 100644 index 0000000000..0ed46c857d --- /dev/null +++ b/spec/presenters/export_summary_spec.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe ExportSummary do + subject { described_class.new(account) } + + let(:account) { Fabricate(:account) } + let(:target_accounts) do + [ + Fabricate(:account), + Fabricate(:account, username: 'one', domain: 'local.host'), + ] + end + + describe '#total_storage' do + it 'returns the total size of the media attachments' do + media_attachment = Fabricate(:media_attachment, account: account) + expect(subject.total_storage).to eq media_attachment.file_file_size || 0 + end + end + + describe '#total_statuses' do + before { Fabricate.times(2, :status, account: account) } + + it 'returns the total number of statuses' do + expect(subject.total_statuses).to eq(2) + end + end + + describe '#total_bookmarks' do + before { Fabricate.times(2, :bookmark, account: account) } + + it 'returns the total number of bookmarks' do + expect(subject.total_bookmarks).to eq(2) + end + end + + describe '#total_follows' do + before { target_accounts.each { |target_account| account.follow!(target_account) } } + + it 'returns the total number of the followed accounts' do + expect(subject.total_follows).to eq(2) + end + end + + describe '#total_lists' do + before { Fabricate.times(2, :list, account: account) } + + it 'returns the total number of lists' do + expect(subject.total_lists).to eq(2) + end + end + + describe '#total_followers' do + before { target_accounts.each { |target_account| target_account.follow!(account) } } + + it 'returns the total number of the follower accounts' do + expect(subject.total_followers).to eq(2) + end + end + + describe '#total_blocks' do + before { target_accounts.each { |target_account| account.block!(target_account) } } + + it 'returns the total number of the blocked accounts' do + expect(subject.total_blocks).to eq(2) + end + end + + describe '#total_mutes' do + before { target_accounts.each { |target_account| account.mute!(target_account) } } + + it 'returns the total number of the muted accounts' do + expect(subject.total_mutes).to eq(2) + end + end + + describe '#total_domain_blocks' do + before { Fabricate.times(2, :account_domain_block, account: account) } + + it 'returns the total number of account domain blocks' do + expect(subject.total_domain_blocks).to eq(2) + end + end +end From cc8d723e7111b7e2e3d6685e0632c38813d27df0 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 3 Oct 2024 09:10:27 -0400 Subject: [PATCH 062/150] Register an XML encoder for response tests (#32220) --- spec/requests/well_known/host_meta_spec.rb | 81 +++++++++++++--------- spec/support/response_encoders.rb | 4 ++ 2 files changed, 53 insertions(+), 32 deletions(-) create mode 100644 spec/support/response_encoders.rb diff --git a/spec/requests/well_known/host_meta_spec.rb b/spec/requests/well_known/host_meta_spec.rb index 726911dda1..8d8e38f521 100644 --- a/spec/requests/well_known/host_meta_spec.rb +++ b/spec/requests/well_known/host_meta_spec.rb @@ -3,45 +3,62 @@ require 'rails_helper' RSpec.describe 'The /.well-known/host-meta request' do - it 'returns http success with valid XML response' do - get '/.well-known/host-meta' + context 'without extension format or accept header' do + it 'returns http success with expected XML' do + get '/.well-known/host-meta' - expect(response) - .to have_http_status(200) - .and have_attributes( - media_type: 'application/xrd+xml' - ) + expect(response) + .to have_http_status(200) + .and have_attributes( + media_type: 'application/xrd+xml' + ) - doc = Nokogiri::XML(response.parsed_body) - expect(doc.at_xpath('/xrd:XRD/xrd:Link[@rel="lrdd"]/@template', 'xrd' => 'http://docs.oasis-open.org/ns/xri/xrd-1.0').value) - .to eq 'https://cb6e6126.ngrok.io/.well-known/webfinger?resource={uri}' + expect(xrd_link_template_value) + .to eq 'https://cb6e6126.ngrok.io/.well-known/webfinger?resource={uri}' + end + + def xrd_link_template_value + response + .parsed_body + .at_xpath('/xrd:XRD/xrd:Link[@rel="lrdd"]/@template', 'xrd' => 'http://docs.oasis-open.org/ns/xri/xrd-1.0') + .value + end end - it 'returns http success with valid JSON response with .json extension' do - get '/.well-known/host-meta.json' + context 'with a .json format extension' do + it 'returns http success with expected JSON' do + get '/.well-known/host-meta.json' - expect(response) - .to have_http_status(200) - .and have_attributes( - media_type: 'application/json' - ) - - expect(response.parsed_body) - .to include( - links: [ - 'rel' => 'lrdd', - 'template' => 'https://cb6e6126.ngrok.io/.well-known/webfinger?resource={uri}', - ] - ) + expect(response) + .to have_http_status(200) + .and have_attributes( + media_type: 'application/json' + ) + expect(response.parsed_body) + .to include(expected_json_template) + end end - it 'returns http success with valid JSON response with Accept header' do - get '/.well-known/host-meta', headers: { 'Accept' => 'application/json' } + context 'with a JSON `Accept` header' do + it 'returns http success with expected JSON' do + get '/.well-known/host-meta', headers: { 'Accept' => 'application/json' } - expect(response) - .to have_http_status(200) - .and have_attributes( - media_type: 'application/json' - ) + expect(response) + .to have_http_status(200) + .and have_attributes( + media_type: 'application/json' + ) + expect(response.parsed_body) + .to include(expected_json_template) + end + end + + def expected_json_template + { + links: [ + 'rel' => 'lrdd', + 'template' => 'https://cb6e6126.ngrok.io/.well-known/webfinger?resource={uri}', + ], + } end end diff --git a/spec/support/response_encoders.rb b/spec/support/response_encoders.rb new file mode 100644 index 0000000000..548dba7132 --- /dev/null +++ b/spec/support/response_encoders.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +ActionDispatch::IntegrationTest + .register_encoder :xml, response_parser: ->(body) { Nokogiri::XML(body) } From 4c0e44ebbe244b32117ef0e2624ca3e7087c34ad Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 3 Oct 2024 18:12:15 +0200 Subject: [PATCH 063/150] Fix recently-broken admin interface buttons (#32240) --- app/javascript/styles/mastodon/forms.scss | 4 ---- app/views/admin/accounts/_buttons.html.haml | 20 +++++++++---------- app/views/admin/accounts/show.html.haml | 2 +- app/views/admin/instances/show.html.haml | 12 +++++------ app/views/admin/invites/index.html.haml | 2 +- app/views/admin/reports/_actions.html.haml | 2 +- app/views/admin/reports/show.html.haml | 4 ++-- app/views/disputes/strikes/show.html.haml | 4 ++-- app/views/settings/exports/show.html.haml | 2 +- .../otp_authentication/show.html.haml | 2 +- .../index.html.haml | 4 ++-- 11 files changed, 27 insertions(+), 31 deletions(-) diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss index 4f974ea585..957a283522 100644 --- a/app/javascript/styles/mastodon/forms.scss +++ b/app/javascript/styles/mastodon/forms.scss @@ -19,10 +19,6 @@ code { margin-bottom: 24px; } -form.button_to { - display: inline-block; -} - .fade-out-top { position: relative; overflow: hidden; diff --git a/app/views/admin/accounts/_buttons.html.haml b/app/views/admin/accounts/_buttons.html.haml index eb1a7c3a4f..2aaca8962c 100644 --- a/app/views/admin/accounts/_buttons.html.haml +++ b/app/views/admin/accounts/_buttons.html.haml @@ -4,8 +4,8 @@ %p.muted-hint= deletion_request.present? ? t('admin.accounts.remote_suspension_reversible_hint_html', date: content_tag(:strong, l(deletion_request.due_at.to_date))) : t('admin.accounts.remote_suspension_irreversible') - else %p.muted-hint= deletion_request.present? ? t('admin.accounts.suspension_reversible_hint_html', date: content_tag(:strong, l(deletion_request.due_at.to_date))) : t('admin.accounts.suspension_irreversible') - = button_to t('admin.accounts.undo_suspension'), unsuspend_admin_account_path(account.id), class: :button if can?(:unsuspend, account) - = button_to t('admin.accounts.redownload'), redownload_admin_account_path(account.id), class: :button if can?(:redownload, account) && account.suspension_origin_remote? + = link_to t('admin.accounts.undo_suspension'), unsuspend_admin_account_path(account.id), method: :post, class: 'button' if can?(:unsuspend, account) + = link_to t('admin.accounts.redownload'), redownload_admin_account_path(account.id), method: :post, class: 'button' if can?(:redownload, account) && account.suspension_origin_remote? - if deletion_request.present? && can?(:destroy, account) = link_to t('admin.accounts.delete'), admin_account_path(account.id), method: :delete, class: 'button button--destructive', data: { confirm: t('admin.accounts.are_you_sure') } - else @@ -14,28 +14,28 @@ - if account.local? && account.user_approved? = link_to t('admin.accounts.warn'), new_admin_account_action_path(account.id, type: 'none'), class: 'button' if can?(:warn, account) - if account.user_disabled? - = button_to t('admin.accounts.enable'), enable_admin_account_path(account.id), class: :button if can?(:enable, account.user) + = link_to t('admin.accounts.enable'), enable_admin_account_path(account.id), method: :post, class: 'button' if can?(:enable, account.user) - elsif can?(:disable, account.user) = link_to t('admin.accounts.disable'), new_admin_account_action_path(account.id, type: 'disable'), class: 'button' - if account.sensitized? - = button_to t('admin.accounts.undo_sensitized'), unsensitive_admin_account_path(account.id), class: :button if can?(:unsensitive, account) + = link_to t('admin.accounts.undo_sensitized'), unsensitive_admin_account_path(account.id), method: :post, class: 'button' if can?(:unsensitive, account) - elsif !account.local? || account.user_approved? = link_to t('admin.accounts.sensitive'), new_admin_account_action_path(account.id, type: 'sensitive'), class: 'button' if can?(:sensitive, account) - if account.silenced? - = button_to t('admin.accounts.undo_silenced'), unsilence_admin_account_path(account.id), class: :button if can?(:unsilence, account) + = link_to t('admin.accounts.undo_silenced'), unsilence_admin_account_path(account.id), method: :post, class: 'button' if can?(:unsilence, account) - elsif !account.local? || account.user_approved? = link_to t('admin.accounts.silence'), new_admin_account_action_path(account.id, type: 'silence'), class: 'button' if can?(:silence, account) - if account.local? - if account.user_pending? - = button_to t('admin.accounts.approve'), approve_admin_account_path(account.id), data: { confirm: t('admin.accounts.are_you_sure') }, class: :button if can?(:approve, account.user) - = button_to t('admin.accounts.reject'), reject_admin_account_path(account.id), data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:reject, account.user) + = link_to t('admin.accounts.approve'), approve_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' if can?(:approve, account.user) + = link_to t('admin.accounts.reject'), reject_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:reject, account.user) - if !account.user_confirmed? && can?(:confirm, account.user) - = button_to t('admin.accounts.confirm'), admin_account_confirmation_path(account.id), class: :button + = link_to t('admin.accounts.confirm'), admin_account_confirmation_path(account.id), method: :post, class: 'button' - if (!account.local? || account.user_approved?) && can?(:suspend, account) = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(account.id, type: 'suspend'), class: 'button' %div - if account.local? - if !account.memorial? && account.user_approved? && can?(:memorialize, account) - = button_to t('admin.accounts.memorialize'), memorialize_admin_account_path(account.id), data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' + = link_to t('admin.accounts.memorialize'), memorialize_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' - elsif can?(:redownload, account) - = button_to t('admin.accounts.redownload'), redownload_admin_account_path(account.id), class: :button + = link_to t('admin.accounts.redownload'), redownload_admin_account_path(account.id), method: :post, class: 'button' diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index 2d9e30e368..f148b9a082 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -30,7 +30,7 @@ = render 'admin/accounts/counters', account: @account - if @account.local? && @account.user.nil? - = button_to t('admin.accounts.unblock_email'), unblock_email_admin_account_path(@account.id), class: :button if can?(:unblock_email, @account) && CanonicalEmailBlock.exists?(reference_account_id: @account.id) + = link_to t('admin.accounts.unblock_email'), unblock_email_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unblock_email, @account) && CanonicalEmailBlock.exists?(reference_account_id: @account.id) - else .table-wrapper %table.table.inline-table diff --git a/app/views/admin/instances/show.html.haml b/app/views/admin/instances/show.html.haml index dd4c50549c..812a9c8870 100644 --- a/app/views/admin/instances/show.html.haml +++ b/app/views/admin/instances/show.html.haml @@ -21,7 +21,7 @@ - if @instance.domain_allow = link_to t('admin.domain_allows.undo'), admin_domain_allow_path(@instance.domain_allow), class: 'button button--destructive', data: { confirm: t('admin.accounts.are_you_sure'), method: :delete } - else - = button_to t('admin.domain_allows.add_new'), admin_domain_allows_path(domain_allow: { domain: @instance.domain }), class: :button + = link_to t('admin.domain_allows.add_new'), admin_domain_allows_path(domain_allow: { domain: @instance.domain }), class: 'button', method: :post - else %p= t('admin.instances.content_policies.description_html') @@ -40,7 +40,7 @@ %td= @instance.domain_block.policies.map { |policy| t(policy, scope: 'admin.instances.content_policies.policies') }.join(' · ') = link_to t('admin.domain_blocks.edit'), edit_admin_domain_block_path(@instance.domain_block), class: 'button' - = button_to t('admin.domain_blocks.undo'), admin_domain_block_path(@instance.domain_block), class: :button, data: { confirm: t('admin.accounts.are_you_sure'), method: :delete } + = link_to t('admin.domain_blocks.undo'), admin_domain_block_path(@instance.domain_block), class: 'button', data: { confirm: t('admin.accounts.are_you_sure'), method: :delete } - else = link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: @instance.domain), class: 'button' @@ -70,16 +70,16 @@ - if @instance.unavailable? %span.negative-hint = t('admin.instances.availability.failure_threshold_reached', date: l(@instance.unavailable_domain.created_at.to_date)) - = button_to t('admin.instances.delivery.restart'), restart_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure') } + = link_to t('admin.instances.delivery.restart'), restart_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post } - elsif @instance.exhausted_deliveries_days.empty? %span.positive-hint = t('admin.instances.availability.no_failures_recorded') - = button_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure') } + = link_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post } - else %span.negative-hint = t('admin.instances.availability.failures_recorded', count: @instance.delivery_failure_tracker.days) - %span= button_to t('admin.instances.delivery.clear'), clear_delivery_errors_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure') } unless @instance.exhausted_deliveries_days.empty? - %span= button_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure') } + %span= link_to t('admin.instances.delivery.clear'), clear_delivery_errors_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post } unless @instance.exhausted_deliveries_days.empty? + %span= link_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post } - if @instance.purgeable? %p= t('admin.instances.purge_description_html') diff --git a/app/views/admin/invites/index.html.haml b/app/views/admin/invites/index.html.haml index bbccca3147..964deaba8f 100644 --- a/app/views/admin/invites/index.html.haml +++ b/app/views/admin/invites/index.html.haml @@ -34,4 +34,4 @@ = paginate @invites - if policy(:invite).deactivate_all? - = button_to t('admin.invites.deactivate_all'), deactivate_all_admin_invites_path, data: { confirm: t('admin.accounts.are_you_sure') }, class: :button + = link_to t('admin.invites.deactivate_all'), deactivate_all_admin_invites_path, method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' diff --git a/app/views/admin/reports/_actions.html.haml b/app/views/admin/reports/_actions.html.haml index c25f45e169..ef016e949b 100644 --- a/app/views/admin/reports/_actions.html.haml +++ b/app/views/admin/reports/_actions.html.haml @@ -2,7 +2,7 @@ .report-actions .report-actions__item .report-actions__item__button - = button_to t('admin.reports.mark_as_resolved'), resolve_admin_report_path(report), class: :button + = link_to t('admin.reports.mark_as_resolved'), resolve_admin_report_path(report), method: :post, class: 'button' .report-actions__item__description = t('admin.reports.actions.resolve_description_html') - if statuses.any? { |status| (status.with_media? || status.with_preview_card?) && !status.discarded? } diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml index 32b6b3be8d..69e9c02921 100644 --- a/app/views/admin/reports/show.html.haml +++ b/app/views/admin/reports/show.html.haml @@ -3,9 +3,9 @@ - content_for :heading_actions do - if @report.unresolved? - = button_to t('admin.reports.mark_as_resolved'), resolve_admin_report_path(@report), class: :button + = link_to t('admin.reports.mark_as_resolved'), resolve_admin_report_path(@report), method: :post, class: 'button' - else - = button_to t('admin.reports.mark_as_unresolved'), reopen_admin_report_path(@report), class: :button + = link_to t('admin.reports.mark_as_unresolved'), reopen_admin_report_path(@report), method: :post, class: 'button' - unless @report.account.local? || @report.target_account.local? .flash-message= t('admin.reports.forwarded_replies_explanation') diff --git a/app/views/disputes/strikes/show.html.haml b/app/views/disputes/strikes/show.html.haml index 1d71e0ddd1..150dc06759 100644 --- a/app/views/disputes/strikes/show.html.haml +++ b/app/views/disputes/strikes/show.html.haml @@ -3,8 +3,8 @@ - content_for :heading_actions do - if @appeal.persisted? - = button_to t('disputes.strikes.approve_appeal'), approve_admin_disputes_appeal_path(@appeal), class: :button if can?(:approve, @appeal) - = button_to t('disputes.strikes.reject_appeal'), reject_admin_disputes_appeal_path(@appeal), class: 'button button--destructive' if can?(:reject, @appeal) + = link_to t('disputes.strikes.approve_appeal'), approve_admin_disputes_appeal_path(@appeal), method: :post, class: 'button' if can?(:approve, @appeal) + = link_to t('disputes.strikes.reject_appeal'), reject_admin_disputes_appeal_path(@appeal), method: :post, class: 'button button--destructive' if can?(:reject, @appeal) - if @strike.overruled? %p.hint diff --git a/app/views/settings/exports/show.html.haml b/app/views/settings/exports/show.html.haml index b36e395e35..5a151be73b 100644 --- a/app/views/settings/exports/show.html.haml +++ b/app/views/settings/exports/show.html.haml @@ -46,7 +46,7 @@ %p.muted-hint= t('exports.archive_takeout.hint_html') - if policy(:backup).create? - %p= button_to t('exports.archive_takeout.request'), settings_export_path, class: :button + %p= link_to t('exports.archive_takeout.request'), settings_export_path, class: 'button', method: :post - unless @backups.empty? %hr.spacer/ diff --git a/app/views/settings/two_factor_authentication/otp_authentication/show.html.haml b/app/views/settings/two_factor_authentication/otp_authentication/show.html.haml index 01f385dbea..d069ba12a9 100644 --- a/app/views/settings/two_factor_authentication/otp_authentication/show.html.haml +++ b/app/views/settings/two_factor_authentication/otp_authentication/show.html.haml @@ -6,4 +6,4 @@ %hr.spacer/ - = button_to t('otp_authentication.setup'), settings_otp_authentication_path, class: 'block-button' + = link_to t('otp_authentication.setup'), settings_otp_authentication_path, data: { method: :post }, class: 'block-button' diff --git a/app/views/settings/two_factor_authentication_methods/index.html.haml b/app/views/settings/two_factor_authentication_methods/index.html.haml index e3a211a3d7..8b670283b9 100644 --- a/app/views/settings/two_factor_authentication_methods/index.html.haml +++ b/app/views/settings/two_factor_authentication_methods/index.html.haml @@ -2,7 +2,7 @@ = t('settings.two_factor_authentication') - content_for :heading_actions do - = button_to t('two_factor_authentication.disable'), disable_settings_two_factor_authentication_methods_path, class: 'button button--destructive' + = link_to t('two_factor_authentication.disable'), disable_settings_two_factor_authentication_methods_path, class: 'button button--destructive', method: :post %p.hint %span.positive-hint @@ -38,4 +38,4 @@ %hr.spacer/ .simple_form - = button_to t('two_factor_authentication.generate_recovery_codes'), settings_two_factor_authentication_recovery_codes_path, class: 'block-button' + = link_to t('two_factor_authentication.generate_recovery_codes'), settings_two_factor_authentication_recovery_codes_path, data: { method: :post }, class: 'block-button' From aba888c4a6c3be008bb708c0871f145cb0356052 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 09:18:38 +0200 Subject: [PATCH 064/150] Update dependency ffmpeg to v7.1 (#32239) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 0452e5d062..a5e35025ae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -214,7 +214,7 @@ FROM build AS ffmpeg # ffmpeg version to compile, change with [--build-arg FFMPEG_VERSION="7.0.x"] # renovate: datasource=repology depName=ffmpeg packageName=openpkg_current/ffmpeg -ARG FFMPEG_VERSION=7.0.2 +ARG FFMPEG_VERSION=7.1 # ffmpeg download URL, change with [--build-arg FFMPEG_URL="https://ffmpeg.org/releases"] ARG FFMPEG_URL=https://ffmpeg.org/releases From 1b247a1dc21bbaf20bd03be073f65e8dfc286dba Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 09:29:53 +0200 Subject: [PATCH 065/150] New Crowdin Translations (automated) (#32249) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/kab.json | 8 +++++--- app/javascript/mastodon/locales/ko.json | 2 +- app/javascript/mastodon/locales/sk.json | 3 ++- app/javascript/mastodon/locales/sq.json | 5 +++++ config/locales/ca.yml | 6 ++++++ config/locales/lv.yml | 7 +++++++ config/locales/simple_form.lv.yml | 1 + config/locales/sk.yml | 6 +++--- 8 files changed, 30 insertions(+), 8 deletions(-) diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json index 07236bb73e..35e9be816e 100644 --- a/app/javascript/mastodon/locales/kab.json +++ b/app/javascript/mastodon/locales/kab.json @@ -278,6 +278,8 @@ "hashtag.counter_by_uses_today": "{count, plural, one {{counter} n tsuffeɣt} other {{counter} n tsuffaɣ}} assa", "hashtag.follow": "Ḍfeṛ ahacṭag", "hashtags.and_other": "…d {count, plural, one {}other {# nniḍen}}", + "hints.threads.replies_may_be_missing": "Tiririyin d-yusan deg iqeddacen nniḍen, yezmer ur d-ddant ara.", + "hints.threads.see_more": "Wali ugar n tririt deg {domain}", "home.column_settings.show_reblogs": "Ssken-d beṭṭu", "home.column_settings.show_replies": "Ssken-d tiririyin", "home.hide_announcements": "Ffer ulɣuyen", @@ -585,7 +587,7 @@ "status.bookmark": "Creḍ", "status.cancel_reblog_private": "Sefsex beṭṭu", "status.cannot_reblog": "Tasuffeɣt-a ur tezmir ara ad tettwabḍu tikelt-nniḍen", - "status.continued_thread": "Asentel yettkemmil", + "status.continued_thread": "Asqerdec yettkemmil", "status.copy": "Nɣel assaɣ ɣer tasuffeɣt", "status.delete": "Kkes", "status.direct": "Bder-d @{name} weḥd-s", @@ -617,10 +619,10 @@ "status.reblogs.empty": "Ula yiwen ur yebḍi tajewwiqt-agi ar tura. Ticki yebḍa-tt yiwen, ad d-iban da.", "status.redraft": "Kkes tɛiwdeḍ tira", "status.remove_bookmark": "Kkes tacreḍt", - "status.replied_in_thread": "Y·t·erra-d deg usentel", + "status.replied_in_thread": "Y·t·erra-d deg usqerdec", "status.replied_to": "Y·terra-yas i {name}", "status.reply": "Err", - "status.replyAll": "Err i lxiḍ", + "status.replyAll": "Err i wesqerdec", "status.report": "Cetki ɣef @{name}", "status.sensitive_warning": "Agbur amḥulfu", "status.share": "Bḍu", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index 2054dfc0ff..e5e7dc2c17 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -317,7 +317,7 @@ "follow_suggestions.curated_suggestion": "스태프의 추천", "follow_suggestions.dismiss": "다시 보지 않기", "follow_suggestions.featured_longer": "{domain} 팀이 손수 고름", - "follow_suggestions.friends_of_friends_longer": "내가 팔로우 하는 사람들 사이에서 인기", + "follow_suggestions.friends_of_friends_longer": "내가 팔로우한 사람들 사이에서 인기", "follow_suggestions.hints.featured": "이 프로필은 {domain} 팀이 손수 선택했습니다.", "follow_suggestions.hints.friends_of_friends": "이 프로필은 내가 팔로우 하는 사람들에게서 유명합니다.", "follow_suggestions.hints.most_followed": "이 프로필은 {domain}에서 가장 많이 팔로우 된 사람들 중 하나입니다.", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index ddf341584c..da3b1eaefd 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -33,7 +33,7 @@ "account.follow": "Sledovať", "account.follow_back": "Sledovať späť", "account.followers": "Sledovatelia", - "account.followers.empty": "Tento účet ešte nikto nesleduje.", + "account.followers.empty": "Ešte nikto nesleduje tohto užívateľa.", "account.followers_counter": "{count, plural, one {{counter} sledujúci} other {{counter} sledujúci}}", "account.following": "Sledovaný účet", "account.following_counter": "{count, plural, one {{counter} sledovaných} other {{counter} sledovaných}}", @@ -85,6 +85,7 @@ "alert.rate_limited.title": "Priveľa žiadostí", "alert.unexpected.message": "Vyskytla sa nečakaná chyba.", "alert.unexpected.title": "Ups!", + "alt_text_badge.title": "Alternatívny popis", "announcement.announcement": "Oznámenie", "attachments_list.unprocessed": "(nespracované)", "audio.hide": "Skryť zvuk", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index 084ac9945f..15101be471 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -852,6 +852,11 @@ "upload_error.poll": "Me pyetësorët s’lejohet ngarkim kartelash.", "upload_form.audio_description": "Përshkruajeni për persona me dëgjim të kufizuar", "upload_form.description": "Përshkruajeni për persona me probleme shikimi", + "upload_form.drag_and_drop.instructions": "Që të merrni një bashkëngjitje media, shtypni tastin Space ose Enter. Teksa bëhet tërheqje, përdorni tastet shigjetë për ta shpënë bashkëngjitjen media në cilëndo drejtori që doni. Shtypni sërish Space ose Enter që të lihet bashkëngjitja media në pozicionin e vet të ri, ose shtypni Esc, që të anulohet veprimi.", + "upload_form.drag_and_drop.on_drag_cancel": "Tërheqja u anulua. Bashkëngjitja media {item} u la.", + "upload_form.drag_and_drop.on_drag_end": "Bashkëngjitja media {item} u la.", + "upload_form.drag_and_drop.on_drag_over": "Bashkëngjitja media {item} u lëviz.", + "upload_form.drag_and_drop.on_drag_start": "U mor bashkëngjitja media {item}.", "upload_form.edit": "Përpunoni", "upload_form.thumbnail": "Ndryshoni miniaturën", "upload_form.video_description": "Përshkruajeni për persona me dëgjim të kufizuar ose probleme shikimi", diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 965f354a35..ced8de4ef2 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -446,6 +446,7 @@ ca: title: Blocar el nou domini de correu-e no_email_domain_block_selected: No s'han canviat els bloqueigs de domini perquè no se n'ha seleccionat cap not_permitted: No permés + resolved_dns_records_hint_html: El nom del domini resol als següents dominis MX, que són els responsables finals per a acceptar els correus. Blocar un domini MX blocarà els registres des de qualsevol adreça de correu que utilitzi el mateix domini MX, encara que el nom visible sigui diferent. Vigileu de no blocar els grans proveïdors de correu. resolved_through_html: Resolt mitjançant %{domain} title: Dominis de correu-e blocats export_domain_allows: @@ -800,6 +801,7 @@ ca: destroyed_msg: La càrrega al lloc s'ha suprimit correctament! software_updates: critical_update: Crítica - si us plau, actualitza ràpidament + description: Es recomana de mantenir actualizada la instal·lació de Mastodon per a beneficiar-se de les darreres correccions i característiques. A més, de vegades és fonamental actualitzar-la per a evitar problemes de seguretat. Per això Mastodon comprova si hi ha actualitzacions cada 30 minuts i us notificarà d'acord amb les preferències de notificacions de correu electrònic. documentation_link: Més informació release_notes: Notes de llançament title: Actualitzacions disponibles @@ -1155,6 +1157,7 @@ ca: account_status: Estat del compte confirming: Esperant que es completi la confirmació del correu-e. functional: El teu compte està completament operatiu. + pending: La vostra sol·licitud està pendent de revisió pel nostre personal. Això pot trigar una mica. Rebreu un correu electrònic quan s'aprovi. redirecting_to: El teu compte és inactiu perquè actualment està redirigint a %{acct}. self_destruct: Com que %{domain} tanca, només tindreu accés limitat al vostre compte. view_strikes: Veure accions del passat contra el teu compte @@ -1202,6 +1205,9 @@ ca: before: 'Abans de procedir, llegiu amb cura aquestes notes:' caches: El contingut que ha estat memoritzat en la memòria cau per altres servidors pot persistir data_removal: Els teus tuts i altres dades seran permanentment eliminades + email_change_html: Podeu canviar l'adreça de correu sense eliminar el vostre compte + email_contact_html: Si encara no arriba, podeu enviar un correu-e a %{email} per a demanar ajuda + email_reconfirmation_html: Si no rebeu el correu electrònic de confirmació , podeu tornar-lo a demanar irreversible: No seràs capaç de restaurar o reactivar el teu compte more_details_html: Per a més detalls, llegeix la política de privadesa. username_available: El teu nom d'usuari esdevindrà altre cop disponible diff --git a/config/locales/lv.yml b/config/locales/lv.yml index 16844a95c2..2cc8ff6a49 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -34,6 +34,7 @@ lv: created_msg: Moderācijas piezīme ir veiksmīgi izveidota! destroyed_msg: Moderācijas piezīme ir veiksmīgi iznīcināta! accounts: + add_email_domain_block: Liegt e-pasta domēnu approve: Apstiprināt approved_msg: Veiksmīgi apstiprināts %{username} reģistrēšanās pieteikums are_you_sure: Vai esi pārliecināts? @@ -61,6 +62,7 @@ lv: demote: Pazemināt destroyed_msg: Lietotāja %{username} dati tagad ievietoti rindā, lai tos nekavējoties izdzēstu disable: Iesaldēt + disable_sign_in_token_auth: Atspējot autentificēšanos ar e-pasta pilnvaru disable_two_factor_authentication: Atspējot 2FA disabled: Iesaldēts display_name: Parādāmais vārds @@ -69,6 +71,7 @@ lv: email: E-pasts email_status: E-pasta statuss enable: Atsaldēt + enable_sign_in_token_auth: Iespējot autentificēšanos ar e-pasta pilnvaru enabled: Iespējots enabled_msg: Veiksmīgi atsaldēts %{username} konts followers: Sekotāji @@ -180,17 +183,21 @@ lv: confirm_user: Apstiprināt lietotāju create_account_warning: Izveidot Brīdinājumu create_announcement: Izveidot Paziņojumu + create_canonical_email_block: Izveidot e-pasta liegumu create_custom_emoji: Izveidot pielāgotu emocijzīmi create_domain_allow: Izveidot Domēna Atļauju create_domain_block: Izveidot Domēna Bloku + create_email_domain_block: Izveidot e-pasta domēna liegumu create_ip_block: Izveidot IP noteikumu create_unavailable_domain: Izveidot Nepieejamu Domēnu create_user_role: Izveidot lomu demote_user: Pazemināt Lietotāju destroy_announcement: Dzēst Paziņojumu + destroy_canonical_email_block: Izdzēst e-pasta liegumu destroy_custom_emoji: Dzēst pielāgoto emocijzīmi destroy_domain_allow: Dzēst Domēna Atļauju destroy_domain_block: Dzēst Domēna Bloku + destroy_email_domain_block: Izdzēst e-pasta domēna liegumu destroy_instance: Attīrīt domēnu destroy_ip_block: Dzēst IP noteikumu destroy_status: Izdzēst Rakstu diff --git a/config/locales/simple_form.lv.yml b/config/locales/simple_form.lv.yml index 9cc32457f7..523e9a5fcc 100644 --- a/config/locales/simple_form.lv.yml +++ b/config/locales/simple_form.lv.yml @@ -86,6 +86,7 @@ lv: custom_css: Vari lietot pielāgotus stilus Mastodon tīmekļa versijā. favicon: WEBP, PNG, GIF vai JPG. Aizstāj noklusējuma Mastodon favikonu ar pielāgotu. mascot: Ignorē ilustrāciju uzlabotajā tīmekļa saskarnē. + media_cache_retention_period: Informācijas nesēju datnes no ierakstiem, kurus ir veikuši attālie lietotāji, tiek kešoti šajā serverī. Kad ir iestatīta apstiprinoša vērtība, informācijas nesēji tiks izdzēsti pēc norādītā dienu skaita. Ja informācijas nesēju dati tiks pieprasīti pēc tam, kad tie tika izdzēsti, tie tiks atkārtoti lejupielādēti, ja avota saturs joprojām būs pieejams. Saišu priekšskatījuma karšu vaicājumu biežuma ierobežojumu dēļ ir ieteicams iestatīt šo vērtību vismaz 14 dienas vai saišu priekšskatījuma kartes netiks atjauninātas pēc pieprasījuma pirms tā laika. peers_api_enabled: Domēna vārdu saraksts, ar kuriem šis serveris ir saskāries fediversā. Šeit nav iekļauti dati par to, vai tu veic federāciju ar noteiktu serveri, tikai tavs serveris par to zina. To izmanto dienesti, kas apkopo statistiku par federāciju vispārīgā nozīmē. profile_directory: Profilu direktorijā ir uzskaitīti visi lietotāji, kuri ir izvēlējušies būt atklājami. require_invite_text: 'Ja pierakstīšanai nepieciešama manuāla apstiprināšana, izdari tā, lai teksta: “Kāpēc vēlaties pievienoties?” ievade ir obligāta, nevis opcionāla' diff --git a/config/locales/sk.yml b/config/locales/sk.yml index 8076682ed4..399ecc061a 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -8,10 +8,10 @@ sk: title: Ohľadom accounts: followers: - few: Sledovateľov + few: Sledujúcich many: Sledovateľov one: Sledujúci - other: Sledovatelia + other: Sledujúci following: Nasledujem instance_actor_flash: Toto konto je virtuálny aktér, ktorý predstavuje samotný server, a nie konkrétneho používateľa. Používa sa na účely federácie a nemal by byť pozastavený. last_active: naposledy aktívny @@ -1167,7 +1167,7 @@ sk: dormant: Spiace follow_failure: Nemožno nasledovať niektoré z vybraných účtov. follow_selected_followers: Následuj označených sledovatelov - followers: Následovatelia + followers: Sledovatelia following: Nasledovaní invited: Pozvaný/á last_active: Naposledy aktívny From 12a8ac1f8514f002a9d2c830e8981fde80b1cba9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 09:57:41 +0200 Subject: [PATCH 066/150] Update dependency node to 20.18 (#32244) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .nvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nvmrc b/.nvmrc index 65da8ce391..10fef252a9 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20.17 +20.18 From 63a959099b854af62b88d6097895d5a7c1443cb3 Mon Sep 17 00:00:00 2001 From: forsamori Date: Fri, 4 Oct 2024 09:02:14 +0100 Subject: [PATCH 067/150] Add margin-bottom to error.dialog to reduce whitespace (#25708) Co-authored-by: Claire --- app/javascript/styles/mastodon/basics.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/styles/mastodon/basics.scss b/app/javascript/styles/mastodon/basics.scss index 1f961cb9e1..1a74d8d52d 100644 --- a/app/javascript/styles/mastodon/basics.scss +++ b/app/javascript/styles/mastodon/basics.scss @@ -141,6 +141,7 @@ body { width: 100%; height: auto; margin-top: -120px; + margin-bottom: -45px; } } From 160917e71814168ce3aac776907dbe23a8c1c178 Mon Sep 17 00:00:00 2001 From: gunchleoc Date: Fri, 4 Oct 2024 09:19:01 +0100 Subject: [PATCH 068/150] Pluralize csv imports (#27094) Co-authored-by: Claire --- app/views/settings/imports/show.html.haml | 4 +- config/i18n-tasks.yml | 4 +- config/locales/en.yml | 48 +++++++++++++++++------ 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/app/views/settings/imports/show.html.haml b/app/views/settings/imports/show.html.haml index 4d50049d3d..dd18ac2168 100644 --- a/app/views/settings/imports/show.html.haml +++ b/app/views/settings/imports/show.html.haml @@ -5,9 +5,9 @@ .flash-message.warning= t('imports.mismatched_types_warning') - if @bulk_import.overwrite? - %p.hint= t("imports.overwrite_preambles.#{@bulk_import.type}_html", filename: @bulk_import.original_filename, total_items: @bulk_import.total_items) + %p.hint= t("imports.overwrite_preambles.#{@bulk_import.type}_html", filename: @bulk_import.original_filename, count: @bulk_import.total_items) - else - %p.hint= t("imports.preambles.#{@bulk_import.type}_html", filename: @bulk_import.original_filename, total_items: @bulk_import.total_items) + %p.hint= t("imports.preambles.#{@bulk_import.type}_html", filename: @bulk_import.original_filename, count: @bulk_import.total_items) .simple_form .actions diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index 8463d4297d..fc043c4223 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -66,8 +66,8 @@ ignore_unused: - 'admin_mailer.*.subject' - 'user_mailer.*.subject' - 'notification_mailer.*' - - 'imports.overwrite_preambles.{following,blocking,muting,domain_blocking,bookmarks,lists}_html' - - 'imports.preambles.{following,blocking,muting,domain_blocking,bookmarks,lists}_html' + - 'imports.overwrite_preambles.{following,blocking,muting,domain_blocking,bookmarks,lists}_html.*' + - 'imports.preambles.{following,blocking,muting,domain_blocking,bookmarks,lists}_html.*' - 'mail_subscriptions.unsubscribe.emails.*' - 'preferences.other' # some locales are missing other keys, therefore leading i18n-tasks to detect `preferences` as plural and not finding use - 'edit_profile.other' # some locales are missing other keys, therefore leading i18n-tasks to detect `preferences` as plural and not finding use diff --git a/config/locales/en.yml b/config/locales/en.yml index bf45dff33a..42327ae183 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1366,19 +1366,43 @@ en: overwrite: Overwrite overwrite_long: Replace current records with the new ones overwrite_preambles: - blocking_html: You are about to replace your block list with up to %{total_items} accounts from %{filename}. - bookmarks_html: You are about to replace your bookmarks with up to %{total_items} posts from %{filename}. - domain_blocking_html: You are about to replace your domain block list with up to %{total_items} domains from %{filename}. - following_html: You are about to follow up to %{total_items} accounts from %{filename} and stop following anyone else. - lists_html: You are about to replace your lists with contents of %{filename}. Up to %{total_items} accounts will be added to new lists. - muting_html: You are about to replace your list of muted accounts with up to %{total_items} accounts from %{filename}. + blocking_html: + one: You are about to replace your block list with up to %{count} account from %{filename}. + other: You are about to replace your block list with up to %{count} accounts from %{filename}. + bookmarks_html: + one: You are about to replace your bookmarks with up to %{count} post from %{filename}. + other: You are about to replace your bookmarks with up to %{count} posts from %{filename}. + domain_blocking_html: + one: You are about to replace your domain block list with up to %{count} domain from %{filename}. + other: You are about to replace your domain block list with up to %{count} domains from %{filename}. + following_html: + one: You are about to follow up to %{count} account from %{filename} and stop following anyone else. + other: You are about to follow up to %{count} accounts from %{filename} and stop following anyone else. + lists_html: + one: You are about to replace your lists with contents of %{filename}. Up to %{count} account will be added to new lists. + other: You are about to replace your lists with contents of %{filename}. Up to %{count} accounts will be added to new lists. + muting_html: + one: You are about to replace your list of muted account with up to %{count} account from %{filename}. + other: You are about to replace your list of muted accounts with up to %{count} accounts from %{filename}. preambles: - blocking_html: You are about to block up to %{total_items} accounts from %{filename}. - bookmarks_html: You are about to add up to %{total_items} posts from %{filename} to your bookmarks. - domain_blocking_html: You are about to block up to %{total_items} domains from %{filename}. - following_html: You are about to follow up to %{total_items} accounts from %{filename}. - lists_html: You are about to add up to %{total_items} accounts from %{filename} to your lists. New lists will be created if there is no list to add to. - muting_html: You are about to mute up to %{total_items} accounts from %{filename}. + blocking_html: + one: You are about to block up to %{count} account from %{filename}. + other: You are about to block up to %{count} accounts from %{filename}. + bookmarks_html: + one: You are about to add up to %{count} post from %{filename} to your bookmarks. + other: You are about to add up to %{count} posts from %{filename} to your bookmarks. + domain_blocking_html: + one: You are about to block up to %{count} domain from %{filename}. + other: You are about to block up to %{count} domains from %{filename}. + following_html: + one: You are about to follow up to %{count} account from %{filename}. + other: You are about to follow up to %{count} accounts from %{filename}. + lists_html: + one: You are about to add up to %{count} account from %{filename} to your lists. New lists will be created if there is no list to add to. + other: You are about to add up to %{count} accounts from %{filename} to your lists. New lists will be created if there is no list to add to. + muting_html: + one: You are about to mute up to %{count} account from %{filename}. + other: You are about to mute up to %{count} accounts from %{filename}. preface: You can import data that you have exported from another server, such as a list of the people you are following or blocking. recent_imports: Recent imports states: From 82e7d53d54143ca69c7b0a0cebacee3f3ddd7b3c Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 4 Oct 2024 04:29:23 -0400 Subject: [PATCH 069/150] Rename transformer constant in sanitizer (#30532) --- lib/sanitize_ext/sanitize_config.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/sanitize_ext/sanitize_config.rb b/lib/sanitize_ext/sanitize_config.rb index f0a7b65783..7387807e47 100644 --- a/lib/sanitize_ext/sanitize_config.rb +++ b/lib/sanitize_ext/sanitize_config.rb @@ -21,7 +21,7 @@ class Sanitize gemini ).freeze - CLASS_WHITELIST_TRANSFORMER = lambda do |env| + ALLOWED_CLASS_TRANSFORMER = lambda do |env| node = env[:node] class_list = node['class']&.split(/[\t\n\f\r ]/) @@ -84,7 +84,7 @@ class Sanitize protocols: {}, transformers: [ - CLASS_WHITELIST_TRANSFORMER, + ALLOWED_CLASS_TRANSFORMER, TRANSLATE_TRANSFORMER, UNSUPPORTED_ELEMENTS_TRANSFORMER, UNSUPPORTED_HREF_TRANSFORMER, From cf28104317642d647d77efe872bdabe3ea0c0624 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 4 Oct 2024 04:30:08 -0400 Subject: [PATCH 070/150] Rename preloaded models constant in cli media (#30531) --- lib/mastodon/cli/media.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/mastodon/cli/media.rb b/lib/mastodon/cli/media.rb index 37f110d898..996b7fd92c 100644 --- a/lib/mastodon/cli/media.rb +++ b/lib/mastodon/cli/media.rb @@ -177,7 +177,7 @@ module Mastodon::CLI attachment_name = path_segments[1].singularize file_name = path_segments.last - next unless PRELOAD_MODEL_WHITELIST.include?(model_name) + next unless PRELOADED_MODELS.include?(model_name) record = model_name.constantize.find_by(id: record_id) attachment = record&.public_send(attachment_name) @@ -296,7 +296,7 @@ module Mastodon::CLI model_name = path_segments.first.classify record_id = path_segments[2...-2].join.to_i - fail_with_message "Cannot find corresponding model: #{model_name}" unless PRELOAD_MODEL_WHITELIST.include?(model_name) + fail_with_message "Cannot find corresponding model: #{model_name}" unless PRELOADED_MODELS.include?(model_name) record = model_name.constantize.find_by(id: record_id) record = record.status if record.respond_to?(:status) @@ -333,7 +333,7 @@ module Mastodon::CLI SQL end - PRELOAD_MODEL_WHITELIST = %w( + PRELOADED_MODELS = %w( Account Backup CustomEmoji @@ -355,7 +355,7 @@ module Mastodon::CLI model_name = segments.first.classify record_id = segments[2...-2].join.to_i - next unless PRELOAD_MODEL_WHITELIST.include?(model_name) + next unless PRELOADED_MODELS.include?(model_name) preload_map[model_name] << record_id end From 49407e7623c52dd9e6e21bcb7a014cb116e081d3 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 4 Oct 2024 10:50:36 +0200 Subject: [PATCH 071/150] Fix Content-Security-Policy when using sso-redirect (#32241) --- app/controllers/concerns/web_app_controller_concern.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/concerns/web_app_controller_concern.rb b/app/controllers/concerns/web_app_controller_concern.rb index ebbdba59af..9485ecda49 100644 --- a/app/controllers/concerns/web_app_controller_concern.rb +++ b/app/controllers/concerns/web_app_controller_concern.rb @@ -13,7 +13,7 @@ module WebAppControllerConcern policy = ContentSecurityPolicy.new if policy.sso_host.present? - p.form_action policy.sso_host + p.form_action policy.sso_host, -> { "https://#{request.host}/auth/auth/" } else p.form_action :none end From 463f9197d822e3b040834b4dab1c5334c7c8b968 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 4 Oct 2024 08:21:55 -0400 Subject: [PATCH 072/150] Add regression coverage for admin reports resolution button within form (#32248) --- spec/system/report_interface_spec.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/spec/system/report_interface_spec.rb b/spec/system/report_interface_spec.rb index 257a1cd6fd..6a90aa5bc6 100644 --- a/spec/system/report_interface_spec.rb +++ b/spec/system/report_interface_spec.rb @@ -28,4 +28,17 @@ RSpec.describe 'report interface', :attachment_processing, :js, :streaming do page.scroll_to(page.find('.batch-table__row')) expect(page).to have_css('.spoiler-button__overlay__label') end + + it 'marks a report resolved from the show page actions area' do + visit admin_report_path(report) + + expect { resolve_report } + .to change { report.reload.action_taken_at }.to(be_present).from(nil) + end + + def resolve_report + within '.report-actions' do + click_on I18n.t('admin.reports.mark_as_resolved') + end + end end From 77f5b127fadc02ba84fd1d5deccc7b70e68aba59 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 4 Oct 2024 14:23:30 +0200 Subject: [PATCH 073/150] Fix unsupported grouped notifications from streaming causing duplicate IDs (#32243) --- .../mastodon/reducers/notification_groups.ts | 87 ++++++++++--------- 1 file changed, 45 insertions(+), 42 deletions(-) diff --git a/app/javascript/mastodon/reducers/notification_groups.ts b/app/javascript/mastodon/reducers/notification_groups.ts index 375e643876..8b033f0fc7 100644 --- a/app/javascript/mastodon/reducers/notification_groups.ts +++ b/app/javascript/mastodon/reducers/notification_groups.ts @@ -206,50 +206,53 @@ function processNewNotification( groups: NotificationGroupsState['groups'], notification: ApiNotificationJSON, ) { - if (shouldGroupNotificationType(notification.type)) { - const existingGroupIndex = groups.findIndex( - (group) => - group.type !== 'gap' && group.group_key === notification.group_key, - ); - - // In any case, we are going to add a group at the top - // If there is currently a gap at the top, now is the time to update it - if (groups.length > 0 && groups[0]?.type === 'gap') { - groups[0].maxId = notification.id; - } - - if (existingGroupIndex > -1) { - const existingGroup = groups[existingGroupIndex]; - - if ( - existingGroup && - existingGroup.type !== 'gap' && - !existingGroup.sampleAccountIds.includes(notification.account.id) // This can happen for example if you like, then unlike, then like again the same post - ) { - // Update the existing group - if ( - existingGroup.sampleAccountIds.unshift(notification.account.id) > - NOTIFICATIONS_GROUP_MAX_AVATARS - ) - existingGroup.sampleAccountIds.pop(); - - existingGroup.most_recent_notification_id = notification.id; - existingGroup.page_max_id = notification.id; - existingGroup.latest_page_notification_at = notification.created_at; - existingGroup.notifications_count += 1; - - groups.splice(existingGroupIndex, 1); - mergeGapsAround(groups, existingGroupIndex); - - groups.unshift(existingGroup); - - return; - } - } + if (!shouldGroupNotificationType(notification.type)) { + notification = { + ...notification, + group_key: `ungrouped-${notification.id}`, + }; } - // We have not found an existing group, create a new one - groups.unshift(createNotificationGroupFromNotificationJSON(notification)); + const existingGroupIndex = groups.findIndex( + (group) => + group.type !== 'gap' && group.group_key === notification.group_key, + ); + + // In any case, we are going to add a group at the top + // If there is currently a gap at the top, now is the time to update it + if (groups.length > 0 && groups[0]?.type === 'gap') { + groups[0].maxId = notification.id; + } + + if (existingGroupIndex > -1) { + const existingGroup = groups[existingGroupIndex]; + + if ( + existingGroup && + existingGroup.type !== 'gap' && + !existingGroup.sampleAccountIds.includes(notification.account.id) // This can happen for example if you like, then unlike, then like again the same post + ) { + // Update the existing group + if ( + existingGroup.sampleAccountIds.unshift(notification.account.id) > + NOTIFICATIONS_GROUP_MAX_AVATARS + ) + existingGroup.sampleAccountIds.pop(); + + existingGroup.most_recent_notification_id = notification.id; + existingGroup.page_max_id = notification.id; + existingGroup.latest_page_notification_at = notification.created_at; + existingGroup.notifications_count += 1; + + groups.splice(existingGroupIndex, 1); + mergeGapsAround(groups, existingGroupIndex); + + groups.unshift(existingGroup); + } + } else { + // We have not found an existing group, create a new one + groups.unshift(createNotificationGroupFromNotificationJSON(notification)); + } } function trimNotifications(state: NotificationGroupsState) { From 4fe7f213a64e22a2912f13a8e5d6ac415125b0a1 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 4 Oct 2024 08:29:43 -0400 Subject: [PATCH 074/150] Use `async_count` in more view locations (#32086) --- app/controllers/admin/announcements_controller.rb | 1 + app/controllers/admin/disputes/appeals_controller.rb | 1 + .../admin/trends/links/preview_card_providers_controller.rb | 1 + app/controllers/admin/trends/tags_controller.rb | 1 + app/views/admin/announcements/index.html.haml | 2 +- app/views/admin/disputes/appeals/index.html.haml | 2 +- .../admin/trends/links/preview_card_providers/index.html.haml | 2 +- app/views/admin/trends/tags/index.html.haml | 2 +- 8 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/controllers/admin/announcements_controller.rb b/app/controllers/admin/announcements_controller.rb index 8f9708183a..12230a6506 100644 --- a/app/controllers/admin/announcements_controller.rb +++ b/app/controllers/admin/announcements_controller.rb @@ -6,6 +6,7 @@ class Admin::AnnouncementsController < Admin::BaseController def index authorize :announcement, :index? + @published_announcements_count = Announcement.published.async_count end def new diff --git a/app/controllers/admin/disputes/appeals_controller.rb b/app/controllers/admin/disputes/appeals_controller.rb index 5e342409b0..0c41553676 100644 --- a/app/controllers/admin/disputes/appeals_controller.rb +++ b/app/controllers/admin/disputes/appeals_controller.rb @@ -6,6 +6,7 @@ class Admin::Disputes::AppealsController < Admin::BaseController def index authorize :appeal, :index? + @pending_appeals_count = Appeal.pending.async_count @appeals = filtered_appeals.page(params[:page]) end diff --git a/app/controllers/admin/trends/links/preview_card_providers_controller.rb b/app/controllers/admin/trends/links/preview_card_providers_controller.rb index 768b79f8db..5e4b4084f8 100644 --- a/app/controllers/admin/trends/links/preview_card_providers_controller.rb +++ b/app/controllers/admin/trends/links/preview_card_providers_controller.rb @@ -4,6 +4,7 @@ class Admin::Trends::Links::PreviewCardProvidersController < Admin::BaseControll def index authorize :preview_card_provider, :review? + @pending_preview_card_providers_count = PreviewCardProvider.unreviewed.async_count @preview_card_providers = filtered_preview_card_providers.page(params[:page]) @form = Trends::PreviewCardProviderBatch.new end diff --git a/app/controllers/admin/trends/tags_controller.rb b/app/controllers/admin/trends/tags_controller.rb index f5946448ae..fcd23fbf66 100644 --- a/app/controllers/admin/trends/tags_controller.rb +++ b/app/controllers/admin/trends/tags_controller.rb @@ -4,6 +4,7 @@ class Admin::Trends::TagsController < Admin::BaseController def index authorize :tag, :review? + @pending_tags_count = Tag.pending_review.async_count @tags = filtered_tags.page(params[:page]) @form = Trends::TagBatch.new end diff --git a/app/views/admin/announcements/index.html.haml b/app/views/admin/announcements/index.html.haml index 72227b0457..6a76c18776 100644 --- a/app/views/admin/announcements/index.html.haml +++ b/app/views/admin/announcements/index.html.haml @@ -9,7 +9,7 @@ %strong= t('admin.relays.status') %ul %li= filter_link_to t('generic.all'), published: nil, unpublished: nil - %li= filter_link_to safe_join([t('admin.announcements.live'), "(#{number_with_delimiter(Announcement.published.count)})"], ' '), published: '1', unpublished: nil + %li= filter_link_to safe_join([t('admin.announcements.live'), "(#{number_with_delimiter(@published_announcements_count.value)})"], ' '), published: '1', unpublished: nil - if @announcements.empty? .muted-hint.center-text diff --git a/app/views/admin/disputes/appeals/index.html.haml b/app/views/admin/disputes/appeals/index.html.haml index 7f04dd40fb..e09e275e5d 100644 --- a/app/views/admin/disputes/appeals/index.html.haml +++ b/app/views/admin/disputes/appeals/index.html.haml @@ -5,7 +5,7 @@ .filter-subset %strong= t('admin.tags.review') %ul - %li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{Appeal.pending.count})"], ' '), status: 'pending' + %li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{@pending_appeals_count.value})"], ' '), status: 'pending' %li= filter_link_to t('admin.trends.approved'), status: 'approved' %li= filter_link_to t('admin.trends.rejected'), status: 'rejected' diff --git a/app/views/admin/trends/links/preview_card_providers/index.html.haml b/app/views/admin/trends/links/preview_card_providers/index.html.haml index 93daf25f31..0770ac4b81 100644 --- a/app/views/admin/trends/links/preview_card_providers/index.html.haml +++ b/app/views/admin/trends/links/preview_card_providers/index.html.haml @@ -12,7 +12,7 @@ %li= filter_link_to t('generic.all'), status: nil %li= filter_link_to t('admin.trends.approved'), status: 'approved' %li= filter_link_to t('admin.trends.rejected'), status: 'rejected' - %li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{PreviewCardProvider.unreviewed.count})"], ' '), status: 'pending_review' + %li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{@pending_preview_card_providers_count.value})"], ' '), status: 'pending_review' .back-link = link_to admin_trends_links_path do = material_symbol 'chevron_left' diff --git a/app/views/admin/trends/tags/index.html.haml b/app/views/admin/trends/tags/index.html.haml index 480877456f..21f6c2947a 100644 --- a/app/views/admin/trends/tags/index.html.haml +++ b/app/views/admin/trends/tags/index.html.haml @@ -12,7 +12,7 @@ %li= filter_link_to t('generic.all'), status: nil %li= filter_link_to t('admin.trends.approved'), status: 'approved' %li= filter_link_to t('admin.trends.rejected'), status: 'rejected' - %li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{Tag.pending_review.count})"], ' '), status: 'pending_review' + %li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{@pending_tags_count.value})"], ' '), status: 'pending_review' = form_with model: @form, url: batch_admin_trends_tags_path do |f| = hidden_field_tag :page, params[:page] || 1 From e4e07b1c34858dc6b7070f1b5d81f40ec63ebf4c Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 4 Oct 2024 10:11:15 -0400 Subject: [PATCH 075/150] Reduce factory usage across `spec/services` area (#32098) --- .../account_statuses_cleanup_service_spec.rb | 75 +++--- .../process_status_update_service_spec.rb | 74 +++-- .../services/authorize_follow_service_spec.rb | 34 ++- .../batched_remove_status_service_spec.rb | 52 ++-- spec/services/block_service_spec.rb | 13 +- spec/services/bulk_import_service_spec.rb | 255 +++++++----------- spec/services/favourite_service_spec.rb | 19 +- spec/services/follow_service_spec.rb | 13 +- .../services/process_mentions_service_spec.rb | 48 ++-- spec/services/reject_follow_service_spec.rb | 36 ++- .../remove_from_followers_service_spec.rb | 23 +- spec/services/remove_status_service_spec.rb | 44 ++- spec/services/report_service_spec.rb | 35 ++- spec/services/resolve_account_service_spec.rb | 128 +++++---- spec/services/resolve_url_service_spec.rb | 44 ++- .../services/translate_status_service_spec.rb | 52 ++-- spec/services/unblock_domain_service_spec.rb | 38 +-- spec/services/unblock_service_spec.rb | 24 +- spec/services/unfollow_service_spec.rb | 38 +-- spec/services/update_account_service_spec.rb | 20 +- spec/services/update_status_service_spec.rb | 143 +++++----- 21 files changed, 567 insertions(+), 641 deletions(-) diff --git a/spec/services/account_statuses_cleanup_service_spec.rb b/spec/services/account_statuses_cleanup_service_spec.rb index 857bd4fda4..553d20029a 100644 --- a/spec/services/account_statuses_cleanup_service_spec.rb +++ b/spec/services/account_statuses_cleanup_service_spec.rb @@ -27,39 +27,35 @@ RSpec.describe AccountStatusesCleanupService do end context 'when given a normal budget of 10' do - it 'reports 3 deleted statuses' do - expect(subject.call(account_policy, 10)).to eq 3 - end + it 'reports 3 deleted statuses and records last deleted id, deletes statuses, preserves recent unrelated statuses' do + expect(subject.call(account_policy, 10)) + .to eq(3) - it 'records the last deleted id' do - subject.call(account_policy, 10) - expect(account_policy.last_inspected).to eq [old_status.id, another_old_status.id].max - end + expect(account_policy.last_inspected) + .to eq [old_status.id, another_old_status.id].max - it 'actually deletes the statuses' do - subject.call(account_policy, 10) - expect(Status.find_by(id: [very_old_status.id, old_status.id, another_old_status.id])).to be_nil - expect { recent_status.reload }.to_not raise_error - end - - it 'preserves recent and unrelated statuses' do - subject.call(account_policy, 10) - expect { unrelated_status.reload }.to_not raise_error - expect { recent_status.reload }.to_not raise_error + expect(Status.find_by(id: [very_old_status.id, old_status.id, another_old_status.id])) + .to be_nil + expect { recent_status.reload } + .to_not raise_error + expect { unrelated_status.reload } + .to_not raise_error + expect { recent_status.reload } + .to_not raise_error end end context 'when called repeatedly with a budget of 2' do - it 'reports 2 then 1 deleted statuses' do - expect(subject.call(account_policy, 2)).to eq 2 - expect(subject.call(account_policy, 2)).to eq 1 - end + it 'reports 2 then 1 deleted statuses and deletes in expected order' do + expect(subject.call(account_policy, 2)) + .to eq(2) + expect(Status.find_by(id: very_old_status.id)) + .to be_nil - it 'actually deletes the statuses in the expected order' do - subject.call(account_policy, 2) - expect(Status.find_by(id: very_old_status.id)).to be_nil - subject.call(account_policy, 2) - expect(Status.find_by(id: [very_old_status.id, old_status.id, another_old_status.id])).to be_nil + expect(subject.call(account_policy, 2)) + .to eq(1) + expect(Status.find_by(id: [very_old_status.id, old_status.id, another_old_status.id])) + .to be_nil end end @@ -90,19 +86,24 @@ RSpec.describe AccountStatusesCleanupService do end end - it 'reports 0 deleted statuses then 0 then 3 then 0 again' do - expect(subject.call(account_policy, 10)).to eq 0 - expect(subject.call(account_policy, 10)).to eq 0 - expect(subject.call(account_policy, 10)).to eq 3 - expect(subject.call(account_policy, 10)).to eq 0 + it 'reports 0 deleted statuses then 0 then 3 then 0 again, and keeps id under oldest deletable record' do + expect(subject.call(account_policy, 10)) + .to eq(0) + expect(subject.call(account_policy, 10)) + .to eq(0) + expect(subject.call(account_policy, 10)) + .to eq(3) + expect(subject.call(account_policy, 10)) + .to eq(0) + expect(account_policy.last_inspected) + .to be < oldest_deletable_record_id end - it 'never causes the recorded id to get higher than oldest deletable toot' do - subject.call(account_policy, 10) - subject.call(account_policy, 10) - subject.call(account_policy, 10) - subject.call(account_policy, 10) - expect(account_policy.last_inspected).to be < Mastodon::Snowflake.id_at(account_policy.min_status_age.seconds.ago, with_random: false) + def oldest_deletable_record_id + Mastodon::Snowflake.id_at( + account_policy.min_status_age.seconds.ago, + with_random: false + ) end end end diff --git a/spec/services/activitypub/process_status_update_service_spec.rb b/spec/services/activitypub/process_status_update_service_spec.rb index a97e840802..b6ceba374f 100644 --- a/spec/services/activitypub/process_status_update_service_spec.rb +++ b/spec/services/activitypub/process_status_update_service_spec.rb @@ -2,10 +2,6 @@ require 'rails_helper' -def poll_option_json(name, votes) - { type: 'Note', name: name, replies: { type: 'Collection', totalItems: votes } } -end - RSpec.describe ActivityPub::ProcessStatusUpdateService do subject { described_class.new } @@ -294,7 +290,6 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do context 'when originally without media attachments' do before do stub_request(:get, 'https://example.com/foo.png').to_return(body: attachment_fixture('emojo.png')) - subject.call(status, json, json) end let(:payload) do @@ -310,19 +305,18 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do } end - it 'updates media attachments' do - media_attachment = status.reload.ordered_media_attachments.first + it 'updates media attachments, fetches attachment, records media change in edit' do + subject.call(status, json, json) - expect(media_attachment).to_not be_nil - expect(media_attachment.remote_url).to eq 'https://example.com/foo.png' - end + expect(status.reload.ordered_media_attachments.first) + .to be_present + .and(have_attributes(remote_url: 'https://example.com/foo.png')) - it 'fetches the attachment' do - expect(a_request(:get, 'https://example.com/foo.png')).to have_been_made - end + expect(a_request(:get, 'https://example.com/foo.png')) + .to have_been_made - it 'records media change in edit' do - expect(status.edits.reload.last.ordered_media_attachment_ids).to_not be_empty + expect(status.edits.reload.last.ordered_media_attachment_ids) + .to_not be_empty end end @@ -344,27 +338,26 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do before do allow(RedownloadMediaWorker).to receive(:perform_async) + end + + it 'updates the existing media attachment in-place, does not queue redownload, updates media, records media change' do subject.call(status, json, json) - end - it 'updates the existing media attachment in-place' do - media_attachment = status.media_attachments.ordered.reload.first + expect(status.media_attachments.ordered.reload.first) + .to be_present + .and have_attributes( + remote_url: 'https://example.com/foo.png', + description: 'A picture' + ) - expect(media_attachment).to_not be_nil - expect(media_attachment.remote_url).to eq 'https://example.com/foo.png' - expect(media_attachment.description).to eq 'A picture' - end + expect(RedownloadMediaWorker) + .to_not have_received(:perform_async) - it 'does not queue redownload for the existing media attachment' do - expect(RedownloadMediaWorker).to_not have_received(:perform_async) - end + expect(status.ordered_media_attachments.map(&:remote_url)) + .to eq %w(https://example.com/foo.png) - it 'updates media attachments' do - expect(status.ordered_media_attachments.map(&:remote_url)).to eq %w(https://example.com/foo.png) - end - - it 'records media change in edit' do - expect(status.edits.reload.last.ordered_media_attachment_ids).to_not be_empty + expect(status.edits.reload.last.ordered_media_attachment_ids) + .to_not be_empty end end @@ -372,10 +365,11 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do before do poll = Fabricate(:poll, status: status) status.update(preloadable_poll: poll) - subject.call(status, json, json) end it 'removes poll and records media change in edit' do + subject.call(status, json, json) + expect(status.reload.poll).to be_nil expect(status.edits.reload.last.poll_options).to be_nil end @@ -398,15 +392,13 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do } end - before do - subject.call(status, json, json) - end - it 'creates a poll and records media change in edit' do - poll = status.reload.poll + subject.call(status, json, json) + + expect(status.reload.poll) + .to be_present + .and have_attributes(options: %w(Foo Bar Baz)) - expect(poll).to_not be_nil - expect(poll.options).to eq %w(Foo Bar Baz) expect(status.edits.reload.last.poll_options).to eq %w(Foo Bar Baz) end end @@ -419,4 +411,8 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do .to eq '2021-09-08 22:39:25 UTC' end end + + def poll_option_json(name, votes) + { type: 'Note', name: name, replies: { type: 'Collection', totalItems: votes } } + end end diff --git a/spec/services/authorize_follow_service_spec.rb b/spec/services/authorize_follow_service_spec.rb index 533b791fb7..de28572802 100644 --- a/spec/services/authorize_follow_service_spec.rb +++ b/spec/services/authorize_follow_service_spec.rb @@ -12,15 +12,15 @@ RSpec.describe AuthorizeFollowService do before do FollowRequest.create(account: bob, target_account: sender) + end + + it 'removes follow request and creates follow relation' do subject.call(bob, sender) - end - it 'removes follow request' do - expect(bob.requested?(sender)).to be false - end - - it 'creates follow relation' do - expect(bob.following?(sender)).to be true + expect(bob) + .to_not be_requested(sender) + expect(bob) + .to be_following(sender) end end @@ -30,19 +30,17 @@ RSpec.describe AuthorizeFollowService do before do FollowRequest.create(account: bob, target_account: sender) stub_request(:post, bob.inbox_url).to_return(status: 200) + end + + it 'removes follow request, creates follow relation, send accept activity', :inline_jobs do subject.call(bob, sender) - end - it 'removes follow request' do - expect(bob.requested?(sender)).to be false - end - - it 'creates follow relation' do - expect(bob.following?(sender)).to be true - end - - it 'sends an accept activity', :inline_jobs do - expect(a_request(:post, bob.inbox_url)).to have_been_made.once + expect(bob) + .to_not be_requested(sender) + expect(bob) + .to be_following(sender) + expect(a_request(:post, bob.inbox_url)) + .to have_been_made.once end end end diff --git a/spec/services/batched_remove_status_service_spec.rb b/spec/services/batched_remove_status_service_spec.rb index 628bb198ef..1ff73a633b 100644 --- a/spec/services/batched_remove_status_service_spec.rb +++ b/spec/services/batched_remove_status_service_spec.rb @@ -24,32 +24,38 @@ RSpec.describe BatchedRemoveStatusService, :inline_jobs do status_alice_hello status_alice_other + end + it 'removes status records, removes from author and local follower feeds, notifies stream, sends delete' do subject.call([status_alice_hello, status_alice_other]) + + expect { Status.find(status_alice_hello.id) } + .to raise_error ActiveRecord::RecordNotFound + expect { Status.find(status_alice_other.id) } + .to raise_error ActiveRecord::RecordNotFound + + expect(feed_ids_for(alice)) + .to_not include(status_alice_hello.id, status_alice_other.id) + + expect(feed_ids_for(jeff)) + .to_not include(status_alice_hello.id, status_alice_other.id) + + expect(redis) + .to have_received(:publish) + .with("timeline:#{jeff.id}", any_args).at_least(:once) + + expect(redis) + .to have_received(:publish) + .with('timeline:public', any_args).at_least(:once) + + expect(a_request(:post, 'http://example.com/inbox')) + .to have_been_made.at_least_once end - it 'removes statuses' do - expect { Status.find(status_alice_hello.id) }.to raise_error ActiveRecord::RecordNotFound - expect { Status.find(status_alice_other.id) }.to raise_error ActiveRecord::RecordNotFound - end - - it 'removes statuses from author\'s home feed' do - expect(HomeFeed.new(alice).get(10).pluck(:id)).to_not include(status_alice_hello.id, status_alice_other.id) - end - - it 'removes statuses from local follower\'s home feed' do - expect(HomeFeed.new(jeff).get(10).pluck(:id)).to_not include(status_alice_hello.id, status_alice_other.id) - end - - it 'notifies streaming API of followers' do - expect(redis).to have_received(:publish).with("timeline:#{jeff.id}", any_args).at_least(:once) - end - - it 'notifies streaming API of public timeline' do - expect(redis).to have_received(:publish).with('timeline:public', any_args).at_least(:once) - end - - it 'sends delete activity to followers' do - expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.at_least_once + def feed_ids_for(account) + HomeFeed + .new(account) + .get(10) + .pluck(:id) end end diff --git a/spec/services/block_service_spec.rb b/spec/services/block_service_spec.rb index 46dd691986..d9687a5404 100644 --- a/spec/services/block_service_spec.rb +++ b/spec/services/block_service_spec.rb @@ -26,15 +26,16 @@ RSpec.describe BlockService do before do stub_request(:post, 'http://example.com/inbox').to_return(status: 200) + end + + it 'creates a blocking relation and send block activity', :inline_jobs do subject.call(sender, bob) - end - it 'creates a blocking relation' do - expect(sender.blocking?(bob)).to be true - end + expect(sender) + .to be_blocking(bob) - it 'sends a block activity', :inline_jobs do - expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once + expect(a_request(:post, 'http://example.com/inbox')) + .to have_been_made.once end end end diff --git a/spec/services/bulk_import_service_spec.rb b/spec/services/bulk_import_service_spec.rb index 0197f81a44..f52fc4d7d5 100644 --- a/spec/services/bulk_import_service_spec.rb +++ b/spec/services/bulk_import_service_spec.rb @@ -24,30 +24,19 @@ RSpec.describe BulkImportService do ].map { |data| import.rows.create!(data: data) } end - before do - account.follow!(Fabricate(:account)) - end + before { account.follow!(Fabricate(:account)) } - it 'does not immediately change who the account follows' do - expect { subject.call(import) }.to_not(change { account.reload.active_relationships.to_a }) - end + it 'does not immediately change who the account follows, enqueues workers, sends follow requests after worker run' do + expect { subject.call(import) } + .to_not(change { account.reload.active_relationships.to_a }) - it 'enqueues workers for the expected rows' do - subject.call(import) - expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows.map(&:id)) - end + expect(row_worker_job_args) + .to match_array(rows.map(&:id)) - it 'requests to follow all the listed users once the workers have run' do - subject.call(import) + stub_resolve_account_and_drain_workers - resolve_account_service_double = instance_double(ResolveAccountService) - allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double) - allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) } - allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) } - - Import::RowWorker.drain - - expect(FollowRequest.includes(:target_account).where(account: account).map { |follow_request| follow_request.target_account.acct }).to contain_exactly('user@foo.bar', 'unknown@unknown.bar') + expect(FollowRequest.includes(:target_account).where(account: account).map { |follow_request| follow_request.target_account.acct }) + .to contain_exactly('user@foo.bar', 'unknown@unknown.bar') end end @@ -71,31 +60,20 @@ RSpec.describe BulkImportService do account.follow!(to_be_unfollowed) end - it 'unfollows user not present on list' do - subject.call(import) - expect(account.following?(to_be_unfollowed)).to be false - end + it 'updates the existing follow relationship as expected and unfollows user not on list, enqueues workers, sends follow reqs after worker run' do + expect { subject.call(import) } + .to change { Follow.where(account: account, target_account: followed).pick(:show_reblogs, :notify, :languages) }.from([true, false, nil]).to([false, true, ['en']]) - it 'updates the existing follow relationship as expected' do - expect { subject.call(import) }.to change { Follow.where(account: account, target_account: followed).pick(:show_reblogs, :notify, :languages) }.from([true, false, nil]).to([false, true, ['en']]) - end + expect(account) + .to_not be_following(to_be_unfollowed) - it 'enqueues workers for the expected rows' do - subject.call(import) - expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows[1..].map(&:id)) - end + expect(row_worker_job_args) + .to match_array(rows[1..].map(&:id)) - it 'requests to follow all the expected users once the workers have run' do - subject.call(import) + stub_resolve_account_and_drain_workers - resolve_account_service_double = instance_double(ResolveAccountService) - allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double) - allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) } - allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) } - - Import::RowWorker.drain - - expect(FollowRequest.includes(:target_account).where(account: account).map { |follow_request| follow_request.target_account.acct }).to contain_exactly('user@foo.bar', 'unknown@unknown.bar') + expect(FollowRequest.includes(:target_account).where(account: account).map { |follow_request| follow_request.target_account.acct }) + .to contain_exactly('user@foo.bar', 'unknown@unknown.bar') end end @@ -110,30 +88,19 @@ RSpec.describe BulkImportService do ].map { |data| import.rows.create!(data: data) } end - before do - account.block!(Fabricate(:account, username: 'already_blocked', domain: 'remote.org')) - end + before { account.block!(Fabricate(:account, username: 'already_blocked', domain: 'remote.org')) } - it 'does not immediately change who the account blocks' do - expect { subject.call(import) }.to_not(change { account.reload.blocking.to_a }) - end + it 'does not immediately change who the account blocks, enqueues worker, blocks after run' do + expect { subject.call(import) } + .to_not(change { account.reload.blocking.to_a }) - it 'enqueues workers for the expected rows' do - subject.call(import) - expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows.map(&:id)) - end + expect(row_worker_job_args) + .to match_array(rows.map(&:id)) - it 'blocks all the listed users once the workers have run' do - subject.call(import) + stub_resolve_account_and_drain_workers - resolve_account_service_double = instance_double(ResolveAccountService) - allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double) - allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) } - allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) } - - Import::RowWorker.drain - - expect(account.blocking.map(&:acct)).to contain_exactly('already_blocked@remote.org', 'user@foo.bar', 'unknown@unknown.bar') + expect(account.reload.blocking.map(&:acct)) + .to contain_exactly('already_blocked@remote.org', 'user@foo.bar', 'unknown@unknown.bar') end end @@ -157,27 +124,18 @@ RSpec.describe BulkImportService do account.block!(to_be_unblocked) end - it 'unblocks user not present on list' do + it 'unblocks user not present on list, enqueues worker, requests follow after run' do subject.call(import) + expect(account.blocking?(to_be_unblocked)).to be false - end - it 'enqueues workers for the expected rows' do - subject.call(import) - expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows[1..].map(&:id)) - end + expect(row_worker_job_args) + .to match_array(rows[1..].map(&:id)) - it 'requests to follow all the expected users once the workers have run' do - subject.call(import) + stub_resolve_account_and_drain_workers - resolve_account_service_double = instance_double(ResolveAccountService) - allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double) - allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) } - allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) } - - Import::RowWorker.drain - - expect(account.blocking.map(&:acct)).to contain_exactly('blocked@foo.bar', 'user@foo.bar', 'unknown@unknown.bar') + expect(account.blocking.map(&:acct)) + .to contain_exactly('blocked@foo.bar', 'user@foo.bar', 'unknown@unknown.bar') end end @@ -192,30 +150,19 @@ RSpec.describe BulkImportService do ].map { |data| import.rows.create!(data: data) } end - before do - account.mute!(Fabricate(:account, username: 'already_muted', domain: 'remote.org')) - end + before { account.mute!(Fabricate(:account, username: 'already_muted', domain: 'remote.org')) } - it 'does not immediately change who the account blocks' do - expect { subject.call(import) }.to_not(change { account.reload.muting.to_a }) - end + it 'does not immediately change who the account blocks, enqueures worker, mutes users after worker run' do + expect { subject.call(import) } + .to_not(change { account.reload.muting.to_a }) - it 'enqueues workers for the expected rows' do - subject.call(import) - expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows.map(&:id)) - end + expect(row_worker_job_args) + .to match_array(rows.map(&:id)) - it 'mutes all the listed users once the workers have run' do - subject.call(import) + stub_resolve_account_and_drain_workers - resolve_account_service_double = instance_double(ResolveAccountService) - allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double) - allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) } - allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) } - - Import::RowWorker.drain - - expect(account.muting.map(&:acct)).to contain_exactly('already_muted@remote.org', 'user@foo.bar', 'unknown@unknown.bar') + expect(account.reload.muting.map(&:acct)) + .to contain_exactly('already_muted@remote.org', 'user@foo.bar', 'unknown@unknown.bar') end end @@ -239,31 +186,19 @@ RSpec.describe BulkImportService do account.mute!(to_be_unmuted) end - it 'updates the existing mute as expected' do - expect { subject.call(import) }.to change { Mute.where(account: account, target_account: muted).pick(:hide_notifications) }.from(false).to(true) - end + it 'updates the existing mute as expected and unblocks user not on list, and enqueues worker, and requests follow after worker run' do + expect { subject.call(import) } + .to change { Mute.where(account: account, target_account: muted).pick(:hide_notifications) }.from(false).to(true) - it 'unblocks user not present on list' do - subject.call(import) expect(account.muting?(to_be_unmuted)).to be false - end - it 'enqueues workers for the expected rows' do - subject.call(import) - expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows[1..].map(&:id)) - end + expect(row_worker_job_args) + .to match_array(rows[1..].map(&:id)) - it 'requests to follow all the expected users once the workers have run' do - subject.call(import) + stub_resolve_account_and_drain_workers - resolve_account_service_double = instance_double(ResolveAccountService) - allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double) - allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) } - allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) } - - Import::RowWorker.drain - - expect(account.muting.map(&:acct)).to contain_exactly('muted@foo.bar', 'user@foo.bar', 'unknown@unknown.bar') + expect(account.muting.map(&:acct)) + .to contain_exactly('muted@foo.bar', 'user@foo.bar', 'unknown@unknown.bar') end end @@ -284,13 +219,11 @@ RSpec.describe BulkImportService do account.block_domain!('blocked.com') end - it 'blocks all the new domains' do + it 'blocks all the new domains and marks import finished' do subject.call(import) - expect(account.domain_blocks.pluck(:domain)).to contain_exactly('alreadyblocked.com', 'blocked.com', 'to-block.com') - end - it 'marks the import as finished' do - subject.call(import) + expect(account.domain_blocks.pluck(:domain)) + .to contain_exactly('alreadyblocked.com', 'blocked.com', 'to-block.com') expect(import.reload.state_finished?).to be true end end @@ -312,14 +245,13 @@ RSpec.describe BulkImportService do account.block_domain!('blocked.com') end - it 'blocks all the new domains' do + it 'blocks all the new domains and marks import finished' do subject.call(import) - expect(account.domain_blocks.pluck(:domain)).to contain_exactly('blocked.com', 'to-block.com') - end - it 'marks the import as finished' do - subject.call(import) - expect(import.reload.state_finished?).to be true + expect(account.domain_blocks.pluck(:domain)) + .to contain_exactly('blocked.com', 'to-block.com') + expect(import.reload.state_finished?) + .to be true end end @@ -347,22 +279,16 @@ RSpec.describe BulkImportService do account.bookmarks.create!(status: bookmarked) end - it 'enqueues workers for the expected rows' do - subject.call(import) - expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows.map(&:id)) - end - - it 'updates the bookmarks as expected once the workers have run' do + it 'enqueues workers for the expected rows and updates bookmarks after worker run' do subject.call(import) - service_double = instance_double(ActivityPub::FetchRemoteStatusService) - allow(ActivityPub::FetchRemoteStatusService).to receive(:new).and_return(service_double) - allow(service_double).to receive(:call).with('https://domain.unknown/foo') { Fabricate(:status, uri: 'https://domain.unknown/foo') } - allow(service_double).to receive(:call).with('https://domain.unknown/private') { Fabricate(:status, uri: 'https://domain.unknown/private', visibility: :direct) } + expect(row_worker_job_args) + .to match_array(rows.map(&:id)) - Import::RowWorker.drain + stub_fetch_remote_and_drain_workers - expect(account.bookmarks.map { |bookmark| bookmark.status.uri }).to contain_exactly(already_bookmarked.uri, status.uri, bookmarked.uri, 'https://domain.unknown/foo') + expect(account.bookmarks.map { |bookmark| bookmark.status.uri }) + .to contain_exactly(already_bookmarked.uri, status.uri, bookmarked.uri, 'https://domain.unknown/foo') end end @@ -390,23 +316,48 @@ RSpec.describe BulkImportService do account.bookmarks.create!(status: bookmarked) end - it 'enqueues workers for the expected rows' do - subject.call(import) - expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows.map(&:id)) - end - - it 'updates the bookmarks as expected once the workers have run' do + it 'enqueues workers for the expected rows and updates bookmarks' do subject.call(import) - service_double = instance_double(ActivityPub::FetchRemoteStatusService) - allow(ActivityPub::FetchRemoteStatusService).to receive(:new).and_return(service_double) - allow(service_double).to receive(:call).with('https://domain.unknown/foo') { Fabricate(:status, uri: 'https://domain.unknown/foo') } - allow(service_double).to receive(:call).with('https://domain.unknown/private') { Fabricate(:status, uri: 'https://domain.unknown/private', visibility: :direct) } + expect(row_worker_job_args) + .to match_array(rows.map(&:id)) - Import::RowWorker.drain + stub_fetch_remote_and_drain_workers - expect(account.bookmarks.map { |bookmark| bookmark.status.uri }).to contain_exactly(status.uri, bookmarked.uri, 'https://domain.unknown/foo') + expect(account.bookmarks.map { |bookmark| bookmark.status.uri }) + .to contain_exactly(status.uri, bookmarked.uri, 'https://domain.unknown/foo') end end + + def row_worker_job_args + Import::RowWorker + .jobs + .pluck('args') + .flatten + end + + def stub_resolve_account_and_drain_workers + resolve_account_service_double = instance_double(ResolveAccountService) + allow(ResolveAccountService) + .to receive(:new) + .and_return(resolve_account_service_double) + allow(resolve_account_service_double) + .to receive(:call) + .with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) } + allow(resolve_account_service_double) + .to receive(:call) + .with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) } + + Import::RowWorker.drain + end + + def stub_fetch_remote_and_drain_workers + service_double = instance_double(ActivityPub::FetchRemoteStatusService) + allow(ActivityPub::FetchRemoteStatusService).to receive(:new).and_return(service_double) + allow(service_double).to receive(:call).with('https://domain.unknown/foo') { Fabricate(:status, uri: 'https://domain.unknown/foo') } + allow(service_double).to receive(:call).with('https://domain.unknown/private') { Fabricate(:status, uri: 'https://domain.unknown/private', visibility: :direct) } + + Import::RowWorker.drain + end end end diff --git a/spec/services/favourite_service_spec.rb b/spec/services/favourite_service_spec.rb index c39362def2..123e8699c7 100644 --- a/spec/services/favourite_service_spec.rb +++ b/spec/services/favourite_service_spec.rb @@ -11,11 +11,9 @@ RSpec.describe FavouriteService do let(:bob) { Fabricate(:account) } let(:status) { Fabricate(:status, account: bob) } - before do - subject.call(sender, status) - end - it 'creates a favourite' do + subject.call(sender, status) + expect(status.favourites.first).to_not be_nil end end @@ -26,15 +24,16 @@ RSpec.describe FavouriteService do before do stub_request(:post, 'http://example.com/inbox').to_return(status: 200, body: '', headers: {}) + end + + it 'creates a favourite and sends like activity', :inline_jobs do subject.call(sender, status) - end - it 'creates a favourite' do - expect(status.favourites.first).to_not be_nil - end + expect(status.favourites.first) + .to_not be_nil - it 'sends a like activity', :inline_jobs do - expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once + expect(a_request(:post, 'http://example.com/inbox')) + .to have_been_made.once end end end diff --git a/spec/services/follow_service_spec.rb b/spec/services/follow_service_spec.rb index 0c4cd60046..bbd8a6f997 100644 --- a/spec/services/follow_service_spec.rb +++ b/spec/services/follow_service_spec.rb @@ -143,15 +143,16 @@ RSpec.describe FollowService do before do stub_request(:post, 'http://example.com/inbox').to_return(status: 200, body: '', headers: {}) + end + + it 'creates follow request and sends an activity to inbox', :inline_jobs do subject.call(sender, bob) - end - it 'creates follow request' do - expect(FollowRequest.find_by(account: sender, target_account: bob)).to_not be_nil - end + expect(FollowRequest.find_by(account: sender, target_account: bob)) + .to_not be_nil - it 'sends a follow activity to the inbox', :inline_jobs do - expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once + expect(a_request(:post, 'http://example.com/inbox')) + .to have_been_made.once end end end diff --git a/spec/services/process_mentions_service_spec.rb b/spec/services/process_mentions_service_spec.rb index 2c202d3e57..3cc83d82f3 100644 --- a/spec/services/process_mentions_service_spec.rb +++ b/spec/services/process_mentions_service_spec.rb @@ -16,20 +16,25 @@ RSpec.describe ProcessMentionsService do before do account.block!(individually_blocked_account) account.domain_blocks.create!(domain: domain_blocked_account.domain) - - subject.call(status) end - it 'creates a mention to the non-blocked account' do - expect(non_blocked_account.mentions.where(status: status).count).to eq 1 + it 'creates a mention to the non-blocked account but not the individually or domain blocked accounts' do + expect { subject.call(status) } + .to create_mention_for_non_blocked + .and skip_mention_for_individual + .and skip_mention_for_domain_blocked end - it 'does not create a mention to the individually blocked account' do - expect(individually_blocked_account.mentions.where(status: status).count).to eq 0 + def create_mention_for_non_blocked + change { non_blocked_account.mentions.where(status: status).count }.to(1) end - it 'does not create a mention to the domain-blocked account' do - expect(domain_blocked_account.mentions.where(status: status).count).to eq 0 + def skip_mention_for_individual + not_change { individually_blocked_account.mentions.where(status: status).count }.from(0) + end + + def skip_mention_for_domain_blocked + not_change { domain_blocked_account.mentions.where(status: status).count }.from(0) end end @@ -40,11 +45,9 @@ RSpec.describe ProcessMentionsService do context 'with a valid remote user' do let!(:remote_user) { Fabricate(:account, username: 'remote_user', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') } - before do - subject.call(status) - end - it 'creates a mention' do + subject.call(status) + expect(remote_user.mentions.where(status: status).count).to eq 1 end end @@ -53,11 +56,9 @@ RSpec.describe ProcessMentionsService do let!(:remote_user) { Fabricate(:account, username: 'remote_user', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') } let(:status) { Fabricate(:status, account: account, text: "Hello @#{remote_user.acct} @#{remote_user.acct} @#{remote_user.acct}", visibility: :public) } - before do - subject.call(status, save_records: false) - end - it 'creates exactly one mention' do + subject.call(status, save_records: false) + expect(status.mentions.size).to eq 1 end end @@ -66,11 +67,9 @@ RSpec.describe ProcessMentionsService do let!(:remote_user) { Fabricate(:account, username: 'sneak', protocol: :activitypub, domain: 'xn--hresiar-mxa.ch', inbox_url: 'http://example.com/inbox') } let!(:status) { Fabricate(:status, account: account, text: 'Hello @sneak@hæresiar.ch') } - before do - subject.call(status) - end - it 'creates a mention' do + subject.call(status) + expect(remote_user.mentions.where(status: status).count).to eq 1 end end @@ -79,11 +78,9 @@ RSpec.describe ProcessMentionsService do let!(:remote_user) { Fabricate(:account, username: 'foo', protocol: :activitypub, domain: 'xn--y9a3aq.xn--y9a3aq', inbox_url: 'http://example.com/inbox') } let!(:status) { Fabricate(:status, account: account, text: 'Hello @foo@հայ.հայ') } - before do - subject.call(status) - end - it 'creates a mention' do + subject.call(status) + expect(remote_user.mentions.where(status: status).count).to eq 1 end end @@ -95,10 +92,11 @@ RSpec.describe ProcessMentionsService do before do stub_request(:get, 'https://example.com/.well-known/host-meta').to_return(status: 404) stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:remote_user@example.com').to_return(status: 500) - subject.call(status) end it 'creates a mention' do + subject.call(status) + expect(remote_user.mentions.where(status: status).count).to eq 1 end end diff --git a/spec/services/reject_follow_service_spec.rb b/spec/services/reject_follow_service_spec.rb index d2c7a00206..eec0d6c1e0 100644 --- a/spec/services/reject_follow_service_spec.rb +++ b/spec/services/reject_follow_service_spec.rb @@ -10,17 +10,15 @@ RSpec.describe RejectFollowService do describe 'local' do let(:bob) { Fabricate(:account) } - before do - FollowRequest.create(account: bob, target_account: sender) + before { FollowRequest.create(account: bob, target_account: sender) } + + it 'removes follow request and does not create relation' do subject.call(bob, sender) - end - it 'removes follow request' do - expect(bob.requested?(sender)).to be false - end - - it 'does not create follow relation' do - expect(bob.following?(sender)).to be false + expect(bob) + .to_not be_requested(sender) + expect(bob) + .to_not be_following(sender) end end @@ -30,19 +28,17 @@ RSpec.describe RejectFollowService do before do FollowRequest.create(account: bob, target_account: sender) stub_request(:post, bob.inbox_url).to_return(status: 200) + end + + it 'removes follow request, does not create relation, sends reject activity', :inline_jobs do subject.call(bob, sender) - end - it 'removes follow request' do - expect(bob.requested?(sender)).to be false - end - - it 'does not create follow relation' do - expect(bob.following?(sender)).to be false - end - - it 'sends a reject activity', :inline_jobs do - expect(a_request(:post, bob.inbox_url)).to have_been_made.once + expect(bob) + .to_not be_requested(sender) + expect(bob) + .to_not be_following(sender) + expect(a_request(:post, bob.inbox_url)) + .to have_been_made.once end end end diff --git a/spec/services/remove_from_followers_service_spec.rb b/spec/services/remove_from_followers_service_spec.rb index 515600096c..381daf1a59 100644 --- a/spec/services/remove_from_followers_service_spec.rb +++ b/spec/services/remove_from_followers_service_spec.rb @@ -10,13 +10,13 @@ RSpec.describe RemoveFromFollowersService do describe 'local' do let(:sender) { Fabricate(:account, username: 'alice') } - before do - Follow.create(account: sender, target_account: bob) - subject.call(bob, sender) - end + before { Follow.create(account: sender, target_account: bob) } it 'does not create follow relation' do - expect(bob.followed_by?(sender)).to be false + subject.call(bob, sender) + + expect(bob) + .to_not be_followed_by(sender) end end @@ -26,15 +26,16 @@ RSpec.describe RemoveFromFollowersService do before do Follow.create(account: sender, target_account: bob) stub_request(:post, sender.inbox_url).to_return(status: 200) + end + + it 'does not create follow relation and sends reject activity', :inline_jobs do subject.call(bob, sender) - end - it 'does not create follow relation' do - expect(bob.followed_by?(sender)).to be false - end + expect(bob) + .to_not be_followed_by(sender) - it 'sends a reject activity', :inline_jobs do - expect(a_request(:post, sender.inbox_url)).to have_been_made.once + expect(a_request(:post, sender.inbox_url)) + .to have_been_made.once end end end diff --git a/spec/services/remove_status_service_spec.rb b/spec/services/remove_status_service_spec.rb index 08f519b536..f2b46f05b0 100644 --- a/spec/services/remove_status_service_spec.rb +++ b/spec/services/remove_status_service_spec.rb @@ -28,42 +28,38 @@ RSpec.describe RemoveStatusService, :inline_jobs do Fabricate(:status, account: bill, reblog: status, uri: 'hoge') end - it 'removes status from author\'s home feed' do - subject.call(status) - expect(HomeFeed.new(alice).get(10).pluck(:id)).to_not include(status.id) - end - - it 'removes status from local follower\'s home feed' do - subject.call(status) - expect(HomeFeed.new(jeff).get(10).pluck(:id)).to_not include(status.id) - end - - it 'publishes to public media timeline' do + it 'removes status from notifications and from author and local follower home feeds, publishes to media timeline, sends delete activities' do allow(redis).to receive(:publish).with(any_args) - subject.call(status) + expect { subject.call(status) } + .to remove_status_from_notifications - expect(redis).to have_received(:publish).with('timeline:public:media', Oj.dump(event: :delete, payload: status.id.to_s)) - end + expect(home_feed_ids(alice)) + .to_not include(status.id) + expect(home_feed_ids(jeff)) + .to_not include(status.id) - it 'sends Delete activity to followers' do - subject.call(status) + expect(redis) + .to have_received(:publish).with('timeline:public:media', Oj.dump(event: :delete, payload: status.id.to_s)) expect(delete_delivery(hank, status)) .to have_been_made.once - end - - it 'sends Delete activity to rebloggers' do - subject.call(status) expect(delete_delivery(bill, status)) .to have_been_made.once end - it 'remove status from notifications' do - expect { subject.call(status) }.to change { - Notification.where(activity_type: 'Favourite', from_account: jeff, account: alice).count - }.from(1).to(0) + def home_feed_ids(personage) + HomeFeed + .new(personage) + .get(10) + .pluck(:id) + end + + def remove_status_from_notifications + change { Notification.where(activity_type: 'Favourite', from_account: jeff, account: alice).count } + .from(1) + .to(0) end def delete_delivery(target, status) diff --git a/spec/services/report_service_spec.rb b/spec/services/report_service_spec.rb index 6518c5c27a..4659e1c7a1 100644 --- a/spec/services/report_service_spec.rb +++ b/spec/services/report_service_spec.rb @@ -31,14 +31,13 @@ RSpec.describe ReportService do context 'when forward is true', :inline_jobs do let(:forward) { true } - it 'sends ActivityPub payload when forward is true' do - subject.call(source_account, remote_account, forward: forward) - expect(a_request(:post, 'http://example.com/inbox')).to have_been_made - end - - it 'has an uri' do + it 'has a URI and sends ActivityPub payload' do report = subject.call(source_account, remote_account, forward: forward) - expect(report.uri).to_not be_nil + + expect(report.uri) + .to_not be_nil + expect(a_request(:post, 'http://example.com/inbox')) + .to have_been_made end context 'when reporting a reply on a different remote server' do @@ -122,13 +121,12 @@ RSpec.describe ReportService do status.mentions.create(account: source_account) end - it 'creates a report' do - expect { subject.call }.to change { target_account.targeted_reports.count }.from(0).to(1) - end + it 'creates a report and attaches the DM to the report' do + expect { subject.call } + .to change { target_account.targeted_reports.count }.from(0).to(1) - it 'attaches the DM to the report' do - subject.call - expect(target_account.targeted_reports.pluck(:status_ids)).to eq [[status.id]] + expect(target_account.targeted_reports.pluck(:status_ids)) + .to eq [[status.id]] end end @@ -146,13 +144,12 @@ RSpec.describe ReportService do status.mentions.create(account: source_account) end - it 'creates a report' do - expect { subject.call }.to change { target_account.targeted_reports.count }.from(0).to(1) - end + it 'creates a report and attaches DM to report' do + expect { subject.call } + .to change { target_account.targeted_reports.count }.from(0).to(1) - it 'attaches the DM to the report' do - subject.call - expect(target_account.targeted_reports.pluck(:status_ids)).to eq [[status.id]] + expect(target_account.targeted_reports.pluck(:status_ids)) + .to eq [[status.id]] end end diff --git a/spec/services/resolve_account_service_spec.rb b/spec/services/resolve_account_service_spec.rb index a856e019a7..1bd4e9a8e3 100644 --- a/spec/services/resolve_account_service_spec.rb +++ b/spec/services/resolve_account_service_spec.rb @@ -22,37 +22,38 @@ RSpec.describe ResolveAccountService do context 'when domain is banned' do before { Fabricate(:domain_block, domain: 'ap.example.com', severity: :suspend) } - it 'does not return an account' do - expect(subject.call('foo@ap.example.com', skip_webfinger: true)).to be_nil - end - - it 'does not make a webfinger query' do - subject.call('foo@ap.example.com', skip_webfinger: true) - expect(a_request(:get, 'https://ap.example.com/.well-known/webfinger?resource=acct:foo@ap.example.com')).to_not have_been_made + it 'does not return an account or make a webfinger query' do + expect(subject.call('foo@ap.example.com', skip_webfinger: true)) + .to be_nil + expect(webfinger_discovery_request) + .to_not have_been_made end end context 'when domain is not banned' do - it 'returns the expected account' do - expect(subject.call('foo@ap.example.com', skip_webfinger: true)).to eq remote_account - end - - it 'does not make a webfinger query' do - subject.call('foo@ap.example.com', skip_webfinger: true) - expect(a_request(:get, 'https://ap.example.com/.well-known/webfinger?resource=acct:foo@ap.example.com')).to_not have_been_made + it 'returns the expected account and does not make a webfinger query' do + expect(subject.call('foo@ap.example.com', skip_webfinger: true)) + .to eq remote_account + expect(webfinger_discovery_request) + .to_not have_been_made end end end context 'when account is not known' do - it 'does not return an account' do - expect(subject.call('foo@ap.example.com', skip_webfinger: true)).to be_nil + it 'does not return an account and does not make webfinger query' do + expect(subject.call('foo@ap.example.com', skip_webfinger: true)) + .to be_nil + expect(webfinger_discovery_request) + .to_not have_been_made end + end - it 'does not make a webfinger query' do - subject.call('foo@ap.example.com', skip_webfinger: true) - expect(a_request(:get, 'https://ap.example.com/.well-known/webfinger?resource=acct:foo@ap.example.com')).to_not have_been_made - end + def webfinger_discovery_request + a_request( + :get, + 'https://ap.example.com/.well-known/webfinger?resource=acct:foo@ap.example.com' + ) end end @@ -84,13 +85,11 @@ RSpec.describe ResolveAccountService do allow(AccountDeletionWorker).to receive(:perform_async) end - it 'returns nil' do - expect(subject.call('hoge@example.com')).to be_nil - end - - it 'queues account deletion worker' do - subject.call('hoge@example.com') - expect(AccountDeletionWorker).to have_received(:perform_async) + it 'returns nil and queues deletion worker' do + expect(subject.call('hoge@example.com')) + .to be_nil + expect(AccountDeletionWorker) + .to have_received(:perform_async) end end @@ -110,9 +109,12 @@ RSpec.describe ResolveAccountService do it 'returns new remote account' do account = subject.call('Foo@redirected.example.com') - expect(account.activitypub?).to be true - expect(account.acct).to eq 'foo@ap.example.com' - expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox' + expect(account) + .to have_attributes( + activitypub?: true, + acct: 'foo@ap.example.com', + inbox_url: 'https://ap.example.com/users/foo/inbox' + ) end end @@ -125,9 +127,12 @@ RSpec.describe ResolveAccountService do it 'returns new remote account' do account = subject.call('Foo@redirected.example.com') - expect(account.activitypub?).to be true - expect(account.acct).to eq 'foo@ap.example.com' - expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox' + expect(account) + .to have_attributes( + activitypub?: true, + acct: 'foo@ap.example.com', + inbox_url: 'https://ap.example.com/users/foo/inbox' + ) end end @@ -161,9 +166,12 @@ RSpec.describe ResolveAccountService do it 'returns new remote account' do account = subject.call('foo@ap.example.com') - expect(account.activitypub?).to be true - expect(account.domain).to eq 'ap.example.com' - expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox' + expect(account) + .to have_attributes( + activitypub?: true, + domain: 'ap.example.com', + inbox_url: 'https://ap.example.com/users/foo/inbox' + ) end context 'with multiple types' do @@ -174,10 +182,13 @@ RSpec.describe ResolveAccountService do it 'returns new remote account' do account = subject.call('foo@ap.example.com') - expect(account.activitypub?).to be true - expect(account.domain).to eq 'ap.example.com' - expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox' - expect(account.actor_type).to eq 'Person' + expect(account) + .to have_attributes( + activitypub?: true, + domain: 'ap.example.com', + inbox_url: 'https://ap.example.com/users/foo/inbox', + actor_type: 'Person' + ) end end end @@ -186,20 +197,21 @@ RSpec.describe ResolveAccountService do let!(:duplicate) { Fabricate(:account, username: 'foo', domain: 'old.example.com', uri: 'https://ap.example.com/users/foo') } let!(:status) { Fabricate(:status, account: duplicate, text: 'foo') } - it 'returns new remote account' do + it 'returns new remote account and merges accounts', :inline_jobs do account = subject.call('foo@ap.example.com') - expect(account.activitypub?).to be true - expect(account.domain).to eq 'ap.example.com' - expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox' - expect(account.uri).to eq 'https://ap.example.com/users/foo' - end + expect(account) + .to have_attributes( + activitypub?: true, + domain: 'ap.example.com', + inbox_url: 'https://ap.example.com/users/foo/inbox', + uri: 'https://ap.example.com/users/foo' + ) - it 'merges accounts', :inline_jobs do - account = subject.call('foo@ap.example.com') - - expect(status.reload.account_id).to eq account.id - expect(Account.where(uri: account.uri).count).to eq 1 + expect(status.reload.account_id) + .to eq account.id + expect(Account.where(uri: account.uri).count) + .to eq 1 end end @@ -210,11 +222,15 @@ RSpec.describe ResolveAccountService do it 'returns new remote account' do account = subject.call('foo@ap.example.com') - expect(account.activitypub?).to be true - expect(account.domain).to eq 'ap.example.com' - expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox' - expect(account.uri).to eq 'https://ap.example.com/users/foo' - expect(status.reload.account).to eq(account) + expect(account) + .to have_attributes( + activitypub?: true, + domain: 'ap.example.com', + inbox_url: 'https://ap.example.com/users/foo/inbox', + uri: 'https://ap.example.com/users/foo' + ) + expect(status.reload.account) + .to eq(account) end end diff --git a/spec/services/resolve_url_service_spec.rb b/spec/services/resolve_url_service_spec.rb index 80f2a5a4ba..eaf00c1ed8 100644 --- a/spec/services/resolve_url_service_spec.rb +++ b/spec/services/resolve_url_service_spec.rb @@ -51,12 +51,11 @@ RSpec.describe ResolveURLService do let(:url) { 'https://example.com/@foo/42' } let(:uri) { 'https://example.com/users/foo/statuses/42' } - it 'returns status by url' do - expect(subject.call(url, on_behalf_of: account)).to eq(status) - end - - it 'returns status by uri' do - expect(subject.call(uri, on_behalf_of: account)).to eq(status) + it 'returns status by URL or URI' do + expect(subject.call(url, on_behalf_of: account)) + .to eq(status) + expect(subject.call(uri, on_behalf_of: account)) + .to eq(status) end end @@ -75,12 +74,11 @@ RSpec.describe ResolveURLService do let(:url) { 'https://example.com/@foo/42' } let(:uri) { 'https://example.com/users/foo/statuses/42' } - it 'does not return the status by url' do - expect(subject.call(url, on_behalf_of: account)).to be_nil - end - - it 'does not return the status by uri' do - expect(subject.call(uri, on_behalf_of: account)).to be_nil + it 'does not return the status by URL or URI' do + expect(subject.call(url, on_behalf_of: account)) + .to be_nil + expect(subject.call(uri, on_behalf_of: account)) + .to be_nil end end @@ -107,22 +105,20 @@ RSpec.describe ResolveURLService do account.follow!(poster) end - it 'returns status by url' do - expect(subject.call(url, on_behalf_of: account)).to eq(status) - end - - it 'returns status by uri' do - expect(subject.call(uri, on_behalf_of: account)).to eq(status) + it 'returns status by URL or URI' do + expect(subject.call(url, on_behalf_of: account)) + .to eq(status) + expect(subject.call(uri, on_behalf_of: account)) + .to eq(status) end end context 'when the account does not follow the poster' do - it 'does not return the status by url' do - expect(subject.call(url, on_behalf_of: account)).to be_nil - end - - it 'does not return the status by uri' do - expect(subject.call(uri, on_behalf_of: account)).to be_nil + it 'does not return the status by URL or URI' do + expect(subject.call(url, on_behalf_of: account)) + .to be_nil + expect(subject.call(uri, on_behalf_of: account)) + .to be_nil end end end diff --git a/spec/services/translate_status_service_spec.rb b/spec/services/translate_status_service_spec.rb index 0779fbbe6c..cd92fb8d10 100644 --- a/spec/services/translate_status_service_spec.rb +++ b/spec/services/translate_status_service_spec.rb @@ -32,20 +32,14 @@ RSpec.describe TranslateStatusService do allow(TranslationService).to receive_messages(configured?: true, configured: translation_service) end - it 'returns translated status content' do - expect(service.call(status, 'es').content).to eq '

Hola

' - end - - it 'returns source language' do - expect(service.call(status, 'es').detected_source_language).to eq 'en' - end - - it 'returns translation provider' do - expect(service.call(status, 'es').provider).to eq 'Dummy' - end - - it 'returns original status' do - expect(service.call(status, 'es').status).to eq status + it 'returns translated status content and source language and provider and original status' do + expect(service.call(status, 'es')) + .to have_attributes( + content: '

Hola

', + detected_source_language: 'en', + provider: 'Dummy', + status: status + ) end describe 'status has content with custom emoji' do @@ -155,26 +149,16 @@ RSpec.describe TranslateStatusService do let!(:source_texts) { service.send(:source_texts) } it 'returns formatted poll options' do - expect(source_texts.size).to eq 3 - expect(source_texts.values).to eq %w(

Hello

Blue Green) - end - - it 'has a first key with content' do - expect(source_texts.keys.first).to eq :content - end - - it 'has the first option in the second key with correct options' do - option1 = source_texts.keys.second - expect(option1).to be_a Poll::Option - expect(option1.id).to eq '0' - expect(option1.title).to eq 'Blue' - end - - it 'has the second option in the third key with correct options' do - option2 = source_texts.keys.third - expect(option2).to be_a Poll::Option - expect(option2.id).to eq '1' - expect(option2.title).to eq 'Green' + expect(source_texts) + .to have_attributes( + size: 3, + values: %w(

Hello

Blue Green), + keys: contain_exactly( + eq(:content), + be_a(Poll::Option).and(have_attributes(id: '0', title: 'Blue')), + be_a(Poll::Option).and(have_attributes(id: '1', title: 'Green')) + ) + ) end end end diff --git a/spec/services/unblock_domain_service_spec.rb b/spec/services/unblock_domain_service_spec.rb index 405fe1cfd2..daa1d480a6 100644 --- a/spec/services/unblock_domain_service_spec.rb +++ b/spec/services/unblock_domain_service_spec.rb @@ -12,26 +12,32 @@ RSpec.describe UnblockDomainService do let!(:silenced) { Fabricate(:account, domain: 'example.com', silenced_at: domain_block.created_at) } let!(:suspended) { Fabricate(:account, domain: 'example.com', suspended_at: domain_block.created_at) } - it 'unsilences accounts and removes block' do - domain_block.update(severity: :silence) + context 'with severity of silence' do + before { domain_block.update(severity: :silence) } - subject.call(domain_block) - expect_deleted_domain_block - expect(silenced.reload.silenced?).to be false - expect(suspended.reload.suspended?).to be true - expect(independently_suspended.reload.suspended?).to be true - expect(independently_silenced.reload.silenced?).to be true + it 'unsilences accounts and removes block' do + subject.call(domain_block) + + expect_deleted_domain_block + expect(silenced.reload.silenced?).to be false + expect(suspended.reload.suspended?).to be true + expect(independently_suspended.reload.suspended?).to be true + expect(independently_silenced.reload.silenced?).to be true + end end - it 'unsuspends accounts and removes block' do - domain_block.update(severity: :suspend) + context 'with severity of suspend' do + before { domain_block.update(severity: :suspend) } - subject.call(domain_block) - expect_deleted_domain_block - expect(suspended.reload.suspended?).to be false - expect(silenced.reload.silenced?).to be false - expect(independently_suspended.reload.suspended?).to be true - expect(independently_silenced.reload.silenced?).to be true + it 'unsuspends accounts and removes block' do + subject.call(domain_block) + + expect_deleted_domain_block + expect(suspended.reload.suspended?).to be false + expect(silenced.reload.silenced?).to be false + expect(independently_suspended.reload.suspended?).to be true + expect(independently_silenced.reload.silenced?).to be true + end end end diff --git a/spec/services/unblock_service_spec.rb b/spec/services/unblock_service_spec.rb index 6132e74415..a2c5188f06 100644 --- a/spec/services/unblock_service_spec.rb +++ b/spec/services/unblock_service_spec.rb @@ -10,13 +10,13 @@ RSpec.describe UnblockService do describe 'local' do let(:bob) { Fabricate(:account) } - before do - sender.block!(bob) - subject.call(sender, bob) - end + before { sender.block!(bob) } it 'destroys the blocking relation' do - expect(sender.blocking?(bob)).to be false + subject.call(sender, bob) + + expect(sender) + .to_not be_blocking(bob) end end @@ -26,15 +26,15 @@ RSpec.describe UnblockService do before do sender.block!(bob) stub_request(:post, 'http://example.com/inbox').to_return(status: 200) + end + + it 'destroys the blocking relation and sends unblock activity', :inline_jobs do subject.call(sender, bob) - end - it 'destroys the blocking relation' do - expect(sender.blocking?(bob)).to be false - end - - it 'sends an unblock activity', :inline_jobs do - expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once + expect(sender) + .to_not be_blocking(bob) + expect(a_request(:post, 'http://example.com/inbox')) + .to have_been_made.once end end end diff --git a/spec/services/unfollow_service_spec.rb b/spec/services/unfollow_service_spec.rb index 0c206c4b98..6cf24ca5e1 100644 --- a/spec/services/unfollow_service_spec.rb +++ b/spec/services/unfollow_service_spec.rb @@ -10,13 +10,13 @@ RSpec.describe UnfollowService do describe 'local' do let(:bob) { Fabricate(:account, username: 'bob') } - before do - sender.follow!(bob) - subject.call(sender, bob) - end + before { sender.follow!(bob) } it 'destroys the following relation' do - expect(sender.following?(bob)).to be false + subject.call(sender, bob) + + expect(sender) + .to_not be_following(bob) end end @@ -26,15 +26,15 @@ RSpec.describe UnfollowService do before do sender.follow!(bob) stub_request(:post, 'http://example.com/inbox').to_return(status: 200) + end + + it 'destroys the following relation and sends unfollow activity' do subject.call(sender, bob) - end - it 'destroys the following relation' do - expect(sender.following?(bob)).to be false - end - - it 'sends an unfollow activity' do - expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once + expect(sender) + .to_not be_following(bob) + expect(a_request(:post, 'http://example.com/inbox')) + .to have_been_made.once end end @@ -44,15 +44,15 @@ RSpec.describe UnfollowService do before do bob.follow!(sender) stub_request(:post, 'http://example.com/inbox').to_return(status: 200) + end + + it 'destroys the following relation and sends a reject activity' do subject.call(bob, sender) - end - it 'destroys the following relation' do - expect(bob.following?(sender)).to be false - end - - it 'sends a reject activity' do - expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once + expect(sender) + .to_not be_following(bob) + expect(a_request(:post, 'http://example.com/inbox')) + .to have_been_made.once end end end diff --git a/spec/services/update_account_service_spec.rb b/spec/services/update_account_service_spec.rb index d066db481e..f9059af07f 100644 --- a/spec/services/update_account_service_spec.rb +++ b/spec/services/update_account_service_spec.rb @@ -18,23 +18,19 @@ RSpec.describe UpdateAccountService do FollowService.new.call(alice, account) FollowService.new.call(bob, account) FollowService.new.call(eve, account) + end + it 'auto accepts pending follow requests from appropriate accounts' do subject.call(account, { locked: false }) - end - it 'auto-accepts pending follow requests' do - expect(alice.following?(account)).to be true - expect(alice.requested?(account)).to be false - end + expect(alice).to be_following(account) + expect(alice).to_not be_requested(account) - it 'does not auto-accept pending follow requests from silenced users' do - expect(bob.following?(account)).to be false - expect(bob.requested?(account)).to be true - end + expect(bob).to_not be_following(account) + expect(bob).to be_requested(account) - it 'auto-accepts pending follow requests from muted users so as to not leak mute' do - expect(eve.following?(account)).to be true - expect(eve.requested?(account)).to be false + expect(eve).to be_following(account) + expect(eve).to_not be_requested(account) end end end diff --git a/spec/services/update_status_service_spec.rb b/spec/services/update_status_service_spec.rb index de06fb13c6..7c92adeffd 100644 --- a/spec/services/update_status_service_spec.rb +++ b/spec/services/update_status_service_spec.rb @@ -10,15 +10,15 @@ RSpec.describe UpdateStatusService do before do allow(ActivityPub::DistributionWorker).to receive(:perform_async) + end + + it 'does not create an edit or notify anyone' do subject.call(status, status.account_id, text: 'Foo') - end - it 'does not create an edit' do - expect(status.reload.edits).to be_empty - end - - it 'does not notify anyone' do - expect(ActivityPub::DistributionWorker).to_not have_received(:perform_async) + expect(status.reload.edits) + .to be_empty + expect(ActivityPub::DistributionWorker) + .to_not have_received(:perform_async) end end @@ -28,18 +28,16 @@ RSpec.describe UpdateStatusService do before do PreviewCardsStatus.create(status: status, preview_card: preview_card) + end + + it 'updates text, resets card, saves edit history' do subject.call(status, status.account_id, text: 'Bar') - end - it 'updates text' do - expect(status.reload.text).to eq 'Bar' - end - - it 'resets preview card' do - expect(status.reload.preview_card).to be_nil - end - - it 'saves edit history' do + expect(status.reload) + .to have_attributes( + text: 'Bar', + preview_card: be_nil + ) expect(status.edits.ordered.pluck(:text)).to eq %w(Foo Bar) end end @@ -50,15 +48,15 @@ RSpec.describe UpdateStatusService do before do PreviewCardsStatus.create(status: status, preview_card: preview_card) + end + + it 'updates content warning and saves history' do subject.call(status, status.account_id, text: 'Foo', spoiler_text: 'Bar') - end - it 'updates content warning' do - expect(status.reload.spoiler_text).to eq 'Bar' - end - - it 'saves edit history' do - expect(status.edits.ordered.pluck(:text, :spoiler_text)).to eq [['Foo', ''], ['Foo', 'Bar']] + expect(status.reload.spoiler_text) + .to eq 'Bar' + expect(status.edits.ordered.pluck(:text, :spoiler_text)) + .to eq [['Foo', ''], ['Foo', 'Bar']] end end @@ -69,23 +67,19 @@ RSpec.describe UpdateStatusService do before do status.media_attachments << detached_media_attachment + end + + it 'updates media attachments, handles attachments, saves history' do subject.call(status, status.account_id, text: 'Foo', media_ids: [attached_media_attachment.id.to_s]) - end - it 'updates media attachments' do - expect(status.ordered_media_attachments).to eq [attached_media_attachment] - end - - it 'does not detach detached media attachments' do - expect(detached_media_attachment.reload.status_id).to eq status.id - end - - it 'attaches attached media attachments' do - expect(attached_media_attachment.reload.status_id).to eq status.id - end - - it 'saves edit history' do - expect(status.edits.ordered.pluck(:ordered_media_attachment_ids)).to eq [[detached_media_attachment.id], [attached_media_attachment.id]] + expect(status.ordered_media_attachments) + .to eq [attached_media_attachment] + expect(detached_media_attachment.reload.status_id) + .to eq status.id + expect(attached_media_attachment.reload.status_id) + .to eq status.id + expect(status.edits.ordered.pluck(:ordered_media_attachment_ids)) + .to eq [[detached_media_attachment.id], [attached_media_attachment.id]] end end @@ -95,19 +89,18 @@ RSpec.describe UpdateStatusService do before do status.media_attachments << media_attachment + end + + it 'does not detach media attachment, updates description, and saves history' do subject.call(status, status.account_id, text: 'Foo', media_ids: [media_attachment.id.to_s], media_attributes: [{ id: media_attachment.id, description: 'New description' }]) - end - it 'does not detach media attachment' do - expect(media_attachment.reload.status_id).to eq status.id - end - - it 'updates the media attachment description' do - expect(media_attachment.reload.description).to eq 'New description' - end - - it 'saves edit history' do - expect(status.edits.ordered.map { |edit| edit.ordered_media_attachments.map(&:description) }).to eq [['Old description'], ['New description']] + expect(media_attachment.reload) + .to have_attributes( + status_id: status.id, + description: 'New description' + ) + expect(status.edits.ordered.map { |edit| edit.ordered_media_attachments.map(&:description) }) + .to eq [['Old description'], ['New description']] end end @@ -120,28 +113,27 @@ RSpec.describe UpdateStatusService do before do status.update(poll: poll) VoteService.new.call(voter, poll, [0]) + end + + it 'updates poll, resets votes, saves history, requeues notifications' do subject.call(status, status.account_id, text: 'Foo', poll: { options: %w(Bar Baz Foo), expires_in: 5.days.to_i }) - end - it 'updates poll' do poll = status.poll.reload - expect(poll.options).to eq %w(Bar Baz Foo) - end - it 'resets votes' do - poll = status.poll.reload - expect(poll.votes_count).to eq 0 - expect(poll.votes.count).to eq 0 - expect(poll.cached_tallies).to eq [0, 0, 0] - end + expect(poll) + .to have_attributes( + options: %w(Bar Baz Foo), + votes_count: 0, + cached_tallies: [0, 0, 0] + ) + expect(poll.votes.count) + .to eq(0) - it 'saves edit history' do - expect(status.edits.ordered.pluck(:poll_options)).to eq [%w(Foo Bar), %w(Bar Baz Foo)] - end + expect(status.edits.ordered.pluck(:poll_options)) + .to eq [%w(Foo Bar), %w(Bar Baz Foo)] - it 'requeues expiration notification' do - poll = status.poll.reload - expect(PollExpirationNotifyWorker).to have_enqueued_sidekiq_job(poll.id).at(poll.expires_at + 5.minutes) + expect(PollExpirationNotifyWorker) + .to have_enqueued_sidekiq_job(poll.id).at(poll.expires_at + 5.minutes) end end @@ -151,16 +143,13 @@ RSpec.describe UpdateStatusService do let!(:bob) { Fabricate(:account, username: 'bob') } let!(:status) { PostStatusService.new.call(account, text: 'Hello @alice') } - before do + it 'changes mentions and keeps old as silent' do subject.call(status, status.account_id, text: 'Hello @bob') - end - it 'changes mentions' do - expect(status.active_mentions.pluck(:account_id)).to eq [bob.id] - end - - it 'keeps old mentions as silent mentions' do - expect(status.mentions.pluck(:account_id)).to contain_exactly(alice.id, bob.id) + expect(status.active_mentions.pluck(:account_id)) + .to eq [bob.id] + expect(status.mentions.pluck(:account_id)) + .to contain_exactly(alice.id, bob.id) end end @@ -168,11 +157,9 @@ RSpec.describe UpdateStatusService do let!(:account) { Fabricate(:account) } let!(:status) { PostStatusService.new.call(account, text: 'Hello #foo') } - before do - subject.call(status, status.account_id, text: 'Hello #bar') - end - it 'changes tags' do + subject.call(status, status.account_id, text: 'Hello #bar') + expect(status.tags.pluck(:name)).to eq %w(bar) end end From ebdeac0731c31b73438aaa369a234d9ac5798b43 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 4 Oct 2024 10:15:14 -0400 Subject: [PATCH 076/150] Add coverage for missing status scenario in NotificationMailer (#32256) --- app/mailers/notification_mailer.rb | 2 +- spec/mailers/notification_mailer_spec.rb | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/mailers/notification_mailer.rb b/app/mailers/notification_mailer.rb index 4c374f5d57..a20992dcb5 100644 --- a/app/mailers/notification_mailer.rb +++ b/app/mailers/notification_mailer.rb @@ -86,7 +86,7 @@ class NotificationMailer < ApplicationMailer end def thread_by_conversation! - return if @status.conversation.nil? + return if @status&.conversation.nil? conversation_message_id = "" diff --git a/spec/mailers/notification_mailer_spec.rb b/spec/mailers/notification_mailer_spec.rb index 4c6107d9f7..d97c01858d 100644 --- a/spec/mailers/notification_mailer_spec.rb +++ b/spec/mailers/notification_mailer_spec.rb @@ -14,6 +14,17 @@ RSpec.describe NotificationMailer do end end + shared_examples 'delivery without status' do + context 'when notification target_status is missing' do + before { allow(notification).to receive(:target_status).and_return(nil) } + + it 'does not deliver mail' do + emails = capture_emails { mail.deliver_now } + expect(emails).to be_empty + end + end + end + let(:receiver) { Fabricate(:user, account_attributes: { username: 'alice' }) } let(:sender) { Fabricate(:account, username: 'bob') } let(:foreign_status) { Fabricate(:status, account: sender, text: 'The body of the foreign status') } @@ -37,6 +48,7 @@ RSpec.describe NotificationMailer do end include_examples 'delivery to non functional user' + include_examples 'delivery without status' end describe 'follow' do @@ -75,6 +87,7 @@ RSpec.describe NotificationMailer do end include_examples 'delivery to non functional user' + include_examples 'delivery without status' end describe 'reblog' do @@ -95,6 +108,7 @@ RSpec.describe NotificationMailer do end include_examples 'delivery to non functional user' + include_examples 'delivery without status' end describe 'follow_request' do From 1f720366e94c175f171156a86d65787d6f0d7ba6 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 4 Oct 2024 16:29:23 +0200 Subject: [PATCH 077/150] Fix notification push notifications not including the author's username (#32254) --- app/javascript/mastodon/locales/en.json | 1 + .../mastodon/service_worker/web_push_locales.js | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 1e78745359..7f8dc74779 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Private reply", "notification.label.reply": "Reply", "notification.mention": "Mention", + "notification.mentioned_you": "{name} mentioned you", "notification.moderation-warning.learn_more": "Learn more", "notification.moderation_warning": "You have received a moderation warning", "notification.moderation_warning.action_delete_statuses": "Some of your posts have been removed.", diff --git a/app/javascript/mastodon/service_worker/web_push_locales.js b/app/javascript/mastodon/service_worker/web_push_locales.js index 89ae20007b..3e39c9a4ed 100644 --- a/app/javascript/mastodon/service_worker/web_push_locales.js +++ b/app/javascript/mastodon/service_worker/web_push_locales.js @@ -6,6 +6,12 @@ const fs = require('fs'); const path = require('path'); +const { defineMessages } = require('react-intl'); + +const messages = defineMessages({ + mentioned_you: { id: 'notification.mentioned_you', defaultMessage: '{name} mentioned you' }, +}); + const filtered = {}; const filenames = fs.readdirSync(path.resolve(__dirname, '../locales')); @@ -20,7 +26,7 @@ filenames.forEach(filename => { 'notification.favourite': full['notification.favourite'] || '', 'notification.follow': full['notification.follow'] || '', 'notification.follow_request': full['notification.follow_request'] || '', - 'notification.mention': full['notification.mention'] || '', + 'notification.mention': full[messages.mentioned_you.id] || '', 'notification.reblog': full['notification.reblog'] || '', 'notification.poll': full['notification.poll'] || '', 'notification.status': full['notification.status'] || '', From 51769e06708f79a485c444d139cbdbdd7249b0cb Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 4 Oct 2024 16:55:44 +0200 Subject: [PATCH 078/150] Fix media gallery items having incorrect borders when hidden (#32257) --- app/javascript/mastodon/components/media_gallery.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/components/media_gallery.jsx b/app/javascript/mastodon/components/media_gallery.jsx index 1380d244ad..e059978442 100644 --- a/app/javascript/mastodon/components/media_gallery.jsx +++ b/app/javascript/mastodon/components/media_gallery.jsx @@ -336,14 +336,14 @@ class MediaGallery extends PureComponent { return (
+ {children} + {(!visible || uncached) && (
{spoilerButton}
)} - {children} - {(visible && !uncached) && (
From c40ab43dc703be988c277d4ba6b7987a3a80e16c Mon Sep 17 00:00:00 2001 From: Christian Schmidt Date: Fri, 4 Oct 2024 18:23:05 +0200 Subject: [PATCH 079/150] Remove redundant title attribute (#32258) --- .../mastodon/features/ui/components/column_link.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/features/ui/components/column_link.jsx b/app/javascript/mastodon/features/ui/components/column_link.jsx index 3386c17f07..f27ed50675 100644 --- a/app/javascript/mastodon/features/ui/components/column_link.jsx +++ b/app/javascript/mastodon/features/ui/components/column_link.jsx @@ -15,7 +15,7 @@ const ColumnLink = ({ icon, activeIcon, iconComponent, activeIconComponent, text if (href) { return ( - + {active ? activeIconElement : iconElement} {text} {badgeElement} @@ -23,7 +23,7 @@ const ColumnLink = ({ icon, activeIcon, iconComponent, activeIconComponent, text ); } else { return ( - + {active ? activeIconElement : iconElement} {text} {badgeElement} From 8572fa14526b9f28600ec7694000fb2f05200be0 Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Tue, 1 Oct 2024 10:22:14 +0200 Subject: [PATCH 080/150] [Glitch] Fix follow notifications from streaming being grouped Port 1be55ce24418ea149a9ca0def237a76f4c6501af to glitch-soc Signed-off-by: Claire --- .../glitch/actions/notification_groups.ts | 4 + .../glitch/reducers/notification_groups.ts | 79 ++++++++++--------- 2 files changed, 46 insertions(+), 37 deletions(-) diff --git a/app/javascript/flavours/glitch/actions/notification_groups.ts b/app/javascript/flavours/glitch/actions/notification_groups.ts index eebf6ce7a2..e39c9d6846 100644 --- a/app/javascript/flavours/glitch/actions/notification_groups.ts +++ b/app/javascript/flavours/glitch/actions/notification_groups.ts @@ -70,6 +70,10 @@ function dispatchAssociatedRecords( const supportedGroupedNotificationTypes = ['favourite', 'reblog']; +export function shouldGroupNotificationType(type: string) { + return supportedGroupedNotificationTypes.includes(type); +} + export const fetchNotifications = createDataLoadingThunk( 'notificationGroups/fetch', async (_params, { getState }) => diff --git a/app/javascript/flavours/glitch/reducers/notification_groups.ts b/app/javascript/flavours/glitch/reducers/notification_groups.ts index 30f7b58737..a2ba9a4f17 100644 --- a/app/javascript/flavours/glitch/reducers/notification_groups.ts +++ b/app/javascript/flavours/glitch/reducers/notification_groups.ts @@ -21,6 +21,7 @@ import { unmountNotifications, refreshStaleNotificationGroups, pollRecentNotifications, + shouldGroupNotificationType, } from 'flavours/glitch/actions/notification_groups'; import { disconnectTimeline, @@ -205,46 +206,50 @@ function processNewNotification( groups: NotificationGroupsState['groups'], notification: ApiNotificationJSON, ) { - const existingGroupIndex = groups.findIndex( - (group) => - group.type !== 'gap' && group.group_key === notification.group_key, - ); + if (shouldGroupNotificationType(notification.type)) { + const existingGroupIndex = groups.findIndex( + (group) => + group.type !== 'gap' && group.group_key === notification.group_key, + ); - // In any case, we are going to add a group at the top - // If there is currently a gap at the top, now is the time to update it - if (groups.length > 0 && groups[0]?.type === 'gap') { - groups[0].maxId = notification.id; - } - - if (existingGroupIndex > -1) { - const existingGroup = groups[existingGroupIndex]; - - if ( - existingGroup && - existingGroup.type !== 'gap' && - !existingGroup.sampleAccountIds.includes(notification.account.id) // This can happen for example if you like, then unlike, then like again the same post - ) { - // Update the existing group - if ( - existingGroup.sampleAccountIds.unshift(notification.account.id) > - NOTIFICATIONS_GROUP_MAX_AVATARS - ) - existingGroup.sampleAccountIds.pop(); - - existingGroup.most_recent_notification_id = notification.id; - existingGroup.page_max_id = notification.id; - existingGroup.latest_page_notification_at = notification.created_at; - existingGroup.notifications_count += 1; - - groups.splice(existingGroupIndex, 1); - mergeGapsAround(groups, existingGroupIndex); - - groups.unshift(existingGroup); + // In any case, we are going to add a group at the top + // If there is currently a gap at the top, now is the time to update it + if (groups.length > 0 && groups[0]?.type === 'gap') { + groups[0].maxId = notification.id; + } + + if (existingGroupIndex > -1) { + const existingGroup = groups[existingGroupIndex]; + + if ( + existingGroup && + existingGroup.type !== 'gap' && + !existingGroup.sampleAccountIds.includes(notification.account.id) // This can happen for example if you like, then unlike, then like again the same post + ) { + // Update the existing group + if ( + existingGroup.sampleAccountIds.unshift(notification.account.id) > + NOTIFICATIONS_GROUP_MAX_AVATARS + ) + existingGroup.sampleAccountIds.pop(); + + existingGroup.most_recent_notification_id = notification.id; + existingGroup.page_max_id = notification.id; + existingGroup.latest_page_notification_at = notification.created_at; + existingGroup.notifications_count += 1; + + groups.splice(existingGroupIndex, 1); + mergeGapsAround(groups, existingGroupIndex); + + groups.unshift(existingGroup); + + return; + } } - } else { - // Create a new group - groups.unshift(createNotificationGroupFromNotificationJSON(notification)); } + + // We have not found an existing group, create a new one + groups.unshift(createNotificationGroupFromNotificationJSON(notification)); } function trimNotifications(state: NotificationGroupsState) { From edfa716a18f133743adabc829f4cfdbe9a255bb0 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 05:08:29 -0400 Subject: [PATCH 081/150] [Glitch] Improve alignment of icons on admin roles list Port f811fcb2b2749d1e7a30ee7558ddff9d01e86e70 to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/styles/admin.scss | 4 ++++ app/javascript/flavours/glitch/styles/tables.scss | 1 + 2 files changed, 5 insertions(+) diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss index c4a16247b8..0cd3789fb8 100644 --- a/app/javascript/flavours/glitch/styles/admin.scss +++ b/app/javascript/flavours/glitch/styles/admin.scss @@ -1075,6 +1075,10 @@ a.name-tag, } } + .icon { + vertical-align: middle; + } + a.announcements-list__item__title { &:hover, &:focus, diff --git a/app/javascript/flavours/glitch/styles/tables.scss b/app/javascript/flavours/glitch/styles/tables.scss index c84f672a6f..75fc29aed5 100644 --- a/app/javascript/flavours/glitch/styles/tables.scss +++ b/app/javascript/flavours/glitch/styles/tables.scss @@ -137,6 +137,7 @@ a.table-action-link { padding: 0 10px; color: $darker-text-color; font-weight: 500; + white-space: nowrap; &:hover { color: $highlight-text-color; From af39ac6edc00e4e27f94ddd85fac6502fb386022 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 1 Oct 2024 09:41:25 -0400 Subject: [PATCH 082/150] [Glitch] Adjust spacing on setting sub-nav items when below mobile size Port f10d61bf86559bc1464b2e7972b8980ae789908d Signed-off-by: Claire --- app/javascript/flavours/glitch/styles/admin.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss index 0cd3789fb8..9bc3c7758e 100644 --- a/app/javascript/flavours/glitch/styles/admin.scss +++ b/app/javascript/flavours/glitch/styles/admin.scss @@ -226,6 +226,10 @@ $content-width: 840px; gap: 5px; white-space: nowrap; + @media screen and (max-width: $mobile-breakpoint) { + flex: 1 0 50%; + } + &:hover, &:focus, &:active { From 61a0c58dee383bf79a3b6ff6c08f82a34710d8dd Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Tue, 1 Oct 2024 12:26:30 -0400 Subject: [PATCH 083/150] [Glitch] Enable ESLlint no-case-declarations Port f91f077985eccf9933346052ce4ee532215099c6 to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/actions/streaming.js | 3 ++- .../flavours/glitch/components/status_content.jsx | 3 ++- app/javascript/flavours/glitch/reducers/compose.js | 6 ++++-- app/javascript/flavours/glitch/reducers/notifications.js | 3 ++- app/javascript/flavours/glitch/reducers/search.js | 3 ++- app/javascript/flavours/glitch/utils/resize_image.js | 6 ++++-- 6 files changed, 16 insertions(+), 8 deletions(-) diff --git a/app/javascript/flavours/glitch/actions/streaming.js b/app/javascript/flavours/glitch/actions/streaming.js index 7948984fba..fa7af7055e 100644 --- a/app/javascript/flavours/glitch/actions/streaming.js +++ b/app/javascript/flavours/glitch/actions/streaming.js @@ -106,12 +106,13 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti dispatch(processNewNotificationForGroups(notificationJSON)); break; } - case 'notifications_merged': + case 'notifications_merged': { const state = getState(); if (state.notifications.top || !state.notifications.mounted) dispatch(expandNotifications({ forceLoad: true, maxId: undefined })); dispatch(refreshStaleNotificationGroups()); break; + } case 'conversation': // @ts-expect-error dispatch(updateConversations(JSON.parse(data.payload))); diff --git a/app/javascript/flavours/glitch/components/status_content.jsx b/app/javascript/flavours/glitch/components/status_content.jsx index d6dfd9f490..a15a4df25a 100644 --- a/app/javascript/flavours/glitch/components/status_content.jsx +++ b/app/javascript/flavours/glitch/components/status_content.jsx @@ -41,7 +41,7 @@ const isLinkMisleading = (link) => { case Node.TEXT_NODE: linkTextParts.push(node.textContent); break; - case Node.ELEMENT_NODE: + case Node.ELEMENT_NODE: { if (node.classList.contains('invisible')) return; const children = node.childNodes; for (let i = 0; i < children.length; i++) { @@ -49,6 +49,7 @@ const isLinkMisleading = (link) => { } break; } + } }; walk(link); diff --git a/app/javascript/flavours/glitch/reducers/compose.js b/app/javascript/flavours/glitch/reducers/compose.js index 211402ab2a..836ad10862 100644 --- a/app/javascript/flavours/glitch/reducers/compose.js +++ b/app/javascript/flavours/glitch/reducers/compose.js @@ -512,7 +512,7 @@ export default function compose(state = initialState, action) { return item; })); - case INIT_MEDIA_EDIT_MODAL: + case INIT_MEDIA_EDIT_MODAL: { const media = state.get('media_attachments').find(item => item.get('id') === action.id); return state.set('media_modal', ImmutableMap({ id: action.id, @@ -521,6 +521,7 @@ export default function compose(state = initialState, action) { focusY: media.getIn(['meta', 'focus', 'y'], 0), dirty: false, })); + } case COMPOSE_CHANGE_MEDIA_DESCRIPTION: return state.setIn(['media_modal', 'description'], action.description).setIn(['media_modal', 'dirty'], true); case COMPOSE_CHANGE_MEDIA_FOCUS: @@ -575,7 +576,7 @@ export default function compose(state = initialState, action) { })); case COMPOSE_DOODLE_SET: return state.mergeIn(['doodle'], action.options); - case REDRAFT: + case REDRAFT: { const do_not_federate = !!action.status.get('local_only'); let text = action.raw_text || unescapeHTML(expandMentions(action.status)); if (do_not_federate) text = text.replace(/ ?👁\ufe0f?\u200b?$/, ''); @@ -616,6 +617,7 @@ export default function compose(state = initialState, action) { })); } }); + } case COMPOSE_SET_STATUS: return state.withMutations(map => { map.set('id', action.status.get('id')); diff --git a/app/javascript/flavours/glitch/reducers/notifications.js b/app/javascript/flavours/glitch/reducers/notifications.js index b9773a0da6..8453dd7038 100644 --- a/app/javascript/flavours/glitch/reducers/notifications.js +++ b/app/javascript/flavours/glitch/reducers/notifications.js @@ -369,9 +369,10 @@ export default function notifications(state = initialState, action) { } return markAllForDelete(st, action.yes); - case NOTIFICATIONS_MARK_AS_READ: + case NOTIFICATIONS_MARK_AS_READ: { const lastNotification = state.get('items').find(item => item !== null); return lastNotification ? recountUnread(state, lastNotification.get('id')) : state; + } default: return state; diff --git a/app/javascript/flavours/glitch/reducers/search.js b/app/javascript/flavours/glitch/reducers/search.js index 7828d49eee..7de1c65c07 100644 --- a/app/javascript/flavours/glitch/reducers/search.js +++ b/app/javascript/flavours/glitch/reducers/search.js @@ -72,9 +72,10 @@ export default function search(state = initialState, action) { }); case SEARCH_EXPAND_REQUEST: return state.set('type', action.searchType).set('isLoading', true); - case SEARCH_EXPAND_SUCCESS: + case SEARCH_EXPAND_SUCCESS: { const results = action.searchType === 'hashtags' ? ImmutableOrderedSet(fromJS(action.results.hashtags)) : action.results[action.searchType].map(item => item.id); return state.updateIn(['results', action.searchType], list => list.union(results)).set('isLoading', false); + } case SEARCH_HISTORY_UPDATE: return state.set('recent', ImmutableOrderedSet(fromJS(action.recent))); default: diff --git a/app/javascript/flavours/glitch/utils/resize_image.js b/app/javascript/flavours/glitch/utils/resize_image.js index e3d4e6a354..c579fe5a2c 100644 --- a/app/javascript/flavours/glitch/utils/resize_image.js +++ b/app/javascript/flavours/glitch/utils/resize_image.js @@ -17,7 +17,7 @@ const dropOrientationIfNeeded = (orientation) => new Promise(resolve => { case false: resolve(orientation); break; - default: + default: { // black 2x1 JPEG, with the following meta information set: // - EXIF Orientation: 6 (Rotated 90° CCW) const testImageURL = @@ -39,6 +39,7 @@ const dropOrientationIfNeeded = (orientation) => new Promise(resolve => { }; img.src = testImageURL; } + } }); // Some browsers don't allow reading from a canvas and instead return all-white @@ -52,7 +53,7 @@ const checkCanvasReliability = () => new Promise((resolve, reject) => { case false: resolve(); break; - default: + default: { // 2×2 GIF with white, red, green and blue pixels const testImageURL = 'data:image/gif;base64,R0lGODdhAgACAKEDAAAA//8AAAD/AP///ywAAAAAAgACAAACA1wEBQA7'; @@ -78,6 +79,7 @@ const checkCanvasReliability = () => new Promise((resolve, reject) => { }; img.src = testImageURL; } + } }); const getImageUrl = inputFile => new Promise((resolve, reject) => { From ce3bedade30342daed6ef8d3c31abceecc8615bd Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 2 Oct 2024 12:03:04 +0200 Subject: [PATCH 084/150] [Glitch] Fix incorrect `'navigator'` check Port 4a737a948a6aa8803ba366374569a93970437ec7 to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/actions/markers.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/javascript/flavours/glitch/actions/markers.ts b/app/javascript/flavours/glitch/actions/markers.ts index 37067dbcf7..ea325109c5 100644 --- a/app/javascript/flavours/glitch/actions/markers.ts +++ b/app/javascript/flavours/glitch/actions/markers.ts @@ -37,8 +37,7 @@ export const synchronouslySubmitMarkers = createAppAsyncThunk( }); return; - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - } else if ('navigator' && 'sendBeacon' in navigator) { + } else if ('sendBeacon' in navigator) { // Failing that, we can use sendBeacon, but we have to encode the data as // FormData for DoorKeeper to recognize the token. const formData = new FormData(); From 54b209243b0fe372ab21a527df2e920a6afe2784 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 2 Oct 2024 15:28:36 +0200 Subject: [PATCH 085/150] [Glitch] Fix media uploads in composer appearing over search results in advanced interface Port b5006539c995cbefda04db25888ffe5bb5995d3f to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/styles/components.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/flavours/glitch/styles/components.scss b/app/javascript/flavours/glitch/styles/components.scss index 72613cbbc4..a17591293f 100644 --- a/app/javascript/flavours/glitch/styles/components.scss +++ b/app/javascript/flavours/glitch/styles/components.scss @@ -3793,6 +3793,7 @@ $ui-header-logo-wordmark-width: 99px; overflow-y: auto; width: 100%; height: 100%; + z-index: 0; } .drawer__inner__mastodon { From 299372babef8831b01576f482a940b4717b36031 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 2 Oct 2024 15:29:23 +0200 Subject: [PATCH 086/150] [Glitch] Fix editing description of media uploads with custom thumbnails Port f760899b04ef5647d8688e9f1f08094fb3cf5894 to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/reducers/compose.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/reducers/compose.js b/app/javascript/flavours/glitch/reducers/compose.js index 836ad10862..16bfacb937 100644 --- a/app/javascript/flavours/glitch/reducers/compose.js +++ b/app/javascript/flavours/glitch/reducers/compose.js @@ -507,7 +507,7 @@ export default function compose(state = initialState, action) { .set('isUploadingThumbnail', false) .update('media_attachments', list => list.map(item => { if (item.get('id') === action.media.id) { - return fromJS(action.media); + return fromJS(action.media).set('unattached', item.get('unattached')); } return item; From b22272fcdce24b26a6cd5c422e8a838b058ab717 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 2 Oct 2024 17:51:05 +0200 Subject: [PATCH 087/150] [Glitch] Hide badges in media gallery when media are hidden Port f768a6eb16880f4e584db530e4106be9b9dcf206 to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/components/media_gallery.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/components/media_gallery.jsx b/app/javascript/flavours/glitch/components/media_gallery.jsx index 4d51bdcdc2..5b1e56185e 100644 --- a/app/javascript/flavours/glitch/components/media_gallery.jsx +++ b/app/javascript/flavours/glitch/components/media_gallery.jsx @@ -198,7 +198,7 @@ class Item extends PureComponent { {visible && thumbnail} - {badges && ( + {visible && badges && (
{badges}
From 819abbdb2fccfa522e8fafefb6fbdfc6ac7e1c85 Mon Sep 17 00:00:00 2001 From: forsamori Date: Fri, 4 Oct 2024 09:02:14 +0100 Subject: [PATCH 088/150] [Glitch] Add margin-bottom to error.dialog to reduce whitespace Port 63a959099b854af62b88d6097895d5a7c1443cb3 to glitch-soc Co-authored-by: Claire Signed-off-by: Claire --- app/javascript/flavours/glitch/styles/basics.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/flavours/glitch/styles/basics.scss b/app/javascript/flavours/glitch/styles/basics.scss index 2223893336..2ecc855b9c 100644 --- a/app/javascript/flavours/glitch/styles/basics.scss +++ b/app/javascript/flavours/glitch/styles/basics.scss @@ -141,6 +141,7 @@ body { width: 100%; height: auto; margin-top: -120px; + margin-bottom: -45px; } } From c720623dc76f435a79c5470f3c7f2b7bce7bb5a4 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 4 Oct 2024 14:23:30 +0200 Subject: [PATCH 089/150] [Glitch] Fix unsupported grouped notifications from streaming causing duplicate IDs Port 77f5b127fadc02ba84fd1d5deccc7b70e68aba59 to glitch-soc Signed-off-by: Claire --- .../glitch/reducers/notification_groups.ts | 87 ++++++++++--------- 1 file changed, 45 insertions(+), 42 deletions(-) diff --git a/app/javascript/flavours/glitch/reducers/notification_groups.ts b/app/javascript/flavours/glitch/reducers/notification_groups.ts index a2ba9a4f17..3eece4b1d0 100644 --- a/app/javascript/flavours/glitch/reducers/notification_groups.ts +++ b/app/javascript/flavours/glitch/reducers/notification_groups.ts @@ -206,50 +206,53 @@ function processNewNotification( groups: NotificationGroupsState['groups'], notification: ApiNotificationJSON, ) { - if (shouldGroupNotificationType(notification.type)) { - const existingGroupIndex = groups.findIndex( - (group) => - group.type !== 'gap' && group.group_key === notification.group_key, - ); - - // In any case, we are going to add a group at the top - // If there is currently a gap at the top, now is the time to update it - if (groups.length > 0 && groups[0]?.type === 'gap') { - groups[0].maxId = notification.id; - } - - if (existingGroupIndex > -1) { - const existingGroup = groups[existingGroupIndex]; - - if ( - existingGroup && - existingGroup.type !== 'gap' && - !existingGroup.sampleAccountIds.includes(notification.account.id) // This can happen for example if you like, then unlike, then like again the same post - ) { - // Update the existing group - if ( - existingGroup.sampleAccountIds.unshift(notification.account.id) > - NOTIFICATIONS_GROUP_MAX_AVATARS - ) - existingGroup.sampleAccountIds.pop(); - - existingGroup.most_recent_notification_id = notification.id; - existingGroup.page_max_id = notification.id; - existingGroup.latest_page_notification_at = notification.created_at; - existingGroup.notifications_count += 1; - - groups.splice(existingGroupIndex, 1); - mergeGapsAround(groups, existingGroupIndex); - - groups.unshift(existingGroup); - - return; - } - } + if (!shouldGroupNotificationType(notification.type)) { + notification = { + ...notification, + group_key: `ungrouped-${notification.id}`, + }; } - // We have not found an existing group, create a new one - groups.unshift(createNotificationGroupFromNotificationJSON(notification)); + const existingGroupIndex = groups.findIndex( + (group) => + group.type !== 'gap' && group.group_key === notification.group_key, + ); + + // In any case, we are going to add a group at the top + // If there is currently a gap at the top, now is the time to update it + if (groups.length > 0 && groups[0]?.type === 'gap') { + groups[0].maxId = notification.id; + } + + if (existingGroupIndex > -1) { + const existingGroup = groups[existingGroupIndex]; + + if ( + existingGroup && + existingGroup.type !== 'gap' && + !existingGroup.sampleAccountIds.includes(notification.account.id) // This can happen for example if you like, then unlike, then like again the same post + ) { + // Update the existing group + if ( + existingGroup.sampleAccountIds.unshift(notification.account.id) > + NOTIFICATIONS_GROUP_MAX_AVATARS + ) + existingGroup.sampleAccountIds.pop(); + + existingGroup.most_recent_notification_id = notification.id; + existingGroup.page_max_id = notification.id; + existingGroup.latest_page_notification_at = notification.created_at; + existingGroup.notifications_count += 1; + + groups.splice(existingGroupIndex, 1); + mergeGapsAround(groups, existingGroupIndex); + + groups.unshift(existingGroup); + } + } else { + // We have not found an existing group, create a new one + groups.unshift(createNotificationGroupFromNotificationJSON(notification)); + } } function trimNotifications(state: NotificationGroupsState) { From 7b40f14452be3a15c9172c776f650eb8e3ef9079 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 4 Oct 2024 16:55:44 +0200 Subject: [PATCH 090/150] [Glitch] Fix media gallery items having incorrect borders when hidden Port 51769e06708f79a485c444d139cbdbdd7249b0cb to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/components/media_gallery.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/javascript/flavours/glitch/components/media_gallery.jsx b/app/javascript/flavours/glitch/components/media_gallery.jsx index 5b1e56185e..f2f8b21e3b 100644 --- a/app/javascript/flavours/glitch/components/media_gallery.jsx +++ b/app/javascript/flavours/glitch/components/media_gallery.jsx @@ -356,14 +356,14 @@ class MediaGallery extends PureComponent { return (
+ {children} + {(!visible || uncached) && (
{spoilerButton}
)} - {children} - {(visible && !uncached) && (
From c37daa11f2b1844a0726f6be580d72781f6b0828 Mon Sep 17 00:00:00 2001 From: Christian Schmidt Date: Fri, 4 Oct 2024 18:23:05 +0200 Subject: [PATCH 091/150] [Glitch] Remove redundant title attribute Port c40ab43dc703be988c277d4ba6b7987a3a80e16c to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/features/ui/components/column_link.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/javascript/flavours/glitch/features/ui/components/column_link.jsx b/app/javascript/flavours/glitch/features/ui/components/column_link.jsx index 452e810a6d..b61e21d9f9 100644 --- a/app/javascript/flavours/glitch/features/ui/components/column_link.jsx +++ b/app/javascript/flavours/glitch/features/ui/components/column_link.jsx @@ -15,7 +15,7 @@ const ColumnLink = ({ icon, activeIcon, iconComponent, activeIconComponent, text if (href) { return ( - + {active ? activeIconElement : iconElement} {text} {badgeElement} @@ -23,7 +23,7 @@ const ColumnLink = ({ icon, activeIcon, iconComponent, activeIconComponent, text ); } else if (to) { return ( - + {active ? activeIconElement : iconElement} {text} {badgeElement} @@ -37,7 +37,7 @@ const ColumnLink = ({ icon, activeIcon, iconComponent, activeIconComponent, text }; return ( // eslint-disable-next-line jsx-a11y/anchor-is-valid -- intentional to have the same look and feel as other menu items - + {iconElement} {text} {badgeElement} From 6967031144c4890ea423154eeeb1d33c2e728540 Mon Sep 17 00:00:00 2001 From: Claire Date: Sun, 6 Oct 2024 18:34:55 +0200 Subject: [PATCH 092/150] Fix video player's height in detailed status view --- .../glitch/features/status/components/detailed_status.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/flavours/glitch/features/status/components/detailed_status.tsx b/app/javascript/flavours/glitch/features/status/components/detailed_status.tsx index dcce9a47de..d1d955395f 100644 --- a/app/javascript/flavours/glitch/features/status/components/detailed_status.tsx +++ b/app/javascript/flavours/glitch/features/status/components/detailed_status.tsx @@ -259,6 +259,7 @@ export const DetailedStatus: React.FC<{ src={attachment.get('url')} alt={description} lang={language} + inline width={300} height={150} onOpenVideo={handleOpenVideo} From 2c54b91dd1a0f0a622ea88628d15c8b1bdda70f7 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 7 Oct 2024 08:53:29 +0200 Subject: [PATCH 093/150] Fix wrong width on logo in detailed link card in web UI (#32271) --- app/javascript/styles/mastodon/components.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 5f410ead93..f257368390 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -10628,6 +10628,7 @@ noscript { gap: 8px; .logo { + width: 16px; height: 16px; color: $darker-text-color; } From 498024558ae8d4111b4c263901dfc105b3563ddc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 09:06:43 +0200 Subject: [PATCH 094/150] New Crowdin Translations (automated) (#32262) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/ca.json | 1 + app/javascript/mastodon/locales/da.json | 1 + app/javascript/mastodon/locales/de.json | 3 +- app/javascript/mastodon/locales/en-GB.json | 5 ++ app/javascript/mastodon/locales/eo.json | 1 + app/javascript/mastodon/locales/es-AR.json | 1 + app/javascript/mastodon/locales/es-MX.json | 11 ++-- app/javascript/mastodon/locales/es.json | 1 + app/javascript/mastodon/locales/fi.json | 1 + app/javascript/mastodon/locales/fo.json | 1 + app/javascript/mastodon/locales/fy.json | 15 +++++ app/javascript/mastodon/locales/gl.json | 1 + app/javascript/mastodon/locales/he.json | 19 +++--- app/javascript/mastodon/locales/hu.json | 1 + app/javascript/mastodon/locales/is.json | 4 ++ app/javascript/mastodon/locales/it.json | 6 ++ app/javascript/mastodon/locales/ja.json | 1 + app/javascript/mastodon/locales/ko.json | 1 + app/javascript/mastodon/locales/nl.json | 9 +-- app/javascript/mastodon/locales/nn.json | 1 + app/javascript/mastodon/locales/pl.json | 1 + app/javascript/mastodon/locales/pt-BR.json | 1 + app/javascript/mastodon/locales/sq.json | 1 + app/javascript/mastodon/locales/sv.json | 1 + app/javascript/mastodon/locales/th.json | 1 + app/javascript/mastodon/locales/tr.json | 1 + app/javascript/mastodon/locales/uk.json | 1 + app/javascript/mastodon/locales/vi.json | 1 + app/javascript/mastodon/locales/zh-CN.json | 1 + app/javascript/mastodon/locales/zh-TW.json | 1 + config/locales/activerecord.fy.yml | 6 ++ config/locales/ar.yml | 14 ----- config/locales/be.yml | 14 ----- config/locales/bg.yml | 14 ----- config/locales/ca.yml | 14 ----- config/locales/cs.yml | 14 ----- config/locales/cy.yml | 14 ----- config/locales/da.yml | 48 +++++++++++---- config/locales/de.yml | 48 +++++++++++---- config/locales/devise.eo.yml | 2 + config/locales/doorkeeper.fy.yml | 1 + config/locales/el.yml | 14 ----- config/locales/en-GB.yml | 51 +++++++++++---- config/locales/es-AR.yml | 48 +++++++++++---- config/locales/es-MX.yml | 64 +++++++++++++------ config/locales/es.yml | 48 +++++++++++---- config/locales/et.yml | 14 ----- config/locales/eu.yml | 14 ----- config/locales/fi.yml | 48 +++++++++++---- config/locales/fo.yml | 14 ----- config/locales/fr-CA.yml | 14 ----- config/locales/fr.yml | 14 ----- config/locales/fy.yml | 63 +++++++++++++++---- config/locales/ga.yml | 14 ----- config/locales/gd.yml | 14 ----- config/locales/gl.yml | 48 +++++++++++---- config/locales/he.yml | 72 ++++++++++++++++++---- config/locales/hu.yml | 48 +++++++++++---- config/locales/ia.yml | 14 ----- config/locales/ie.yml | 14 ----- config/locales/io.yml | 14 ----- config/locales/is.yml | 18 ++---- config/locales/it.yml | 48 +++++++++++---- config/locales/ja.yml | 19 ++---- config/locales/ko.yml | 36 +++++++---- config/locales/lad.yml | 14 ----- config/locales/lv.yml | 14 ----- config/locales/ms.yml | 14 ----- config/locales/my.yml | 14 ----- config/locales/nl.yml | 52 +++++++++++----- config/locales/nn.yml | 16 +---- config/locales/no.yml | 14 ----- config/locales/pl.yml | 14 ----- config/locales/pt-BR.yml | 14 ----- config/locales/pt-PT.yml | 14 ----- config/locales/ru.yml | 14 ----- config/locales/simple_form.fy.yml | 3 + config/locales/simple_form.nl.yml | 2 +- config/locales/sl.yml | 14 ----- config/locales/sq.yml | 48 +++++++++++---- config/locales/sr-Latn.yml | 14 ----- config/locales/sr.yml | 14 ----- config/locales/sv.yml | 14 ----- config/locales/th.yml | 14 ----- config/locales/tr.yml | 48 +++++++++++---- config/locales/uk.yml | 14 ----- config/locales/vi.yml | 36 +++++++---- config/locales/zh-CN.yml | 36 +++++++---- config/locales/zh-HK.yml | 14 ----- config/locales/zh-TW.yml | 36 +++++++---- 90 files changed, 788 insertions(+), 761 deletions(-) diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index b79ac156e2..1b583b3204 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Resposta en privat", "notification.label.reply": "Resposta", "notification.mention": "Menció", + "notification.mentioned_you": "{name} us ha mencionat", "notification.moderation-warning.learn_more": "Per a saber-ne més", "notification.moderation_warning": "Heu rebut un avís de moderació", "notification.moderation_warning.action_delete_statuses": "S'han eliminat algunes de les vostres publicacions.", diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index 659f807d05..e225bb30ae 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Privat svar", "notification.label.reply": "Besvar", "notification.mention": "Omtale", + "notification.mentioned_you": "{name} nævnte dig", "notification.moderation-warning.learn_more": "Læs mere", "notification.moderation_warning": "Du er tildelt en moderationsadvarsel", "notification.moderation_warning.action_delete_statuses": "Nogle af dine indlæg er blevet fjernet.", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 0b541b2e48..3d8b57db4a 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -62,7 +62,7 @@ "account.requested_follow": "{name} möchte dir folgen", "account.share": "Profil von @{name} teilen", "account.show_reblogs": "Geteilte Beiträge von @{name} anzeigen", - "account.statuses_counter": "{count, plural, one {{counter} Beitrag} other {{counter} Beiträge}}", + "account.statuses_counter": "{count, plural, one {{counter} post} other {{counter} posts}}", "account.unblock": "Blockierung von @{name} aufheben", "account.unblock_domain": "Blockierung von {domain} aufheben", "account.unblock_short": "Blockierung aufheben", @@ -516,6 +516,7 @@ "notification.label.private_reply": "Private Antwort", "notification.label.reply": "Antwort", "notification.mention": "Erwähnung", + "notification.mentioned_you": "{name} erwähnte dich", "notification.moderation-warning.learn_more": "Mehr erfahren", "notification.moderation_warning": "Du wurdest von den Moderator*innen verwarnt", "notification.moderation_warning.action_delete_statuses": "Einige deiner Beiträge sind entfernt worden.", diff --git a/app/javascript/mastodon/locales/en-GB.json b/app/javascript/mastodon/locales/en-GB.json index b1d61ddd3d..da4c005203 100644 --- a/app/javascript/mastodon/locales/en-GB.json +++ b/app/javascript/mastodon/locales/en-GB.json @@ -852,6 +852,11 @@ "upload_error.poll": "File upload not allowed with polls.", "upload_form.audio_description": "Describe for people who are deaf or hard of hearing", "upload_form.description": "Describe for people who are blind or have low vision", + "upload_form.drag_and_drop.instructions": "To pick up a media attachment, press space or enter. While dragging, use the arrow keys to move the media attachment in any given direction. Press space or enter again to drop the media attachment in its new position, or press escape to cancel.", + "upload_form.drag_and_drop.on_drag_cancel": "Dragging was cancelled. Media attachment {item} was dropped.", + "upload_form.drag_and_drop.on_drag_end": "Media attachment {item} was dropped.", + "upload_form.drag_and_drop.on_drag_over": "Media attachment {item} was moved.", + "upload_form.drag_and_drop.on_drag_start": "Picked up media attachment {item}.", "upload_form.edit": "Edit", "upload_form.thumbnail": "Change thumbnail", "upload_form.video_description": "Describe for people who are deaf, hard of hearing, blind or have low vision", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index 35c2a5c744..5f6582fb68 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Privata respondo", "notification.label.reply": "Respondi", "notification.mention": "Mencii", + "notification.mentioned_you": "{name} menciis vin", "notification.moderation-warning.learn_more": "Lerni pli", "notification.moderation_warning": "Vi ricevis moderigan averton", "notification.moderation_warning.action_delete_statuses": "Kelkaj el viaj afiŝoj estis forigitaj.", diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index 609175d94f..7fec88a96e 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Respuesta privada", "notification.label.reply": "Respuesta", "notification.mention": "Mención", + "notification.mentioned_you": "{name} te mencionó", "notification.moderation-warning.learn_more": "Aprendé más", "notification.moderation_warning": "Recibiste una advertencia de moderación", "notification.moderation_warning.action_delete_statuses": "Se eliminaron algunos de tus mensajes.", diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json index 7c2e400338..ddfdf6960b 100644 --- a/app/javascript/mastodon/locales/es-MX.json +++ b/app/javascript/mastodon/locales/es-MX.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Respuesta privada", "notification.label.reply": "Respuesta", "notification.mention": "Mención", + "notification.mentioned_you": "{name} te ha mencionado", "notification.moderation-warning.learn_more": "Saber más", "notification.moderation_warning": "Has recibido una advertencia de moderación", "notification.moderation_warning.action_delete_statuses": "Se han eliminado algunas de tus publicaciones.", @@ -852,11 +853,11 @@ "upload_error.poll": "Subida de archivos no permitida con encuestas.", "upload_form.audio_description": "Describir para personas con problemas auditivos", "upload_form.description": "Describir para los usuarios con dificultad visual", - "upload_form.drag_and_drop.instructions": "Para recoger un archivo multimedia, pulsa la barra espaciadora o la tecla Enter. Mientras arrastras, utiliza las teclas de flecha para mover el archivo multimedia en cualquier dirección. Vuelve a pulsar la barra espaciadora o la tecla Enter para soltar el archivo multimedia en su nueva posición, o pulsa Escape para cancelar.", - "upload_form.drag_and_drop.on_drag_cancel": "Se canceló el arrastre. Se eliminó el archivo adjunto {item}.", - "upload_form.drag_and_drop.on_drag_end": "El archivo adjunto {item} ha sido eliminado.", - "upload_form.drag_and_drop.on_drag_over": "El archivo adjunto {item} se ha movido.", - "upload_form.drag_and_drop.on_drag_start": "Se ha recogido el archivo adjunto {item}.", + "upload_form.drag_and_drop.instructions": "Para recoger un archivo adjunto, pulsa la barra espaciadora o la tecla Intro. Mientras arrastras, usa las teclas de flecha para mover el archivo adjunto en cualquier dirección. Vuelve a pulsar la barra espaciadora o la tecla Intro para soltar el archivo adjunto en su nueva posición, o pulsa la tecla Escape para cancelar.", + "upload_form.drag_and_drop.on_drag_cancel": "Arrastre cancelado. El archivo adjunto {item} fue eliminado.", + "upload_form.drag_and_drop.on_drag_end": "El archivo adjunto {item} fue eliminado.", + "upload_form.drag_and_drop.on_drag_over": "El archivo adjunto {item} fue movido.", + "upload_form.drag_and_drop.on_drag_start": "Recogidos los archivos adjuntos {item}.", "upload_form.edit": "Editar", "upload_form.thumbnail": "Cambiar miniatura", "upload_form.video_description": "Describir para personas con problemas auditivos o visuales", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index b841489338..2aeb7d47ea 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Respuesta privada", "notification.label.reply": "Respuesta", "notification.mention": "Mención", + "notification.mentioned_you": "{name} te ha mencionado", "notification.moderation-warning.learn_more": "Saber más", "notification.moderation_warning": "Has recibido una advertencia de moderación", "notification.moderation_warning.action_delete_statuses": "Se han eliminado algunas de tus publicaciones.", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index 2e4cd661d5..ac7ab097fa 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Yksityinen vastaus", "notification.label.reply": "Vastaus", "notification.mention": "Maininta", + "notification.mentioned_you": "{name} mainitsi sinut", "notification.moderation-warning.learn_more": "Lue lisää", "notification.moderation_warning": "Olet saanut moderointivaroituksen", "notification.moderation_warning.action_delete_statuses": "Julkaisujasi on poistettu.", diff --git a/app/javascript/mastodon/locales/fo.json b/app/javascript/mastodon/locales/fo.json index c7e752d378..5ad8ba557b 100644 --- a/app/javascript/mastodon/locales/fo.json +++ b/app/javascript/mastodon/locales/fo.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Privat svar", "notification.label.reply": "Svara", "notification.mention": "Umrøð", + "notification.mentioned_you": "{name} nevndi teg", "notification.moderation-warning.learn_more": "Lær meira", "notification.moderation_warning": "Tú hevur móttikið eina umsjónarávaring", "notification.moderation_warning.action_delete_statuses": "Onkrir av tínum postum eru strikaðir.", diff --git a/app/javascript/mastodon/locales/fy.json b/app/javascript/mastodon/locales/fy.json index 1d71ef36c6..9fa2300fbc 100644 --- a/app/javascript/mastodon/locales/fy.json +++ b/app/javascript/mastodon/locales/fy.json @@ -85,6 +85,7 @@ "alert.rate_limited.title": "Dataferkear beheind", "alert.unexpected.message": "Der is in ûnferwachte flater bard.", "alert.unexpected.title": "Oepsy!", + "alt_text_badge.title": "Alternative tekst", "announcement.announcement": "Oankundiging", "attachments_list.unprocessed": "(net ferwurke)", "audio.hide": "Audio ferstopje", @@ -221,6 +222,8 @@ "domain_block_modal.they_cant_follow": "Net ien op dizze server kin jo folgje.", "domain_block_modal.they_wont_know": "Se krije net te witten dat se blokkearre wurde.", "domain_block_modal.title": "Domein blokkearje?", + "domain_block_modal.you_will_lose_num_followers": "Jo ferlieze {followersCount, plural, one {{followersCountDisplay} folger} other {{followersCountDisplay} folgers}} en {followingCount, plural, one {{followingCountDisplay} persoan dy’t jo folgje} other {{followingCountDisplay} persoanen dy’t jo folgje}}.", + "domain_block_modal.you_will_lose_relationships": "Jo ferlieze alle folgers en minsken dy’t jo folgje fan dizze server.", "domain_block_modal.you_wont_see_posts": "Jo sjogge gjin berjochten of meldingen mear fan brûkers op dizze server.", "domain_pill.activitypub_lets_connect": "It soarget derfoar dat jo net allinnich mar ferbine en kommunisearje kinne mei minsken op Mastodon, mar ek mei oare sosjale apps.", "domain_pill.activitypub_like_language": "ActivityPub is de taal dy’t Mastodon mei oare sosjale netwurken sprekt.", @@ -433,6 +436,8 @@ "lightbox.close": "Slute", "lightbox.next": "Folgjende", "lightbox.previous": "Foarige", + "lightbox.zoom_in": "Oarspronklike grutte toane", + "lightbox.zoom_out": "Passend toane", "limited_account_hint.action": "Profyl dochs besjen", "limited_account_hint.title": "Dit profyl is troch de behearders fan {domain} ferstoppe.", "link_preview.author": "Troch {name}", @@ -454,6 +459,7 @@ "lists.subheading": "Jo listen", "load_pending": "{count, plural, one {# nij item} other {# nije items}}", "loading_indicator.label": "Lade…", + "media_gallery.hide": "Ferstopje", "moved_to_account_banner.text": "Omdat jo nei {movedToAccount} ferhuze binne is jo account {disabledAccount} op dit stuit útskeakele.", "mute_modal.hide_from_notifications": "Meldingen ferstopje", "mute_modal.hide_options": "Opsjes ferstopje", @@ -510,6 +516,7 @@ "notification.label.private_reply": "Priveereaksje", "notification.label.reply": "Beäntwurdzje", "notification.mention": "Fermelding", + "notification.mentioned_you": "{name} hat dy fermeld", "notification.moderation-warning.learn_more": "Mear ynfo", "notification.moderation_warning": "Jo hawwe in moderaasje-warskôging ûntfongen", "notification.moderation_warning.action_delete_statuses": "Guon fan jo berjochten binne fuortsmiten.", @@ -774,6 +781,7 @@ "status.bookmark": "Blêdwizer tafoegje", "status.cancel_reblog_private": "Net langer booste", "status.cannot_reblog": "Dit berjocht kin net boost wurde", + "status.continued_thread": "Ferfolgje it petear", "status.copy": "Copy link to status", "status.delete": "Fuortsmite", "status.detailed_status": "Detaillearre petearoersjoch", @@ -782,6 +790,7 @@ "status.edit": "Bewurkje", "status.edited": "Lêst bywurke op {date}", "status.edited_x_times": "{count, plural, one {{count} kear} other {{count} kearen}} bewurke", + "status.embed": "Koade om op te nimmen", "status.favourite": "Favoryt", "status.favourites": "{count, plural, one {favoryt} other {favoriten}}", "status.filter": "Dit berjocht filterje", @@ -806,6 +815,7 @@ "status.reblogs.empty": "Net ien hat dit berjocht noch boost. Wannear’t ien dit docht, falt dat hjir te sjen.", "status.redraft": "Fuortsmite en opnij opstelle", "status.remove_bookmark": "Blêdwizer fuortsmite", + "status.replied_in_thread": "Antwurde yn petear", "status.replied_to": "Antwurde op {name}", "status.reply": "Beäntwurdzje", "status.replyAll": "Alle beäntwurdzje", @@ -843,6 +853,11 @@ "upload_error.poll": "It opladen fan bestannen is yn enkêten net tastien.", "upload_form.audio_description": "Describe for people with hearing loss", "upload_form.description": "Describe for the visually impaired", + "upload_form.drag_and_drop.instructions": "Druk op spaasje of Enter om in mediabylage op te pakken. Bruk de pylktoetsen om de bylage yn in bepaalde rjochting te ferpleatsen. Druk opnij op de spaasjebalke of Enter om de mediabylage op de nije posysje te pleatsen, of druk op Esc om te annulearjen.", + "upload_form.drag_and_drop.on_drag_cancel": "Slepen is annulearre. Mediabylage {item} is net ferpleatst.", + "upload_form.drag_and_drop.on_drag_end": "Mediabylage {item} is net ferpleatst.", + "upload_form.drag_and_drop.on_drag_over": "Mediabylage {item} is ferpleatst.", + "upload_form.drag_and_drop.on_drag_start": "Mediabylage {item} is oppakt.", "upload_form.edit": "Bewurkje", "upload_form.thumbnail": "Miniatuerôfbylding wizigje", "upload_form.video_description": "Describe for people with hearing loss or visual impairment", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index 2a31bfa463..27b4ad2460 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Resposta privada", "notification.label.reply": "Resposta", "notification.mention": "Mención", + "notification.mentioned_you": "{name} mencionoute", "notification.moderation-warning.learn_more": "Saber máis", "notification.moderation_warning": "Recibiches unha advertencia da moderación", "notification.moderation_warning.action_delete_statuses": "Algunha das túas publicacións foron eliminadas.", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index 16f558e543..d9b0382f4a 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -1,5 +1,5 @@ { - "about.blocks": "שרתים שנחסמו על ידי המנהלים", + "about.blocks": "שרתים מוגבלים", "about.contact": "יצירת קשר:", "about.disclaimer": "מסטודון היא תוכנת קוד פתוח חינמית וסימן מסחרי של Mastodon gGmbH.", "about.domain_blocks.no_reason_available": "הסיבה אינה זמינה", @@ -34,9 +34,9 @@ "account.follow_back": "לעקוב בחזרה", "account.followers": "עוקבים", "account.followers.empty": "אף אחד לא עוקב אחר המשתמש הזה עדיין.", - "account.followers_counter": "{count, plural,one {עוקב אחד} other {{count} עוקבים}}", + "account.followers_counter": "{count, plural,one {עוקב אחד} other {{counter} עוקבים}}", "account.following": "נעקבים", - "account.following_counter": "{count, plural,one {עוקב אחרי {count}}other {עוקב אחרי {count}}}", + "account.following_counter": "{count, plural,one {עוקב אחרי {count}}other {עוקב אחרי {counter}}}", "account.follows.empty": "משתמש זה עדיין לא עוקב אחרי אף אחד.", "account.go_to_profile": "מעבר לפרופיל", "account.hide_reblogs": "להסתיר הידהודים מאת @{name}", @@ -62,7 +62,7 @@ "account.requested_follow": "{name} ביקשו לעקוב אחריך", "account.share": "שתף את הפרופיל של @{name}", "account.show_reblogs": "הצג הדהודים מאת @{name}", - "account.statuses_counter": "{count, plural, one {הודעה אחת} two {הודעותיים} many {{count} הודעות} other {{count} הודעות}}", + "account.statuses_counter": "{count, plural, one {הודעה אחת} two {הודעותיים} many {{counter} הודעות} other {{counter} הודעות}}", "account.unblock": "להסיר חסימה ל- @{name}", "account.unblock_domain": "הסירי את החסימה של קהילת {domain}", "account.unblock_short": "הסר חסימה", @@ -349,9 +349,9 @@ "hashtag.column_settings.tag_mode.any": "לפחות אחד מאלה", "hashtag.column_settings.tag_mode.none": "אף אחד מאלה", "hashtag.column_settings.tag_toggle": "כלול תגיות נוספות בטור זה", - "hashtag.counter_by_accounts": "{count, plural,one{{count} משתתף.ת}other{{count} משתתפיםות}}", - "hashtag.counter_by_uses": "{count, plural, one {הודעה אחת} two {הודעותיים} many {{count} הודעות} other {{count} הודעות}}", - "hashtag.counter_by_uses_today": "{count, plural, one {הודעה אחת} two {הודעותיים} many {{count} הודעות} other {{count} הודעות}} היום", + "hashtag.counter_by_accounts": "{count, plural,one{{count} משתתף.ת}other{{counter} משתתפיםות}}", + "hashtag.counter_by_uses": "{count, plural, one {הודעה אחת} two {הודעותיים} many {{counter} הודעות} other {{counter} הודעות}}", + "hashtag.counter_by_uses_today": "{count, plural, one {הודעה אחת} two {הודעותיים} many {{counter} הודעות} other {{counter} הודעות}} היום", "hashtag.follow": "לעקוב אחרי תגית", "hashtag.unfollow": "להפסיק לעקוב אחרי תגית", "hashtags.and_other": "…{count, plural,other {ועוד #}}", @@ -442,7 +442,7 @@ "limited_account_hint.title": "פרופיל המשתמש הזה הוסתר על ידי המנחים של {domain}.", "link_preview.author": "מאת {name}", "link_preview.more_from_author": "עוד מאת {name}", - "link_preview.shares": "{count, plural, one {הודעה אחת} two {הודעותיים} many {{count} הודעות} other {{count} הודעות}}", + "link_preview.shares": "{count, plural, one {הודעה אחת} two {הודעותיים} many {{counter} הודעות} other {{counter} הודעות}}", "lists.account.add": "הוסף לרשימה", "lists.account.remove": "הסר מרשימה", "lists.delete": "מחיקת רשימה", @@ -516,6 +516,7 @@ "notification.label.private_reply": "תשובה בפרטי", "notification.label.reply": "תשובה", "notification.mention": "אזכור", + "notification.mentioned_you": "אוזכרת על ידי {name}", "notification.moderation-warning.learn_more": "למידע נוסף", "notification.moderation_warning": "קיבלת אזהרה מצוות ניהול התוכן", "notification.moderation_warning.action_delete_statuses": "חלק מהודעותיך הוסרו.", @@ -840,7 +841,7 @@ "time_remaining.minutes": "נותרו {number, plural, one {# דקה} other {# דקות}}", "time_remaining.moments": "רגעים נותרו", "time_remaining.seconds": "נותרו {number, plural, one {# שניה} other {# שניות}}", - "trends.counter_by_accounts": "{count, plural, one {אדם אחד} other {{count} א.נשים}} {days, plural, one {מאז אתמול} two {ביומיים האחרונים} other {במשך {days} הימים האחרונים}}", + "trends.counter_by_accounts": "{count, plural, one {אדם אחד} other {{counter} א.נשים}} {days, plural, one {מאז אתמול} two {ביומיים האחרונים} other {במשך {days} הימים האחרונים}}", "trends.trending_now": "נושאים חמים", "ui.beforeunload": "הטיוטא תאבד אם תעזבו את מסטודון.", "units.short.billion": "{count} מליארד", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index f9f403177c..0fee79f8b5 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Privát válasz", "notification.label.reply": "Válasz", "notification.mention": "Említés", + "notification.mentioned_you": "{name} megemlített", "notification.moderation-warning.learn_more": "További információ", "notification.moderation_warning": "Moderációs figyelmeztetést kaptál", "notification.moderation_warning.action_delete_statuses": "Néhány bejegyzésedet eltávolították.", diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json index c78c5d7842..bbd3a7a358 100644 --- a/app/javascript/mastodon/locales/is.json +++ b/app/javascript/mastodon/locales/is.json @@ -85,6 +85,7 @@ "alert.rate_limited.title": "Með takmörkum", "alert.unexpected.message": "Upp kom óvænt villa.", "alert.unexpected.title": "Úbbs!", + "alt_text_badge.title": "Hjálpartexti mynda", "announcement.announcement": "Auglýsing", "attachments_list.unprocessed": "(óunnið)", "audio.hide": "Fela hljóð", @@ -433,6 +434,8 @@ "lightbox.close": "Loka", "lightbox.next": "Næsta", "lightbox.previous": "Fyrra", + "lightbox.zoom_in": "Renna að raunstærð", + "lightbox.zoom_out": "Renna að svo passi", "limited_account_hint.action": "Birta notandasniðið samt", "limited_account_hint.title": "Þetta notandasnið hefur verið falið af umsjónarmönnum {domain}.", "link_preview.author": "Frá {name}", @@ -511,6 +514,7 @@ "notification.label.private_reply": "Einkasvar", "notification.label.reply": "Svara", "notification.mention": "Minnst á", + "notification.mentioned_you": "{name} minntist á þig", "notification.moderation-warning.learn_more": "Kanna nánar", "notification.moderation_warning": "Þú hefur fengið aðvörun frá umsjónarmanni", "notification.moderation_warning.action_delete_statuses": "Sumar færslurnar þínar hafa verið fjarlægðar.", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index ef709516c2..885be73c62 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Rispondi in privato", "notification.label.reply": "Rispondi", "notification.mention": "Menziona", + "notification.mentioned_you": "{name} ti ha menzionato", "notification.moderation-warning.learn_more": "Scopri di più", "notification.moderation_warning": "Hai ricevuto un avviso di moderazione", "notification.moderation_warning.action_delete_statuses": "Alcuni dei tuoi post sono stati rimossi.", @@ -852,6 +853,11 @@ "upload_error.poll": "Caricamento del file non consentito con i sondaggi.", "upload_form.audio_description": "Descrizione per persone con deficit uditivi", "upload_form.description": "Descrizione per ipovedenti", + "upload_form.drag_and_drop.instructions": "Per selezionare un allegato multimediale, premi Spazio o Invio. Mentre trascini, usa i tasti con le frecce per spostare l'allegato multimediale in una qualsiasi direzione. Premi di nuovo Spazio o Invio per rilasciare l'allegato multimediale nella sua nuova posizione, oppure premi Esc per annullare.", + "upload_form.drag_and_drop.on_drag_cancel": "Il trascinamento è stato annullato. L'allegato multimediale {item} è stato eliminato.", + "upload_form.drag_and_drop.on_drag_end": "L'allegato multimediale {item} è stato eliminato.", + "upload_form.drag_and_drop.on_drag_over": "L'allegato multimediale {item} è stato spostato.", + "upload_form.drag_and_drop.on_drag_start": "L'allegato multimediale {item} è stato ricevuto.", "upload_form.edit": "Modifica", "upload_form.thumbnail": "Cambia la miniatura", "upload_form.video_description": "Descrizione per persone con deficit uditivi o ipovedenti", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index 46444863ac..1810314c84 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -514,6 +514,7 @@ "notification.label.private_reply": "非公開の返信", "notification.label.reply": "返信", "notification.mention": "メンション", + "notification.mentioned_you": "{name} さんがあなたに返信しました", "notification.moderation-warning.learn_more": "さらに詳しく", "notification.moderation_warning": "管理者から警告が来ています", "notification.moderation_warning.action_delete_statuses": "あなたによるいくつかの投稿が削除されました。", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index e5e7dc2c17..edcbadd12d 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "개인 답글", "notification.label.reply": "답글", "notification.mention": "멘션", + "notification.mentioned_you": "{name} 님의 멘션", "notification.moderation-warning.learn_more": "더 알아보기", "notification.moderation_warning": "중재 경고를 받았습니다", "notification.moderation_warning.action_delete_statuses": "게시물 몇 개가 삭제되었습니다.", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index 71523b37d8..c0ca8f1766 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -516,10 +516,11 @@ "notification.label.private_reply": "Privéreactie", "notification.label.reply": "Reactie", "notification.mention": "Vermelding", + "notification.mentioned_you": "Je bent vermeld door {name}", "notification.moderation-warning.learn_more": "Meer informatie", "notification.moderation_warning": "Je hebt een moderatie-waarschuwing ontvangen", "notification.moderation_warning.action_delete_statuses": "Sommige van je berichten zijn verwijderd.", - "notification.moderation_warning.action_disable": "Je account is uitgeschakeld.", + "notification.moderation_warning.action_disable": "Jouw account is uitgeschakeld.", "notification.moderation_warning.action_mark_statuses_as_sensitive": "Sommige van je berichten zijn gemarkeerd als gevoelig.", "notification.moderation_warning.action_none": "Jouw account heeft een moderatie-waarschuwing ontvangen.", "notification.moderation_warning.action_sensitive": "Je berichten worden vanaf nu als gevoelig gemarkeerd.", @@ -531,11 +532,11 @@ "notification.reblog.name_and_others_with_link": "{name} en {count, plural, one {# ander persoon} other {# andere personen}} hebben jouw bericht geboost", "notification.relationships_severance_event": "Verloren verbindingen met {name}", "notification.relationships_severance_event.account_suspension": "Een beheerder van {from} heeft {target} geschorst, wat betekent dat je geen updates meer van hen kunt ontvangen of met hen kunt communiceren.", - "notification.relationships_severance_event.domain_block": "Een beheerder van {from} heeft {target} geblokkeerd, inclusief {followersCount} van jouw volgers en {followingCount, plural, one {# account} other {# accounts}} die jij volgt.", + "notification.relationships_severance_event.domain_block": "Een beheerder van {from} heeft {target} geblokkeerd, inclusief {followersCount} van jouw volgers en {followingCount, plural, one {# account} other {# accounts}} die je volgt.", "notification.relationships_severance_event.learn_more": "Meer informatie", - "notification.relationships_severance_event.user_domain_block": "Je hebt {target} geblokkeerd, waarmee je {followersCount} van je volgers en {followingCount, plural, one {# account} other {# accounts}} die jij volgt, bent verloren.", + "notification.relationships_severance_event.user_domain_block": "Je hebt {target} geblokkeerd, waarmee je {followersCount} van je volgers en {followingCount, plural, one {# account} other {# accounts}} die je volgt, bent verloren.", "notification.status": "{name} heeft zojuist een bericht geplaatst", - "notification.update": "{name} heeft een bericht bewerkt", + "notification.update": "{name} bewerkte een bericht", "notification_requests.accept": "Accepteren", "notification_requests.accept_multiple": "{count, plural, one {# verzoek accepteren…} other {# verzoeken accepteren…}}", "notification_requests.confirm_accept_multiple.button": "{count, plural, one {Verzoek accepteren} other {Verzoeken accepteren}}", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json index 69883a5495..58ed018ba0 100644 --- a/app/javascript/mastodon/locales/nn.json +++ b/app/javascript/mastodon/locales/nn.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Privat svar", "notification.label.reply": "Svar", "notification.mention": "Omtale", + "notification.mentioned_you": "{name} nemnde deg", "notification.moderation-warning.learn_more": "Lær meir", "notification.moderation_warning": "Du har mottatt ei moderasjonsåtvaring", "notification.moderation_warning.action_delete_statuses": "Nokre av innlegga dine har blitt fjerna.", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index 4dc74db8cb..c6555ebb76 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Odpowiedź prywatna", "notification.label.reply": "Odpowiedź", "notification.mention": "Wzmianka", + "notification.mentioned_you": "{name} wspomniał(a) o Tobie", "notification.moderation-warning.learn_more": "Dowiedz się więcej", "notification.moderation_warning": "Otrzymałeś/-łaś ostrzeżenie moderacyjne", "notification.moderation_warning.action_delete_statuses": "Niektóre twoje wpisy zostały usunięte.", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index ab5701cde0..b6d2fe112e 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Resposta privada", "notification.label.reply": "Resposta", "notification.mention": "Menção", + "notification.mentioned_you": "{name} te mencionou", "notification.moderation-warning.learn_more": "Aprender mais", "notification.moderation_warning": "Você recebeu um aviso de moderação", "notification.moderation_warning.action_delete_statuses": "Algumas das suas publicações foram removidas.", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index 15101be471..182f018873 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Përgjigje private", "notification.label.reply": "Përgjigje", "notification.mention": "Përmendje", + "notification.mentioned_you": "{name} ju ka përmendur", "notification.moderation-warning.learn_more": "Mësoni më tepër", "notification.moderation_warning": "Ju është dhënë një sinjalizim moderimi", "notification.moderation_warning.action_delete_statuses": "Disa nga postimet tuaja janë hequr.", diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json index b1e5a95edf..298852100c 100644 --- a/app/javascript/mastodon/locales/sv.json +++ b/app/javascript/mastodon/locales/sv.json @@ -506,6 +506,7 @@ "notification.label.private_reply": "Privata svar", "notification.label.reply": "Svar", "notification.mention": "Nämn", + "notification.mentioned_you": "{name} nämnde dig", "notification.moderation-warning.learn_more": "Läs mer", "notification.moderation_warning": "Du har fått en moderationsvarning", "notification.moderation_warning.action_delete_statuses": "Några av dina inlägg har tagits bort.", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index 160b6ec4e6..88c48bfb40 100644 --- a/app/javascript/mastodon/locales/th.json +++ b/app/javascript/mastodon/locales/th.json @@ -512,6 +512,7 @@ "notification.label.private_reply": "การตอบกลับแบบส่วนตัว", "notification.label.reply": "การตอบกลับ", "notification.mention": "การกล่าวถึง", + "notification.mentioned_you": "{name} ได้กล่าวถึงคุณ", "notification.moderation-warning.learn_more": "เรียนรู้เพิ่มเติม", "notification.moderation_warning": "คุณได้รับคำเตือนการกลั่นกรอง", "notification.moderation_warning.action_delete_statuses": "เอาโพสต์บางส่วนของคุณออกแล้ว", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 36c0b68f00..937b3e8e19 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Özel yanıt", "notification.label.reply": "Yanıt", "notification.mention": "Bahsetme", + "notification.mentioned_you": "{name} sizden söz etti", "notification.moderation-warning.learn_more": "Daha fazlası", "notification.moderation_warning": "Hesabınız bir denetim uyarısı aldı", "notification.moderation_warning.action_delete_statuses": "Bazı gönderileriniz kaldırıldı.", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index a48b071f54..5a9d388f0b 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Приватна відповідь", "notification.label.reply": "Відповідь", "notification.mention": "Згадка", + "notification.mentioned_you": "{name} згадує вас", "notification.moderation-warning.learn_more": "Докладніше", "notification.moderation_warning": "Ви отримали попередження модерації", "notification.moderation_warning.action_delete_statuses": "Деякі з ваших дописів було вилучено.", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index 770dcbaef5..cf33a15d32 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "Trả lời riêng", "notification.label.reply": "Trả lời", "notification.mention": "Lượt nhắc", + "notification.mentioned_you": "{name} nhắc đến bạn", "notification.moderation-warning.learn_more": "Tìm hiểu", "notification.moderation_warning": "Bạn vừa nhận một cảnh báo kiểm duyệt", "notification.moderation_warning.action_delete_statuses": "Một vài tút của bạn bị gỡ.", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index 0a4505d4ee..74702e5127 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "私人回复", "notification.label.reply": "回复", "notification.mention": "提及", + "notification.mentioned_you": "{name} 提到了你", "notification.moderation-warning.learn_more": "了解更多", "notification.moderation_warning": "你收到了一条管理警告", "notification.moderation_warning.action_delete_statuses": "你的一些嘟文已被移除。", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index 2047a69f44..e93f7d5180 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -516,6 +516,7 @@ "notification.label.private_reply": "私訊回嘟", "notification.label.reply": "回嘟", "notification.mention": "提及", + "notification.mentioned_you": "{name} 已提及您", "notification.moderation-warning.learn_more": "了解更多", "notification.moderation_warning": "您已收到管理員警告", "notification.moderation_warning.action_delete_statuses": "某些您的嘟文已被刪除。", diff --git a/config/locales/activerecord.fy.yml b/config/locales/activerecord.fy.yml index b571ab60dc..69139eba1d 100644 --- a/config/locales/activerecord.fy.yml +++ b/config/locales/activerecord.fy.yml @@ -15,6 +15,12 @@ fy: user/invite_request: text: Reden errors: + attributes: + domain: + invalid: is in ûnjildige domeinnamme + messages: + invalid_domain_on_line: "%{value} is in ûnjildige domeinnamme" + too_many_lines: giet oer de limyt fan %{limit} rigels models: account: attributes: diff --git a/config/locales/ar.yml b/config/locales/ar.yml index 829855776d..1a6f0da8c6 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -1394,20 +1394,6 @@ ar: merge_long: الإبقاء علي التسجيلات الحالية وإضافة الجديدة overwrite: إعادة الكتابة overwrite_long: استبدال التسجيلات الحالية بالجديدة - overwrite_preambles: - blocking_html: أنت على وشك استبدال قائمة الحظر بما يصل إلى %{total_items} من الحسابات من %{filename}. - bookmarks_html: أنت على وشك استبدال إشاراتك المرجعية بما يصل إلى %{total_items} من المشاركات من %{filename}. - domain_blocking_html: أنت على وشك إرشاداتك المرجعية بما يصل إلى %{total_items} من المشاركات من %{filename}. - following_html: أنت على وشك متابعة ما يصل إلى %{total_items} من الحسابات من %{filename} والتوقف عن متابعة أي شخص آخر. - lists_html: إنّك بصدد استبدال قوائمك بمحتوى مِلَفّ %{filename}. ما يُقارِب %{total_items} حسابًا سوف تُضاف إلى قوائم جديدة. - muting_html: أنت على وشك استبدال قائمة الحسابات الصامتة بما يصل إلى %{total_items} من الحسابات من %{filename}. - preambles: - blocking_html: أنت على وشك حظر ما يصل إلى %{total_items} من الحسابات من %{filename}. - bookmarks_html: أنت على وشك إضافة ما يصل إلى %{total_items} من المشاركات من %{filename} إلى إشاراتك المرجعية. - domain_blocking_html: أنت على وشك حظر ما يصل إلى %{total_items} من النطاقات من %{filename}. - following_html: أنت على وشك متابعة ما يصل إلى %{total_items} من الحسابات من %{filename}. - lists_html: أنت على وشك إضافة ما يصل إلى %{total_items} حسابات من %{filename} إلى قوائمك. سيتم إنشاء قوائم جديدة في حالة عدم وجود قائمة للإضافة إليها. - muting_html: أنت على وشك تجاهل ما يصل إلى %{total_items} من الحسابات من %{filename}. preface: بإمكانك استيراد بيانات قد قُمتَ بتصديرها مِن مثيل خادم آخَر، كقوائم المستخدِمين الذين كنتَ تتابِعهم أو قُمتَ بحظرهم. recent_imports: الاستيرادات الحديثة states: diff --git a/config/locales/be.yml b/config/locales/be.yml index d1d3e17679..b627672b2d 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -1391,20 +1391,6 @@ be: merge_long: Захаваць існуючыя запісы і дадаць новыя overwrite: Перазапісаць overwrite_long: Замяніць бягучыя запісы на новыя - overwrite_preambles: - blocking_html: Вы збіраецеся замяніць свой спіс блакіровак на %{total_items} уліковых запісаў з файла %{filename}. - bookmarks_html: Вы збіраецеся замяніць свае закладкі на %{total_items} допісаў з файла %{filename}. - domain_blocking_html: Вы збіраецеся замяніць свой спіс блакіроўкі даменаў на %{total_items} даменаў з файла %{filename}. - following_html: Вы збіраецеся падпісацца на %{total_items} уліковых запісаў з файла %{filename} і адпісацца ад усіх іншых карыстальнікаў. - lists_html: Вы збіраецеся замяніць свае спісы змесцівам з %{filename}. Да %{total_items} уліковых запісаў будуць дададзены ў новыя спісы. - muting_html: Вы збіраецеся замяніць свой спіс ігнараваных уліковых запісаў на %{total_items} уліковых запісаў з файла %{filename}. - preambles: - blocking_html: Вы збіраецеся заблакіраваць да %{total_items} уліковых запісаў з файла%{filename}. - bookmarks_html: Вы збіраецеся дадаць да %{total_items} паведамленняў з файла %{filename} у вашы закладкі. - domain_blocking_html: Вы збіраецеся заблакіраваць да %{total_items} даменаў з файла %{filename}. - following_html: Вы збіраецеся падпісацца на%{total_items} уліковых запісаў з файла %{filename}. - lists_html: Вы збіраецеся дадаць да %{total_items} уліковых запісаў з %{filename} у вашы спісы. Новыя спісы будуць створаны, калі іх няма. - muting_html: Вы збіраецеся ігнараваць да %{total_items} уліковых запісаў з файла %{filename}. preface: Вы можаце імпартаваць даныя, экспартаваныя вамі з іншага сервера, напрыклад, спіс людзей, на якіх вы падпісаны або якіх блакуеце. recent_imports: Нядаўнія імпарты states: diff --git a/config/locales/bg.yml b/config/locales/bg.yml index 00b3a41167..1fdd0e3533 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -1300,20 +1300,6 @@ bg: merge_long: Пази текущите записи и добавя нови overwrite: Презаписване overwrite_long: Заменя текущите записи с новите - overwrite_preambles: - blocking_html: На път сте да замените списъка си с блокирани с до %{total_items} акаунта от %{filename}. - bookmarks_html: На път сте да замените списъка си с отметки с до %{total_items} публикации от %{filename}. - domain_blocking_html: На път сте да замените списъка си с блокирани домейни с до %{total_items} домейна от %{filename}. - following_html: На път сте да последвате до %{total_items} акаунта от %{filename} и да спрете да следвате някой друг. - lists_html: На път сте да замените списъците си със съдържание от %{filename}. До %{total_items} акаунта ще се добавят към новите списъци. - muting_html: На път сте да замените списъка си със заглушени акаунти с до %{total_items} акаунта от %{filename}. - preambles: - blocking_html: На път сте да блокирате до %{total_items} акаунта от %{filename}. - bookmarks_html: На път сте да добавите до %{total_items} публикации от %{filename} в отметките си. - domain_blocking_html: На път сте да блокирате до %{total_items} домейна от %{filename}. - following_html: На път сте да последвате до %{total_items} акаунта от %{filename}. - lists_html: На път сте да добавите до %{total_items} акаунта от %{filename} към вашите списъци. Нови списъци ще се сътворят, ако няма списъци за добавяне. - muting_html: На път сте да заглушите до %{total_items} акаунта от %{filename}. preface: Можеш да импортираш някои данни, като например всички хора, които следваш или блокираш в акаунта си на тази инстанция, от файлове, създадени чрез експорт в друга инстанция. recent_imports: Скорошни внасяния states: diff --git a/config/locales/ca.yml b/config/locales/ca.yml index ced8de4ef2..bb81aaa59c 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -1365,20 +1365,6 @@ ca: merge_long: Mantenir els registres existents i afegir-ne de nous overwrite: Sobreescriu overwrite_long: Reemplaça els registres actuals amb els nous - overwrite_preambles: - blocking_html: Ets a punt per a reemplaçar la teva llista de bloquejos de fins a %{total_items} comptes des de %{filename}. - bookmarks_html: Ets a punt de reemplaçar els teus marcadors de fins a %{total_items} tuts des de %{filename}. - domain_blocking_html: Ets a punt de reemplaçar la teva llista de dominis bloquejats de fins a %{total_items} dominis des de %{filename}. - following_html: Ets a punt de seguir fins a %{total_items} comptes des de %{filename} i deixar de seguir a la resta. - lists_html: Estàs a punt de reemplaçar les teves llistes amb contactes de %{filename}. S'afegiran fins a %{total_items} comptes a les noves llistes. - muting_html: Ets a punt de reemplaçar la teva llista de comptes silenciats de fins a %{total_items} comptes des de %{filename}. - preambles: - blocking_html: Ets a punt de bloquejar fins a %{total_items} comptes des de %{filename}. - bookmarks_html: Ets a punt d'afegir fins a %{total_items} tuts des de %{filename} als teus marcadors. - domain_blocking_html: Ets a punt de bloquejar fins a %{total_items} dominis des de %{filename}. - following_html: Ets a punt de seguir fins a %{total_items} comptes des de %{filename}. - lists_html: Estàs a punt d'afegir %{total_items} comptes de %{filename} a les teves llistes. Es crearan noves llistes si no hi ha cap llista on afegir-los. - muting_html: Ets a punt de silenciar fins a %{total_items} comptes des de %{filename}. preface: Pots importar algunes les dades que has exportat des d'un altre servidor, com ara el llistat de les persones que estàs seguint o bloquejant. recent_imports: Importacions recents states: diff --git a/config/locales/cs.yml b/config/locales/cs.yml index 91fa517944..15211b928a 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -1348,20 +1348,6 @@ cs: merge_long: Ponechat existující záznamy a přidat nové overwrite: Přepsat overwrite_long: Nahradit aktuální záznamy novými - overwrite_preambles: - blocking_html: Chystáte se nahradit váš seznam bloků s %{total_items} účtami od %{filename}. - bookmarks_html: Chystáte se nahradit své záložky s %{total_items} příspěvků z %{filename}. - domain_blocking_html: Chystáte se nahradit seznam stránek s %{total_items} stránek z %{filename}. - following_html: Chystáte se sledovat%{total_items} účtů z %{filename} a přestanete sledovat všechny ostatní. - lists_html: Chystáte se nahradit své seznamy obsahem %{filename}. Až %{total_items} účtů budou přidány do nových seznamů. - muting_html: Chystáte se nahradit seznam skrytých účtů s %{total_items} účtami z %{filename}. - preambles: - blocking_html: Chystáte se blokovat%{total_items} účtů z %{filename}. - bookmarks_html: Chystáte se přidat až %{total_items} příspěvků z %{filename} do vašich záložek. - domain_blocking_html: Chystáte se blokovat%{total_items} stránek z %{filename}. - following_html: Chystáte se sledovat%{total_items} účtů z %{filename}. - lists_html: Chystáte se přidat %{total_items} účtů z %{filename} do vaších seznamů. Nové seznamy budou vytvořeny, pokud neexistuje žádný seznam, do kterého by bylo možné přidat. - muting_html: Chystáte se skrýt%{total_items} účtů z %{filename}. preface: Můžete importovat data, která jste exportovali z jiného serveru, jako například seznam lidí, které sledujete či blokujete. recent_imports: Nedávné importy states: diff --git a/config/locales/cy.yml b/config/locales/cy.yml index a70d08ed8e..d57ef38696 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -1465,20 +1465,6 @@ cy: merge_long: Cadw'r cofnodion presennol ac ychwanegu rhai newydd overwrite: Trosysgrifio overwrite_long: Amnewid y cofnodion cyfredol gyda'r rhai newydd - overwrite_preambles: - blocking_html: Rydych ar fin amnewid eich rhestr rhwystro gyda hyd at %{total_items} o gyfrifon o %{filename} . - bookmarks_html: Rydych ar fin amnewid eich nodau tudalen gyda hyd at %{total_items} o bostiadau gan %{filename} . - domain_blocking_html: Rydych ar fin amnewid eich rhestr rhwystro parth gyda hyd at %{total_items} parth o %{filename} . - following_html: Rydych ar fin dilyn hyd at %{total_items} o gyfrifon o %{filename} a pheidio a ddilyn unrhyw un arall . - lists_html: Rydych ar fin amnewid eich rhestrau gyda chynnwys %{filename} . Bydd hyd at %{total_items} o gyfrifon yn cael eu hychwanegu at restrau newydd. - muting_html: Rydych ar fin amnewid eich rhestr o gyfrifon tawel gyda hyd at %{total_items} o gyfrifon o %{filename} . - preambles: - blocking_html: Rydych ar fin rhwystro hyd at %{total_items} o gyfrifon o %{filename} . - bookmarks_html: Rydych ar fin ychwanegu hyd at %{total_items} o bostiadau o %{filename} at eich nodau tudalen . - domain_blocking_html: Rydych ar fin rhwystro hyd at %{total_items} parth o %{filename} . - following_html: Rydych ar fin dilyn hyd at %{total_items} cyfrif gan %{filename} . - lists_html: Rydych ar fin ychwanegu hyd at %{total_items} o gyfrifon o %{filename} at eich rhestrau . Bydd rhestrau newydd yn cael eu creu os nad oes rhestr i ychwanegu ati. - muting_html: Rydych ar fin anwybyddu hyd at %{total_items} cyfrif o %{filename}. preface: Gallwch fewnforio data rydych chi wedi'i allforio o weinydd arall, fel rhestr o'r bobl rydych chi'n eu dilyn neu'n eu blocio. recent_imports: Mewnforion diweddar states: diff --git a/config/locales/da.yml b/config/locales/da.yml index 0da901d4a8..1f80503e91 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -1366,19 +1366,43 @@ da: overwrite: Overskriv overwrite_long: Erstat aktuelle poster med de nye overwrite_preambles: - blocking_html: Du er ved at erstatte bloklisten med op til %{total_items} konti fra %{filename}. - bookmarks_html: Du er ved at erstatte bogmærkelisten med op til %{total_items} emner fra %{filename}. - domain_blocking_html: Du er ved at erstatte domæneblokeringslisten med op til %{total_items} domæner fra %{filename}. - following_html: Du er ved at følge op til %{total_items} konti fra %{filename} og stoppe med at følge alle andre. - lists_html: Du er ved at erstatte dine lister med indholdet af %{filename}. Op til %{total_items} konti tilføjes nye lister. - muting_html: Du er ved at erstatte listen over tavsgjorte konti med op til %{total_items} konti fra %{filename}. + blocking_html: + one: Man er ved at erstatte sin sortliste med %{count} konto fra %{filename}. + other: Man er ved at erstatte sin sortliste med optil %{count} konti fra %{filename}. + bookmarks_html: + one: Man er ved at erstatte sine bogmærker med %{count} post fra %{filename}. + other: Man er ved at erstatte sine bogmærker med op til %{count} poster fra %{filename}. + domain_blocking_html: + one: Man er ved at erstatte sin domænesortliste med %{count} domæne fra %{filename}. + other: Man er ved at erstatte sin domænesortliste med op til %{count} domæner fra %{filename}. + following_html: + one: Man er ved at følge %{count} konto fra %{filename} og stoppe med at følge andre. + other: Man er ved at følge %{count} konti fra %{filename} og stoppe med at følge andre. + lists_html: + one: Man er ved at erstatte sine lister med indhold fra %{filename}. %{count} konto føjes til nye lister. + other: Man er ved at erstatte sine lister med indhold fra %{filename}. Op til %{count} konti føjes til nye lister. + muting_html: + one: Man er ved at sin liste over en tavsgjort konto med %{count} konto fra %{filename}. + other: Man er ved at sin liste over tavsgjorte konti med op til %{count} konti fra %{filename}. preambles: - blocking_html: Du er ved at blokere op til %{total_items} konti fra %{filename}. - bookmarks_html: Du er ved at føje op til %{total_items} indlæg fra %{filename} til bogmærkelisten. - domain_blocking_html: Du er ved at blokere op til %{total_items} domæner fra %{filename}. - following_html: Du er ved at følge op til %{total_items} konti fra %{filename}. - lists_html: Du er ved at tilføje op til %{total_items} konti fra %{filename} til dine lister. Nye lister oprettes, hvis der ikke er nogen liste at føje konti til. - muting_html: Du er ved at tavsgøre op til %{total_items} konti fra %{filename}. + blocking_html: + one: Man er ved at blokere %{count} konto fra %{filename}. + other: Man er ved at blokere op til %{count} konti fra %{filename}. + bookmarks_html: + one: Man er ved at tilføje %{count} post fra %{filename} til sine bogmærker. + other: Man er ved at tilføje %{count} poster fra %{filename} til sine bogmærker. + domain_blocking_html: + one: Man er ved at blokere %{count} domæne fra %{filename}. + other: Man er ved at blokere op til %{count} domæner fra %{filename}. + following_html: + one: Man er ved at følge %{count} konto fra %{filename}. + other: Man er ved at følge op til%{count} konti fra %{filename}. + lists_html: + one: Man er ved at tilføje %{count} konto fra %{filename} til sine lister. Nye lister oprettes, hvis der ikke findes nogen liste at tilføje til. + other: Man er ved at tilføje %{count} konti fra %{filename} til sine lister. Nye lister oprettes, hvis der ikke findes nogen liste at tilføje til. + muting_html: + one: Man er ved at tavsgøre %{count} konto fra %{filename}. + other: Man er ved at tavsgøre op til %{count} konto fra %{filename}. preface: Du kan importere data, du har eksporteret fra en anden server, såsom en liste over folk du følger eller blokerer. recent_imports: Seneste importer states: diff --git a/config/locales/de.yml b/config/locales/de.yml index 7a8469df61..5f0b4ae353 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1366,19 +1366,43 @@ de: overwrite: Überschreiben overwrite_long: Bestehende Datensätze durch neue ersetzen overwrite_preambles: - blocking_html: Du bist dabei, deine Liste blockierter Konten durch bis zu %{total_items} Konten aus %{filename} zu ersetzen. - bookmarks_html: Du bist dabei, deine Lesezeichen durch bis zu %{total_items} Beiträge aus %{filename} zu ersetzen. - domain_blocking_html: Du bist dabei, deine Liste blockierter Domains durch bis zu %{total_items} Domains aus %{filename} zu ersetzen. - following_html: Du bist dabei, bis zu %{total_items} Konten aus %{filename} zu folgen und niemand anderes zu folgen. - lists_html: Du bist dabei, deine Listen durch den Inhalt aus %{filename} zu ersetzen. Es werden bis zu %{total_items} Konten zu neuen Listen hinzugefügt. - muting_html: Du bist dabei, deine Liste stummgeschalteter Konten durch bis zu %{total_items} Konten aus %{filename} zu ersetzen. + blocking_html: + one: Du bist dabei, deine Liste blockierter Konten aus %{filename} durch bis zu %{count} Konto zu ersetzen. + other: Du bist dabei, deine Liste blockierter Konten aus %{filename} durch bis zu %{count} Konten zu ersetzen. + bookmarks_html: + one: Du bist dabei, deine Lesezeichen aus %{filename} durch bis zu %{count} Beitrag zu ersetzen. + other: Du bist dabei, deine Lesezeichen aus %{filename} durch bis zu %{count} Beiträge zu ersetzen. + domain_blocking_html: + one: Du bist dabei, deine Liste blockierter Domains aus %{filename} durch bis zu %{count} Domain zu ersetzen. + other: Du bist dabei, deine Liste blockierter Domains aus %{filename} durch bis zu %{count} Domains zu ersetzen. + following_html: + one: Du bist dabei, bis zu %{count} Konto aus %{filename} zu folgen und allen anderen zu entfolgen. + other: Du bist dabei, bis zu %{count} Konten aus %{filename} zu folgen und allen anderen zu entfolgen. + lists_html: + one: Du bist dabei, deine Listen mit dem Inhalt aus %{filename} zu ersetzen. Bis zu %{count} Konto wird zu neuen Listen hinzugefügt. + other: Du bist dabei, deine Listen mit dem Inhalt aus %{filename} zu ersetzen. Bis zu %{count} Konten wird zu neuen Listen hinzugefügt. + muting_html: + one: Du bist dabei, deine Liste mit einem stummgeschalteten Konto aus %{filename} durch bis zu %{count} Konto zu ersetzen. + other: Du bist dabei, deine Liste stummgeschalteter Konten aus %{filename} durch bis zu %{count} Konten zu ersetzen. preambles: - blocking_html: Du bist dabei, bis zu %{total_items}%{total_items} Konten aus %{filename} zu blockieren. - bookmarks_html: Du bist dabei, bis zu %{total_items} Beiträge aus %{filename} zu deinen Lesezeichen hinzuzufügen. - domain_blocking_html: Du bist dabei, bis zu %{total_items} Domains aus %{filename} zu blockieren. - following_html: Du bist dabei, bis zu %{total_items} Konten aus %{filename} zu folgen. - lists_html: Du bist dabei, bis zu %{total_items} Konten aus %{filename} zu deinen Listen hinzuzufügen. Wenn es keine Liste gibt, zu der etwas hinzugefügt werden kann, dann werden neue Listen erstellt. - muting_html: Du bist dabei, bis zu %{total_items} Konten aus %{filename} stummzuschalten. + blocking_html: + one: Du bist dabei, bis zu %{count} Konto aus %{filename} zu blockieren. + other: Du bist dabei, bis zu %{count} Konten aus %{filename} zu blockieren. + bookmarks_html: + one: Du bist dabei, bis zu %{count} Beitrag aus %{filename} zu deinen Lesezeichen hinzuzufügen. + other: Du bist dabei, bis zu %{count} Beiträge aus %{filename} zu deinen Lesezeichen hinzuzufügen. + domain_blocking_html: + one: Du bist dabei, bis zu %{count} Domain aus %{filename} zu blockieren. + other: Du bist dabei, bis zu %{count} Domains aus %{filename} zu blockieren. + following_html: + one: Du bist dabei, bis zu %{count} Konto aus %{filename} zu folgen. + other: Du bist dabei, bis zu %{count} Konten aus %{filename} zu folgen. + lists_html: + one: Du bist dabei, bis zu %{count} Konto aus %{filename} zu deinen Listen hinzuzufügen. Wenn es keine Listen gibt, zu denen etwas hinzugefügt werden kann, dann werden neue Listen erstellt. + other: Du bist dabei, bis zu %{count} Konten aus %{filename} zu deinen Listen hinzuzufügen. Wenn es keine Listen gibt, zu denen etwas hinzugefügt werden kann, dann werden neue Listen erstellt. + muting_html: + one: Du bist dabei, bis zu %{count} Konto aus %{filename} stummzuschalten. + other: Du bist dabei, bis zu %{count} Konten aus %{filename} stummzuschalten. preface: Daten, die du von einem Mastodon-Server exportiert hast, kannst du hierher importieren. Das betrifft beispielsweise die Listen von Profilen, denen du folgst oder die du blockiert hast. recent_imports: Zuletzt importiert states: diff --git a/config/locales/devise.eo.yml b/config/locales/devise.eo.yml index 9d946967e9..43aef271f9 100644 --- a/config/locales/devise.eo.yml +++ b/config/locales/devise.eo.yml @@ -73,9 +73,11 @@ eo: title: Unu el viaj sekurecaj ŝlosiloj estis forigita webauthn_disabled: explanation: Aŭtentigo per sekurecaj ŝlosiloj estas malŝaltita por via konto. + extra: Ensaluto nun eblas uzante nur la ĵetonon generitan de la parigita tempbazita unufoja pasvorta aplikaĵo. subject: 'Mastodon: sekureca-ŝlosila aŭtentigo malebligita' title: Sekurecaj ŝlosiloj malaktivigitaj webauthn_enabled: + explanation: Sekurecŝlosila aŭtentigo estas ebligita por via konto. extra: Via sekureca ŝlosilo nun povas esti uzata por ensaluto. subject: 'Mastodon: sekureca-ŝlosila aŭtentigo ebligita' title: Sekurecaj ŝlosiloj aktivigitaj diff --git a/config/locales/doorkeeper.fy.yml b/config/locales/doorkeeper.fy.yml index 94e67d17a6..180c7e733f 100644 --- a/config/locales/doorkeeper.fy.yml +++ b/config/locales/doorkeeper.fy.yml @@ -60,6 +60,7 @@ fy: error: title: Der is in flater bard new: + prompt_html: "%{client_name} freget om tagong ta jo account. Keur dit fersyk allinnich goed as jo dizze boarne werkenne en fertrouwe." review_permissions: Tastimmingen beoardiele title: Autorisaasje fereaske show: diff --git a/config/locales/el.yml b/config/locales/el.yml index 4496ec51a6..0df31b246f 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -1322,20 +1322,6 @@ el: merge_long: Διατήρηση των εγγράφων που υπάρχουν και προσθήκη των νέων overwrite: Αντικατάσταση overwrite_long: Αντικατάσταση των υπαρχόντων εγγράφων με τις καινούργιες - overwrite_preambles: - blocking_html: Πρόκειται να αντικαταστήσεις τη λίστα αποκλεισμών με έως και %{total_items} λογαριασμούς από το %{filename}. - bookmarks_html: Πρόκειται να αντικαταστήσεις τους σελιδοδείκτες σου με έως και %{total_items} αναρτήσεις από το %{filename}. - domain_blocking_html: Πρόκειται να αντικαταστήσεις τη λίστα αποκλεισμών τομέων με έως και %{total_items} τομείς από το %{filename}. - following_html: Πρόκειται να ακολουθήσεις μέχρι %{total_items} λογαριασμούς από το %{filename} και να σταματήσεις να ακολουθείς οποιονδήποτε άλλο. - lists_html: Πρόκειται να αντικαταστήσεις τις λίστες σου με περιεχόμενο του %{filename}. Μέχρι %{total_items} λογαριασμοί θα προστεθούν σε νέες λίστες. - muting_html: Πρόκειται να αντικαταστήσεις τη λίστα λογαριασμών σε σίγαση με έως και %{total_items} λογαριασμούς από το %{filename}. - preambles: - blocking_html: Πρόκειται να αποκλείσεις έως και %{total_items} λογαριασμούς από το %{filename}. - bookmarks_html: Πρόκειται να προσθέσεις μέχρι και %{total_items} αναρτήσεις από το %{filename} στους σελιδοδείκτες σου. - domain_blocking_html: Πρόκειται να αποκλείσεις έως και %{total_items} τομείς από το %{filename}. - following_html: Πρόκειται να ακολουθήσεις έως και %{total_items} λογαριασμούς από το %{filename}. - lists_html: Πρόκειται να προσθέσεις μέχρι και %{total_items} λογαριασμούς από το %{filename} στις λίστες σου. Θα δημιουργηθούν νέες λίστες αν δεν υπάρχει λίστα για προσθήκη. - muting_html: Πρόκειται να κάνεις σίγαση σε έως και %{total_items} λογαριασμούς από το %{filename}. preface: Μπορείς να εισάγεις τα δεδομένα που έχεις εξάγει από άλλο διακομιστή, όπως τη λίστα των ατόμων που ακολουθείς ή έχεις αποκλείσει. recent_imports: Πρόσφατες Εισαγωγές states: diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index fbd48d1c31..65b2e6f71a 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -875,6 +875,9 @@ en-GB: message_html: You haven't defined any server rules. sidekiq_process_check: message_html: No Sidekiq process running for the %{value} queue(s). Please review your Sidekiq configuration + software_version_check: + action: See available updates + message_html: A Mastodon update is available. software_version_critical_check: action: See available updates message_html: A critical Mastodon update is available, please update as quickly as possible. @@ -1363,19 +1366,43 @@ en-GB: overwrite: Overwrite overwrite_long: Replace current records with the new ones overwrite_preambles: - blocking_html: You are about to replace your block list with up to %{total_items} accounts from %{filename}. - bookmarks_html: You are about to replace your bookmarks with up to %{total_items} posts from %{filename}. - domain_blocking_html: You are about to replace your domain block list with up to %{total_items} domains from %{filename}. - following_html: You are about to follow up to %{total_items} accounts from %{filename} and stop following anyone else. - lists_html: You are about to replace your lists with contents of %{filename}. Up to %{total_items} accounts will be added to new lists. - muting_html: You are about to replace your list of muted accounts with up to %{total_items} accounts from %{filename}. + blocking_html: + one: You are about to replace your block list with up to %{count} account from %{filename}. + other: You are about to replace your block list with up to %{count} accounts from %{filename}. + bookmarks_html: + one: You are about to replace your bookmarks with up to %{count} post from %{filename}. + other: You are about to replace your bookmarks with up to %{count} posts from %{filename}. + domain_blocking_html: + one: You are about to replace your domain block list with up to %{count} domain from %{filename}. + other: You are about to replace your domain block list with up to %{count} domains from %{filename}. + following_html: + one: You are about to follow up to %{count} account from %{filename} and stop following anyone else. + other: You are about to follow up to %{count} accounts from %{filename} and stop following anyone else. + lists_html: + one: You are about to replace your lists with contents of %{filename}. Up to %{count} account will be added to new lists. + other: You are about to replace your lists with contents of %{filename}. Up to %{count} accounts will be added to new lists. + muting_html: + one: You are about to replace your list of muted account with up to %{count} account from %{filename}. + other: You are about to replace your list of muted accounts with up to %{count} accounts from %{filename}. preambles: - blocking_html: You are about to block up to %{total_items} accounts from %{filename}. - bookmarks_html: You are about to add up to %{total_items} posts from %{filename} to your bookmarks. - domain_blocking_html: You are about to block up to %{total_items} domains from %{filename}. - following_html: You are about to follow up to %{total_items} accounts from %{filename}. - lists_html: You are about to add up to %{total_items} accounts from %{filename} to your lists. New lists will be created if there is no list to add to. - muting_html: You are about to mute up to %{total_items} accounts from %{filename}. + blocking_html: + one: You are about to block up to %{count} account from %{filename}. + other: You are about to block up to %{count} accounts from %{filename}. + bookmarks_html: + one: You are about to add up to %{count} post from %{filename} to your bookmarks. + other: You are about to add up to %{count} posts from %{filename} to your bookmarks. + domain_blocking_html: + one: You are about to block up to %{count} domain from %{filename}. + other: You are about to block up to %{count} domains from %{filename}. + following_html: + one: You are about to follow up to %{count} account from %{filename}. + other: You are about to follow up to %{count} accounts from %{filename}. + lists_html: + one: You are about to add up to %{count} account from %{filename} to your lists. New lists will be created if there is no list to add to. + other: You are about to add up to %{count} accounts from %{filename} to your lists. New lists will be created if there is no list to add to. + muting_html: + one: You are about to mute up to %{count} account from %{filename}. + other: You are about to mute up to %{count} accounts from %{filename}. preface: You can import data that you have exported from another server, such as a list of the people you are following or blocking. recent_imports: Recent imports states: diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index 49b8f288fa..cfc24ce270 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -1366,19 +1366,43 @@ es-AR: overwrite: Sobrescribir overwrite_long: Reemplazar registros actuales con los nuevos overwrite_preambles: - blocking_html: Estás a punto de reemplazar tu lista de bloqueos por hasta %{total_items} cuentas provenientes de %{filename}. - bookmarks_html: Estás a punto de reemplazar tus marcadores por hasta %{total_items} mensajes provenientes de %{filename}. - domain_blocking_html: Estás a punto de reemplazar tu lista de bloqueos de dominio por hasta %{total_items} dominios provenientes de %{filename}. - following_html: Estás a punto de seguir hasta %{total_items} cuentas provenientes de %{filename} y dejar de seguir a cualquier otra cuenta. - lists_html: Estás a punto de reemplazar tus listas con el contenido de %{filename}. Se agregarán hasta %{total_items} cuentas a listas nuevas. - muting_html: Estás a punto de reemplazar tu lista de cuentas silenciadas con hasta %{total_items} cuentas provenientes de %{filename}. + blocking_html: + one: Estás a punto de reemplazar tu lista de bloqueos por hasta %{count} cuenta provenientes de %{filename}. + other: Estás a punto de reemplazar tu lista de bloqueos por hasta %{count} cuentas provenientes de %{filename}. + bookmarks_html: + one: Estás a punto de reemplazar tus marcadores por hasta %{count} mensaje provenientes de %{filename}. + other: Estás a punto de reemplazar tus marcadores por hasta %{count} mensajes provenientes de %{filename}. + domain_blocking_html: + one: Estás a punto de reemplazar tu lista de bloqueos de dominio por hasta %{count} dominio provenientes de %{filename}. + other: Estás a punto de reemplazar tu lista de bloqueos de dominio por hasta %{count} dominios provenientes de %{filename}. + following_html: + one: Estás a punto de seguir hasta %{count} cuenta provenientes de %{filename} y dejar de seguir a cualquier otra cuenta. + other: Estás a punto de seguir hasta %{count} cuentas provenientes de %{filename} y dejar de seguir a cualquier otra cuenta. + lists_html: + one: Estás a punto de reemplazar tus listas con el contenido de %{filename}. Se agregarán hasta %{count} cuenta a listas nuevas. + other: Estás a punto de reemplazar tus listas con el contenido de %{filename}. Se agregarán hasta %{count} cuentas a listas nuevas. + muting_html: + one: Estás a punto de reemplazar tu lista de cuentas silenciadas con hasta %{count} cuenta provenientes de %{filename}. + other: Estás a punto de reemplazar tu lista de cuentas silenciadas con hasta %{count} cuentas provenientes de %{filename}. preambles: - blocking_html: Estás a punto de bloquear hasta %{total_items} cuentas provenientes de %{filename}. - bookmarks_html: Está a punto de agregar hasta %{total_items} mensajes provenientes de %{filename} a tus marcadores. - domain_blocking_html: Estás a punto de bloquear hasta %{total_items} dominios provenientes de %{filename}. - following_html: Estás a punto de seguir hasta cuentas%{total_items} provenientes de %{filename}. - lists_html: Estás a punto de agregar hasta %{total_items} cuentas desde %{filename} a tus listas. Se crearán nuevas listas si no hay lista a cual agregar. - muting_html: Estás a punto de silenciar hasta %{total_items} cuentas provenientes de %{filename}. + blocking_html: + one: Estás a punto de bloquear hasta %{count} cuenta provenientes de %{filename}. + other: Estás a punto de bloquear hasta %{count} cuentas provenientes de %{filename}. + bookmarks_html: + one: Está a punto de agregar hasta %{count} mensaje provenientes de %{filename} a tus marcadores. + other: Está a punto de agregar hasta %{count} mensajes provenientes de %{filename} a tus marcadores. + domain_blocking_html: + one: Estás a punto de bloquear hasta %{count} dominio provenientes de %{filename}. + other: Estás a punto de bloquear hasta %{count} dominios provenientes de %{filename}. + following_html: + one: Estás a punto de seguir hasta %{count} cuenta provenientes de %{filename}. + other: Estás a punto de seguir hasta %{count} cuentas provenientes de %{filename}. + lists_html: + one: Estás a punto de agregar hasta %{count} cuenta desde %{filename} a tus listas. Se crearán nuevas listas si no hay lista a cuál agregar. + other: Estás a punto de agregar hasta %{count} cuentas desde %{filename} a tus listas. Se crearán nuevas listas si no hay lista a cuál agregar. + muting_html: + one: Estás a punto de silenciar hasta %{count} cuenta provenientes de %{filename}. + other: Estás a punto de silenciar hasta %{count} cuentas provenientes de %{filename}. preface: Podés importar ciertos datos que exportaste desde otro servidor, como una lista de las cuentas que estás siguiendo o bloqueando. recent_imports: Importaciones recientes states: diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index 0f4c8452c0..4e7ee657e6 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -180,21 +180,21 @@ es-MX: confirm_user: Confirmar Usuario create_account_warning: Crear Advertencia create_announcement: Crear Anuncio - create_canonical_email_block: Crear Bloqueo de Correo Electrónico + create_canonical_email_block: Crear bloqueo de correo electrónico create_custom_emoji: Crear Emoji Personalizado create_domain_allow: Crear Permiso de Dominio create_domain_block: Crear Bloqueo de Dominio - create_email_domain_block: Crear Bloqueo de Dominio de Correo Electrónico + create_email_domain_block: Crear bloqueo de dominio de correo electrónico create_ip_block: Crear regla IP create_unavailable_domain: Crear Dominio No Disponible create_user_role: Crear rol demote_user: Degradar Usuario destroy_announcement: Eliminar Anuncio - destroy_canonical_email_block: Eliminar Bloqueo de Correo Electrónico + destroy_canonical_email_block: Eliminar bloqueo de correo electrónico destroy_custom_emoji: Eliminar Emoji Personalizado destroy_domain_allow: Eliminar Permiso de Dominio destroy_domain_block: Eliminar Bloqueo de Dominio - destroy_email_domain_block: Eliminar Bloqueo de Dominio de Correo Electrónico + destroy_email_domain_block: Eliminar bloqueo de dominio de correo electrónico destroy_instance: Purgar dominio destroy_ip_block: Eliminar regla IP destroy_status: Eliminar Estado @@ -876,8 +876,8 @@ es-MX: sidekiq_process_check: message_html: No hay ningún proceso Sidekiq en ejecución para la(s) cola(s) %{value}. Por favor, revise su configuración de Sidekiq software_version_check: - action: Ver actualizaciones disponibles - message_html: Hay disponible una actualización de Mastodon. + action: Ver las actualizaciones disponibles + message_html: Ya está disponible una actualización de Mastodon. software_version_critical_check: action: Ver actualizaciones disponibles message_html: Una actualización crítica de Mastodon está disponible, por favor actualice lo antes posible. @@ -1366,19 +1366,43 @@ es-MX: overwrite: Sobrescribir overwrite_long: Reemplazar registros actuales con los nuevos overwrite_preambles: - blocking_html: Estás a punto de reemplazar tu lista de bloqueos por hasta %{total_items} cuentas provenientes de %{filename}. - bookmarks_html: Estás a punto de reemplazar tus marcadores por hasta %{total_items} publicaciones provenientes de %{filename}. - domain_blocking_html: Estás a punto de reemplazar tu lista de bloqueos de dominio por hasta %{total_items} dominios provenientes de %{filename}. - following_html: Estás a punto de seguir hasta %{total_items} cuentas provenientes de %{filename} y dejar de seguir a cualquier otra cuenta. - lists_html: Estás a punto de reemplazar tus listas con contenidos de %{filename}. %{total_items} cuentas se añadirán a listas nuevas. - muting_html: Estás a punto de reemplazar tu lista de cuentas silenciadas con hasta %{total_items} cuentas proveninetes de %{filename}. + blocking_html: + one: Estás a punto de reemplazar tu lista de bloqueos por %{count} cuenta proveniente de %{filename}. + other: Estás a punto de reemplazar tu lista de bloqueos por hasta %{count} cuentas provenientes de %{filename}. + bookmarks_html: + one: Estás a punto de reemplazar tus marcadores por %{count} publicación proveniente de %{filename}. + other: Estás a punto de reemplazar tus marcadores por hasta %{count} publicaciones provenientes de %{filename}. + domain_blocking_html: + one: Estás a punto de reemplazar tu lista de bloqueos de dominio por %{count} dominio proveniente de %{filename}. + other: Estás a punto de reemplazar tu lista de bloqueos de dominio por hasta %{count} dominios provenientes de %{filename}. + following_html: + one: Estás a punto de seguir a %{count} cuenta proveniente de %{filename} y dejar de seguir a cualquier otra cuenta. + other: Estás a punto de seguir hasta %{count} cuentas provenientes de %{filename} y dejar de seguir a cualquier otra cuenta. + lists_html: + one: Estás a punto de reemplazar tus listas con el contenido de %{filename}. Se añadirá %{count} cuenta a una nueva lista. + other: Estás a punto de reemplazar tus listas con el contenido de %{filename}. Se añadirán %{count} cuentas a nuevas listas. + muting_html: + one: Estás a punto de reemplazar tu lista de cuentas silenciadas con %{count} cuenta proveninete de %{filename}. + other: Estás a punto de reemplazar tu lista de cuentas silenciadas con hasta %{count} cuentas provenientes de %{filename}. preambles: - blocking_html: Estás a punto de bloquear hasta %{total_items} cuentas proveninetes de %{filename}. - bookmarks_html: Estás a punto de añadir hasta %{total_items} publicaciones proveninetes de %{filename} a tus marcadores. - domain_blocking_html: Estás a punto de bloquear hasta %{total_items} dominios provenientes de %{filename}. - following_html: Estás a punto de seguir hasta cuentas%{total_items} provenientes de %{filename}. - lists_html: Estás a punto de añadir %{total_items} cuentas desde %{filename} a tus listas. Se crearán nuevas listas si no hay listas para añadirlas. - muting_html: Estás a punto de silenciar hasta %{total_items} cuentas provenientes de %{filename}. + blocking_html: + one: Estás a punto de bloquear a %{count} cuenta proveninete de %{filename}. + other: Estás a punto de bloquear hasta %{count} cuentas provenientes de %{filename}. + bookmarks_html: + one: Está a punto de añadir %{count} publicación proveniente de %{filename} a tus marcadores. + other: Está a punto de añadir hasta %{count} publicaciones provenientes de %{filename} a tus marcadores. + domain_blocking_html: + one: Estás a punto de bloquear %{count} dominio proveniente de %{filename}. + other: Estás a punto de bloquear hasta %{count} dominios provenientes de %{filename}. + following_html: + one: Estás a punto de seguir a %{count} cuenta proveniente de %{filename}. + other: Estás a punto de seguir hasta %{count} cuentas provenientes de %{filename}. + lists_html: + one: Estás a punto de añadir %{count} cuenta desde %{filename} a tus listas. Se creará una nueva listas si no hay listas donde añadirla. + other: Estás a punto de añadir %{count} cuentas desde %{filename} a tus listas. Se crearán nuevas listas si no hay listas donde añadirlas. + muting_html: + one: Estás a punto de silenciar a %{count} cuenta proveniente de %{filename}. + other: Estás a punto de silenciar hasta %{count} cuentas provenientes de %{filename}. preface: Puedes importar ciertos datos, como todas las personas que estás siguiendo o bloqueando en tu cuenta en esta instancia, desde archivos exportados de otra instancia. recent_imports: Importaciones recientes states: @@ -1453,8 +1477,8 @@ es-MX: emails: notification_emails: favourite: correos de notificación de favoritos - follow: correos de notificación de nuevos seguidores - follow_request: correos de notificación de solicitud de seguidor + follow: correos electrónicos de notificación de seguimiento + follow_request: correos electrónicos de solicitud de seguimiento mention: correos de notificación de menciones reblog: correos de notificación de impulsos resubscribe_html: Si te has dado de baja por error, puedes volver a darte de alta desde tus ajustes de notificaciones por correo. diff --git a/config/locales/es.yml b/config/locales/es.yml index aa18e7b52e..bb9e5daff5 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1366,19 +1366,43 @@ es: overwrite: Sobrescribir overwrite_long: Reemplazar registros actuales con los nuevos overwrite_preambles: - blocking_html: Estás a punto de reemplazar tu lista de bloqueos por hasta %{total_items} cuentas provenientes de %{filename}. - bookmarks_html: Estás a punto de reemplazar tus marcadores por hasta %{total_items} publicaciones provenientes de %{filename}. - domain_blocking_html: Estás a punto de reemplazar tu lista de bloqueos de dominio por hasta %{total_items} dominios provenientes de %{filename}. - following_html: Estás a punto de seguir hasta %{total_items} cuentas provenientes de %{filename} y dejar de seguir a cualquier otra cuenta. - lists_html: Estás a punto de reemplazar tus listas con contenidos de %{filename}. Se añadirán %{total_items} cuentas a nuevas listas. - muting_html: Estás a punto de reemplazar tu lista de cuentas silenciadas con hasta %{total_items} cuentas proveninetes de %{filename}. + blocking_html: + one: Estás a punto de reemplazar tu lista de bloqueos por %{count} cuenta proveniente de %{filename}. + other: Estás a punto de reemplazar tu lista de bloqueos por hasta %{count} cuentas provenientes de %{filename}. + bookmarks_html: + one: Estás a punto de reemplazar tus marcadores por %{count} publicación proveniente de %{filename}. + other: Estás a punto de reemplazar tus marcadores por hasta %{count} publicaciones provenientes de %{filename}. + domain_blocking_html: + one: Estás a punto de reemplazar tu lista de bloqueos de dominio por %{count} dominio proveniente de %{filename}. + other: Estás a punto de reemplazar tu lista de bloqueos de dominio por hasta %{count} dominios provenientes de %{filename}. + following_html: + one: Estás a punto de seguir a %{count} cuenta proveniente de %{filename} y dejar de seguir a cualquier otra cuenta. + other: Estás a punto de seguir hasta %{count} cuentas provenientes de %{filename} y dejar de seguir a cualquier otra cuenta. + lists_html: + one: Estás a punto de reemplazar tus listas con el contenido de %{filename}. Se añadirá %{count} cuenta a una nueva lista. + other: Estás a punto de reemplazar tus listas con el contenido de %{filename}. Se añadirán %{count} cuentas a nuevas listas. + muting_html: + one: Estás a punto de reemplazar tu lista de cuentas silenciadas con %{count} cuenta proveninete de %{filename}. + other: Estás a punto de reemplazar tu lista de cuentas silenciadas con hasta %{count} cuentas provenientes de %{filename}. preambles: - blocking_html: Estás a punto de bloquear hasta %{total_items} cuentas proveninetes de %{filename}. - bookmarks_html: Está a punto de añadir hasta %{total_items} publicaciones proveninetes de %{filename} a tus marcadores. - domain_blocking_html: Estás a punto de bloquear hasta %{total_items} dominios provenientes de %{filename}. - following_html: Estás a punto de seguir hasta cuentas%{total_items} provenientes de %{filename}. - lists_html: Estás a punto de añadir %{total_items} cuentas desde %{filename} a tus listas. Se crearán nuevas listas si no hay listas para añadirlas. - muting_html: Estás a punto de silenciar hasta %{total_items} cuentas provenientes de %{filename}. + blocking_html: + one: Estás a punto de bloquear a %{count} cuenta proveninete de %{filename}. + other: Estás a punto de bloquear hasta %{count} cuentas provenientes de %{filename}. + bookmarks_html: + one: Está a punto de añadir %{count} publicación proveniente de %{filename} a tus marcadores. + other: Está a punto de añadir hasta %{count} publicaciones provenientes de %{filename} a tus marcadores. + domain_blocking_html: + one: Estás a punto de bloquear %{count} dominio proveniente de %{filename}. + other: Estás a punto de bloquear hasta %{count} dominios provenientes de %{filename}. + following_html: + one: Estás a punto de seguir a %{count} cuenta proveniente de %{filename}. + other: Estás a punto de seguir hasta %{count} cuentas provenientes de %{filename}. + lists_html: + one: Estás a punto de añadir %{count} cuenta desde %{filename} a tus listas. Se creará una nueva listas si no hay listas donde añadirla. + other: Estás a punto de añadir %{count} cuentas desde %{filename} a tus listas. Se crearán nuevas listas si no hay listas donde añadirlas. + muting_html: + one: Estás a punto de silenciar a %{count} cuenta proveniente de %{filename}. + other: Estás a punto de silenciar hasta %{count} cuentas provenientes de %{filename}. preface: Puedes importar ciertos datos, como todas las personas que estás siguiendo o bloqueando en tu cuenta en esta instancia, desde archivos exportados de otra instancia. recent_imports: Importaciones recientes states: diff --git a/config/locales/et.yml b/config/locales/et.yml index b71e3ccb68..4372a92843 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -1362,20 +1362,6 @@ et: merge_long: Hoia olemasolevad andmed ja lisa uusi overwrite: Kirjuta üle overwrite_long: Vaheta praegused andmed uute vastu - overwrite_preambles: - blocking_html: Oled asendamas oma blokeeringute loetelu kuni %{total_items} kontoga kohast %{filename}. - bookmarks_html: Oled asendamas oma järjehoidjaid kuni %{total_items} postitusega kohast %{filename}. - domain_blocking_html: Oled asendamas oma domeenide blokeeringute loetelu kuni %{total_items} domeeniga kohast %{filename}. - following_html: Oled jälgima hakkamas kuni %{total_items} kontot kohast %{filename} ja lõpetad kõigi teiste jälgimise. - lists_html: Oled asendamas oma loetelusid faili %{filename} sisuga. Uutesse loeteludesse lisatakse kuni %{total_items} kontot. - muting_html: Oled asendamas oma vaigistatud kontode loetelu kuni %{total_items} kontoga kohast %{filename}. - preambles: - blocking_html: Oled blokeerimas kuni %{total_items} kontoga kohast %{filename}. - bookmarks_html: Oled lisamas kuni %{total_items} postitust kohast %{filename} to your bookmarks. - domain_blocking_html: Oled blokeerimas kuni %{total_items} domeeni kohast %{filename}. - following_html: Oled jälgima hakkamas kuni %{total_items} kontot kohast %{filename}. - lists_html: Oled lisamas oma loeteludesse failist %{filename} kuni %{total_items} kontot. Kui pole loetelusi, kuhu lisada, luuakse uued loetelud. - muting_html: Oled vaigistamas kuni %{total_items} kontot kohast %{filename}. preface: Saad importida mistahes andmeid, mis on eksporditud teisest serverist. Näiteks nimekirja inimestest, keda jälgid ja keda blokeerid. recent_imports: Viimati imporditud states: diff --git a/config/locales/eu.yml b/config/locales/eu.yml index e80207d46f..e9c3be2d24 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -1276,20 +1276,6 @@ eu: merge_long: Mantendu dauden erregistroak eta gehitu berriak overwrite: Gainidatzi overwrite_long: Ordeztu oraingo erregistroak berriekin - overwrite_preambles: - blocking_html: "Blokeatutakoen zerrenda %{filename} fitxategiak dituen %{total_items} kontuekin ordeztear zaude." - bookmarks_html: "Laster-markak %{filename} fitxategiak dituen %{total_items} argitalpenekin ordeztear zaude." - domain_blocking_html: "Blokeatutako domeinuen zerrenda %{filename} fitxategiak dituen %{total_items} domeinuekin ordeztear zaude." - following_html: "%{filename} fitxategiak dituen %{total_items} kontuei jarraitzear zaude; gainontzekoak jarraitzeari utziko diozu." - lists_html: "Zerrendak %{filename} fitxategiak duen edukiarekin ordeztear zaude. %{total_items} kontu gehituko dira zerrenda berrietara." - muting_html: "Mutututako kontuen zerrenda %{filename} fitxategiak dituen %{total_items} kontuekin ordeztear zaude." - preambles: - blocking_html: "%{filename} fitxategiak dituen %{total_items} kontuak blokeatzear zaude." - bookmarks_html: "%{filename} fitxategiak dituen %{total_items} argitalpenei laster-marka jartzear zaude." - domain_blocking_html: "%{filename} fitxategiak dituen %{total_items} domeinuak blokeatzear zaude." - following_html: "%{filename} fitxategiak dituen %{total_items} konturi jarraitzear zaude." - lists_html: "%{filename} fitxategiak dituen %{total_items} kontu zerrendetan gehitzear zaude. Zerrenda berriak sortuko dira zerrendarik ez badago." - muting_html: "%{filename} fitxategiak dituen %{total_items} kontuak mututzear zaude." preface: Beste zerbitzari bateko datuak inportatu ditzakezu, esaterako jarraitzen duzun edo blokeatu duzun jendearen zerrenda. recent_imports: Azken inportazioak states: diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 22ccc71161..1767f9e63e 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -1366,19 +1366,43 @@ fi: overwrite: Korvaa overwrite_long: Korvaa nykyiset tietueet uusilla overwrite_preambles: - blocking_html: Olet aikeissa korvata estoluettelosi kaikkiaan %{total_items} tilillä tiedostosta %{filename}. - bookmarks_html: Olet aikeissa korvata kirjanmerkkisi kaikkiaan %{total_items} julkaisulla tiedostosta %{filename}. - domain_blocking_html: Olet aikeissa korvata verkkotunnusten estoluettelosi kaikkiaan %{total_items} verkkotunnuksella tiedostosta %{filename}. - following_html: Olet aikeissa seurata kaikkiaan %{total_items} tiliä tiedostosta %{filename} ja lopettaa kaikkien muiden seuraamisen. - lists_html: Olet aikeissa korvata listojasi tiedoston %{filename} sisällöllä. Uusiin listoihin lisätään kaikkiaan %{total_items} tiliä. - muting_html: Olet aikeissa korvata mykistettyjen tilien luettelosi kaikkiaan %{total_items} tilillä tiedostosta %{filename}. + blocking_html: + one: Olet aikeissa korvata estoluettelosi kaikkiaan %{count} tilillä tiedostosta %{filename}. + other: Olet aikeissa korvata estoluettelosi kaikkiaan %{count} tilillä tiedostosta %{filename}. + bookmarks_html: + one: Olet aikeissa korvata kirjanmerkkisi kaikkiaan %{count} julkaisulla tiedostosta %{filename}. + other: Olet aikeissa korvata kirjanmerkkisi kaikkiaan %{count} julkaisulla tiedostosta %{filename}. + domain_blocking_html: + one: Olet aikeissa korvata verkkotunnusten estoluettelosi kaikkiaan %{count} verkkotunnuksella tiedostosta %{filename}. + other: Olet aikeissa korvata verkkotunnusten estoluettelosi kaikkiaan %{count} verkkotunnuksella tiedostosta %{filename}. + following_html: + one: Olet aikeissa seurata kaikkiaan %{count} tiliä tiedostosta %{filename} ja lopettaa kaikkien muiden seuraamisen. + other: Olet aikeissa seurata kaikkiaan %{count} tiliä tiedostosta %{filename} ja lopettaa kaikkien muiden seuraamisen. + lists_html: + one: Olet aikeissa korvata listojasi tiedoston %{filename} sisällöllä. Uusiin listoihin lisätään kaikkiaan %{count} tili. + other: Olet aikeissa korvata listojasi tiedoston %{filename} sisällöllä. Uusiin listoihin lisätään kaikkiaan %{count} tiliä. + muting_html: + one: Olet aikeissa korvata mykistettyjen tilien luettelosi kaikkiaan %{count} tilillä tiedostosta %{filename}. + other: Olet aikeissa korvata mykistettyjen tilien luettelosi kaikkiaan %{count} tilillä tiedostosta %{filename}. preambles: - blocking_html: Olet aikeissa estää kaikkiaan %{total_items} tiliä tiedostosta %{filename}. - bookmarks_html: Olet aikeissa lisätä kaikkiaan %{total_items} julkaisua tiedostosta %{filename}kirjanmerkkeihisi. - domain_blocking_html: Olet aikeissa estää kaikkiaan %{total_items} verkkotunnusta tiedostosta %{filename}. - following_html: Olet aikeissa seurata kaikkiaan %{total_items} tiliä tiedostosta %{filename}. - lists_html: Olet aikeissa lisätä listoihisi kaikkiaan %{total_items} tiliä tiedostosta %{filename}. Uusia listoja luodaan, jos sopivaa kohdelistaa ei ole olemassa. - muting_html: Olet aikeissa mykistää kaikkiaan %{total_items} tiliä tiedostosta %{filename}. + blocking_html: + one: Olet aikeissa estää kaikkiaan %{count} tilin tiedostosta %{filename}. + other: Olet aikeissa estää kaikkiaan %{count} tiliä tiedostosta %{filename}. + bookmarks_html: + one: Olet aikeissa lisätä kaikkiaan %{count} julkaisun tiedostosta %{filename}kirjanmerkkeihisi. + other: Olet aikeissa lisätä kaikkiaan %{count} julkaisua tiedostosta %{filename}kirjanmerkkeihisi. + domain_blocking_html: + one: Olet aikeissa estää kaikkiaan %{count} verkkotunnuksen tiedostosta %{filename}. + other: Olet aikeissa estää kaikkiaan %{count} verkkotunnusta tiedostosta %{filename}. + following_html: + one: Olet aikeissa seurata kaikkiaan %{count} tiliä tiedostosta %{filename}. + other: Olet aikeissa seurata kaikkiaan %{count} tiliä tiedostosta %{filename}. + lists_html: + one: Olet aikeissa lisätä listoihisi kaikkiaan %{count} tilin tiedostosta %{filename}. Uusia listoja luodaan, jos sopivaa kohdelistaa ei ole olemassa. + other: Olet aikeissa lisätä listoihisi kaikkiaan %{count} tiliä tiedostosta %{filename}. Uusia listoja luodaan, jos sopivaa kohdelistaa ei ole olemassa. + muting_html: + one: Olet aikeissa mykistää kaikkiaan %{count} tilin tiedostosta %{filename}. + other: Olet aikeissa mykistää kaikkiaan %{count} tiliä tiedostosta %{filename}. preface: Voit tuoda toiselta palvelimelta viemiäsi tietoja, kuten seuraamiesi tai estämiesi käyttäjien luettelon. recent_imports: Viimeksi tuotu states: diff --git a/config/locales/fo.yml b/config/locales/fo.yml index 31eb67b3b0..55104eb6ff 100644 --- a/config/locales/fo.yml +++ b/config/locales/fo.yml @@ -1365,20 +1365,6 @@ fo: merge_long: Varðveit verandi teigarøð og legg nýggjar afturat overwrite: Skriva omaná overwrite_long: Legg nýggj teigarøð inn fyri tey verandi - overwrite_preambles: - blocking_html: Tú ert í ferð við at útskifta blokeringslistan hjá tær við upp til %{total_items} kontum frá %{filename}. - bookmarks_html: Tú ert í ferð við at útskifta tíni bókamerki við upp til %{total_items} postum frá %{filename}. - domain_blocking_html: Tú ert í ferð við at útskifta navnaøkisblokeringslistan hjá tær við upp til %{total_items} navnaøkjum frá %{filename}. - following_html: Tú ert í ferð við at fylgja upp til %{total_items} kontum frá %{filename} og at gevast at fylgja øðrum. - lists_html: Tú ert í ferð við at skifta listarnar hjá tær út við tað, sum er í %{filename}. Upp til %{total_items} kontur verða lagdar afturat nýggjum listum. - muting_html: Tú ert í ferð við at útskifta listan hjá tær við doyvdum kontum við upp til %{total_items} kontum frá %{filename}. - preambles: - blocking_html: Tú ert í ferð við at blokera upp til %{total_items} kontur frá %{filename}. - bookmarks_html: Tú ert í ferð við at leggja upp til %{total_items} postar frá %{filename} afturat tínum bókamerkjum. - domain_blocking_html: Tú ert í ferð við at blokera upp til %{total_items} navnaøki frá %{filename}. - following_html: Tú ert í ferð við at fylgja upp til %{total_items} kontur frá %{filename}. - lists_html: Tú ert í ferð við at leggja upp til %{total_items} kontur frá %{filename} afturat tínum listum. Nýggir listar verða stovnaðir, um eingin listi er at leggja afturat. - muting_html: Tú ert í ferð við at doyva upp til %{total_items} kontur frá %{filename}. preface: Tú kanst innlesa dátur, sum tú hevur útlisið frá einum øðrum ambætara, so sum listar av fólki, sum tú fylgir ella blokerar. recent_imports: Feskar innflytingar states: diff --git a/config/locales/fr-CA.yml b/config/locales/fr-CA.yml index 16cdb79317..01463edacb 100644 --- a/config/locales/fr-CA.yml +++ b/config/locales/fr-CA.yml @@ -1368,20 +1368,6 @@ fr-CA: merge_long: Garder les enregistrements existants et ajouter les nouveaux overwrite: Écraser overwrite_long: Remplacer les enregistrements actuels par les nouveaux - overwrite_preambles: - blocking_html: Vous allez remplacer votre liste de blocages par jusqu'à %{total_items} comptes tirés de %{filename}. - bookmarks_html: Vous allez remplacer vos signets par jusqu'à %{total_items} posts tirés de %{filename}. - domain_blocking_html: Vous allez remplacer votre liste de blocages de domaines par jusqu'à %{total_items} domaines tirés de %{filename}. - following_html: Vous allez suivre jusqu’à %{total_items} comptes depuis %{filename} et arrêter de suivre n’importe qui d’autre. - lists_html: Vous allez remplacer vos listes par le contenu de %{filename}. Jusqu'à %{total_items} comptes seront ajoutés à de nouvelles listes. - muting_html: Vous allez remplacer votre liste de comptes masqués par jusqu'à %{total_items} comptes tirés de %{filename}. - preambles: - blocking_html: Vous allez bloquer jusqu'à %{total_items} comptes tirés de %{filename}. - bookmarks_html: Vous allez ajouter jusqu'à %{total_items} messages de %{filename} à vos signets. - domain_blocking_html: Vous allez bloquer jusqu'à %{total_items} domaines tirés de %{filename}. - following_html: Vous allez suivre jusqu'à %{total_items} comptes tirés de %{filename}. - lists_html: Vous allez ajouter jusqu'à %{total_items} comptes depuis %{filename} à vos listes. De nouvelles listes seront créées s'il n'y a aucune liste à laquelle les ajouter. - muting_html: Vous allez masquer jusqu'à %{total_items} comptes tirés de %{filename}. preface: Vous pouvez importer certaines données que vous avez exporté d’un autre serveur, comme une liste des personnes que vous suivez ou bloquez sur votre compte. recent_imports: Importations récentes states: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index bc57d00e65..c3ce66c397 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -1368,20 +1368,6 @@ fr: merge_long: Garder les enregistrements existants et ajouter les nouveaux overwrite: Écraser overwrite_long: Remplacer les enregistrements actuels par les nouveaux - overwrite_preambles: - blocking_html: Vous allez remplacer votre liste de blocage par près de %{total_items} comptes tirés de %{filename}. - bookmarks_html: Vous allez remplacer vos signets par près de %{total_items} posts tirés de %{filename}. - domain_blocking_html: Vous allez remplacer votre liste de blocage de domaines par près de %{total_items} domaines tirés de %{filename}. - following_html: Vous allez suivre jusqu’à %{total_items} comptes depuis %{filename} et arrêter de suivre n’importe qui d’autre. - lists_html: Vous allez remplacer vos listes par le contenu de %{filename}. Près de %{total_items} comptes seront ajoutés à de nouvelles listes. - muting_html: Vous allez remplacer votre liste de comptes masqués par près de %{total_items} comptes tirés de %{filename}. - preambles: - blocking_html: Vous allez bloquer près de %{total_items} comptes tirés de %{filename}. - bookmarks_html: Vous allez ajouter près de %{total_items} messages de %{filename} à vos signets. - domain_blocking_html: Vous allez bloquer près de %{total_items} domaines tirés de %{filename}. - following_html: Vous allez suivre près de %{total_items} comptes tirés de %{filename}. - lists_html: Vous allez ajouter près de %{total_items} comptes depuis %{filename} à vos listes. De nouvelles listes seront créées si besoin. - muting_html: Vous allez masquer près de %{total_items} comptes tirés de %{filename}. preface: Vous pouvez importer certaines données que vous avez exporté d’un autre serveur, comme une liste des personnes que vous suivez ou bloquez sur votre compte. recent_imports: Récents imports states: diff --git a/config/locales/fy.yml b/config/locales/fy.yml index 0379af34e9..d63d2ac2aa 100644 --- a/config/locales/fy.yml +++ b/config/locales/fy.yml @@ -24,6 +24,8 @@ fy: admin: account_actions: action: Aksje útfiere + already_silenced: Dizze account is al beheind. + already_suspended: Dizze account is al opskort. title: Moderaasjemaatregelen tsjin %{acct} nimme account_moderation_notes: create: Lit in opmerking efter @@ -45,6 +47,7 @@ fy: title: E-mailadres foar %{username} wizigje change_role: changed_msg: Rol mei sukses wizige! + edit_roles: Brûkersrollen beheare label: Rol wizigje no_role: Gjin rol title: Rol fan %{username} wizigje @@ -601,6 +604,7 @@ fy: suspend_description_html: De account en alle ynhâld sil net tagonklik wêze en úteinlik fuortsmiten wurde, en ynteraksje hjirmei sil net mooglik wêze. Binnen 30 dagen werom te draaien. Dit slút alle rapportaazjes oer dizze account. actions_description_html: Beslis hokker maatregel nommen wurde moat om dizze rapportaazje op te lossen. Wannear’t jo in (straf)maatregel tsjin it rapportearre account nimme, kriget de account in e-mailmelding, behalve wannear’t de spam-kategory keazen is. actions_description_remote_html: Beslút hokker aksje nommen wurde moat om dizze rapportaazje ôf te hanneljen. Dit hat allinnich ynfloed op hoe’t jo server kommunisearret mei dizze eksterne account en omgiet mei de ynhâld. + actions_no_posts: Dit rapport hat gjin byhearrende berjochten om fuort te smiten add_to_report: Mear oan de rapportaazje tafoegje already_suspended_badges: local: Al opskoarte op dizze server @@ -871,6 +875,9 @@ fy: message_html: Jo hawwe foar dizze server gjin regels opsteld. sidekiq_process_check: message_html: Der draait gjin Sidekiq-proses foar de wachtrige(n) %{value}. Kontrolearje jo Sidekiq-konfiguraasje + software_version_check: + action: Beskikbere fernijingen besjen + message_html: Der is in Mastodon-fernijing beskikber. software_version_critical_check: action: Beskikbere fernijingen besjen message_html: Der is in kritike fernijing foar Mastodon beskikber. Wurkje sa gau as mooglik by. @@ -1156,6 +1163,12 @@ fy: view_strikes: Besjoch de earder troch moderatoaren fêststelde skeiningen dy’t jo makke hawwe too_fast: Formulier is te fluch yntsjinne. Probearje it nochris. use_security_key: Befeiligingskaai brûke + author_attribution: + example_title: Faorbyldtekst + hint_html: Bepaal hoe’t wy jo fermelde, wannear’t jo keppelingen op Mastodon dield wurde. + more_from_html: Mear fan %{name} + s_blog: Weblog fan %{name} + title: Auteur-attribúsje challenge: confirm: Trochgean hint_html: "Tip: Wy freegje jo it kommende oere net mear nei jo wachtwurd." @@ -1353,19 +1366,43 @@ fy: overwrite: Oerskriuwe overwrite_long: Aktuele gegevens mei de nije gegevens ferfange overwrite_preambles: - blocking_html: Jo steane op it punt om jo blokkearlist mei mear as %{total_items} accounts fan %{filename} te ferfangen. - bookmarks_html: Jo steane op it punt om jo blêdwizers mei mear as %{total_items} artikelen fan %{filename} te ferfangen. - domain_blocking_html: Jo steane op it punt om jo domeinblokkearlist mei mear as %{total_items} domeinen fan %{filename} te ferfangen. - following_html: Jo steane op it punt om %{total_items} accounts út %{filename} te folgjen en te stopjen mei folgjen fan alle oaren. - lists_html: Jo steane op it punt jo listen te ferfangen troch ynhâld fan %{filename}. Oant %{total_items} accounts sille oan nije listen tafoege wurde. - muting_html: Jo steane op it punt om jo list mei negearre accounts mei mear as %{total_items} accounts fan %{filename} út te ferfangen. + blocking_html: + one: Jo steane op it punt om jo blokkearlist mei mear as %{count} account fan %{filename} te ferfangen. + other: Jo steane op it punt om jo blokkearlist mei mear as %{count} accounts fan %{filename} te ferfangen. + bookmarks_html: + one: Jo steane op it punt om jo blêdwizers mei mear as %{count} artikel fan %{filename} te ferfangen. + other: Jo steane op it punt om jo blêdwizers mei mear as %{count} artikelen fan %{filename} te ferfangen. + domain_blocking_html: + one: Jo steane op it punt om jo domeinblokkearlist mei mear as %{count} domein fan %{filename} te ferfangen. + other: Jo steane op it punt om jo domeinblokkearlist mei mear as %{count} domeinen fan %{filename} te ferfangen. + following_html: + one: Jo steane op it punt om %{count} account út %{filename} te folgjen en te stopjen mei folgjen fan alle oaren. + other: Jo steane op it punt om %{count} accounts út %{filename} te folgjen en te stopjen mei folgjen fan alle oaren. + lists_html: + one: Jo steane op it punt jo listen te ferfangen troch ynhâld fan %{filename}. Oant %{count} account sille oan nije listen tafoege wurde. + other: Jo steane op it punt jo listen te ferfangen troch ynhâld fan %{filename}. Oant %{count} accounts sille oan nije listen tafoege wurde. + muting_html: + one: Jo steane op it punt om jo list mei negearre accounts mei mear as %{count} account fan %{filename} út te ferfangen. + other: Jo steane op it punt om jo list mei negearre accounts mei mear as %{count} accounts fan %{filename} út te ferfangen. preambles: - blocking_html: Jo steane op it punt om %{total_items} accounts fan %{filename} út te blokkearjen. - bookmarks_html: Jo steane op it punt om %{total_items} berjochten fan %{filename} út oan jo blêdwizers ta te foegjen. - domain_blocking_html: Jo steane op it punt om %{total_items} domeinen fan %{filename} út te blokkearjen. - following_html: Jo steane op it punt om %{total_items} accounts fan %{filename} út te folgjen. - lists_html: Jo steane op it punt om oant %{total_items} accounts fan %{filename} ta te foegjen oan jo listen. Nije listen wurde oanmakke as der gjin list is om oan ta te foegjen. - muting_html: Jo steane op it punt om %{total_items} accounts fan %{filename} út te negearjen. + blocking_html: + one: Jo steane op it punt om %{count} account fan %{filename} út te blokkearjen. + other: Jo steane op it punt om %{count} accounts fan %{filename} út te blokkearjen. + bookmarks_html: + one: Jo steane op it punt om %{count} berjocht fan %{filename} út oan jo blêdwizers ta te foegjen. + other: Jo steane op it punt om %{count} berjochten fan %{filename} út oan jo blêdwizers ta te foegjen. + domain_blocking_html: + one: Jo steane op it punt om %{count} domein fan %{filename} út te blokkearjen. + other: Jo steane op it punt om %{count} domeinen fan %{filename} út te blokkearjen. + following_html: + one: Jo steane op it punt om %{count} account fan %{filename} út te folgjen. + other: Jo steane op it punt om %{count} accounts fan %{filename} út te folgjen. + lists_html: + one: Jo steane op it punt om oant %{count} account fan %{filename} ta te foegjen oan jo listen. Nije listen wurde oanmakke as der gjin list is om oan ta te foegjen. + other: Jo steane op it punt om oant %{count} accounts fan %{filename} ta te foegjen oan jo listen. Nije listen wurde oanmakke as der gjin list is om oan ta te foegjen. + muting_html: + one: Jo steane op it punt om %{count} account fan %{filename} út te negearjen. + other: Jo steane op it punt om %{count} accounts fan %{filename} út te negearjen. preface: Jo kinne bepaalde gegevens, lykas de minsken dy’t jo folgje of blokkearre hawwe, nei jo account op dizze server ymportearje. Jo moatte dizze gegevens wol earst op de oarspronklike server eksportearje. recent_imports: Resinte ymports states: @@ -1682,6 +1719,7 @@ fy: delete: Account fuortsmite development: Untwikkelers edit_profile: Profyl bewurkje + export: Eksportearje featured_tags: Utljochte hashtags import: Ymportearje import_and_export: Ymportearje en eksportearje @@ -1931,6 +1969,7 @@ fy: instructions_html: Kopiearje en plak de ûndersteande koade yn de HTML fan jo website. Foegje dernei it adres fan jo website ta oan ien fan de ekstra fjilden op jo profyl op it ljepblêd ‘Profyl bewurkje’ en bewarje de wizigingen. verification: Ferifikaasje verified_links: Jo ferifiearre keppelingen + website_verification: Website-ferifikaasje webauthn_credentials: add: Nije befeiligingskaai tafoegje create: diff --git a/config/locales/ga.yml b/config/locales/ga.yml index e25865903e..a201b73325 100644 --- a/config/locales/ga.yml +++ b/config/locales/ga.yml @@ -1440,20 +1440,6 @@ ga: merge_long: Coinnigh taifid atá ann cheana féin agus cuir cinn nua leis overwrite: Forscríobh overwrite_long: Cuir na cinn nua in ionad na dtaifead reatha - overwrite_preambles: - blocking_html: Tá tú ar tí do liosta bloc a chur in ionad suas le %{total_items} cuntas ó %{filename}. - bookmarks_html: Tá tú ar tí do leabharmharcanna a chur in ionad suas le %{total_items} postáil ó %{filename}. - domain_blocking_html: Tá tú ar tí do liosta bloc fearainn a chur in ionad suas le %{total_items} fearainn ó %{filename}. - following_html: Tá tú ar tí leanúint suas go dtí %{total_items} cuntas ó %{filename} agus stop a leanúint aon duine eile. - lists_html: Tá tú ar tí do liostaí a chur in ionad inneachair %{filename}. Cuirfear suas le %{total_items} cuntas le liostaí nua. - muting_html: Tá tú ar tí do liosta cuntas balbhaithe a chur in ionad suas le %{total_items} cuntas ó %{filename}. - preambles: - blocking_html: Tá tú ar tí bloc suas le %{total_items} cuntas ó %{filename}. - bookmarks_html: Tá tú ar tí %{total_items} postáil ó %{filename} a chur le do leabharmharcanna. - domain_blocking_html: Tá tú ar tí bloc suas le %{total_items} fearainn ó %{filename}. - following_html: Tá tú ar tí leanúint suas go dtí %{total_items} cuntas ó %{filename}. - lists_html: Tá tú ar tí %{total_items} cuntas ó %{filename} a chur le do liostaí. Cruthófar liostaí nua mura bhfuil aon liosta le cur leis. - muting_html: Tá tú ar tí balbhú suas le %{total_items} cuntas ó %{filename}. preface: Is féidir leat sonraí a d’easpórtáil tú a allmhairiú ó fhreastalaí eile, mar shampla liosta de na daoine a bhfuil tú ag leanúint nó ag cur bac orthu. recent_imports: Allmhairí le déanaí states: diff --git a/config/locales/gd.yml b/config/locales/gd.yml index a030b0d185..cb7c6254bc 100644 --- a/config/locales/gd.yml +++ b/config/locales/gd.yml @@ -1415,20 +1415,6 @@ gd: merge_long: Cùm na reacordan a tha ann is cuir feadhainn ùr ris overwrite: Sgrìobh thairis air overwrite_long: Cuir na reacordan ùra an àite na feadhna a tha ann - overwrite_preambles: - blocking_html: Tha thu an impis suas ri %{total_items} cunntas(an) o %{filename} a chur an àite liosta nam bacaidhean agad. - bookmarks_html: Tha thu an impis suas ri %{total_items} post(aichean) o %{filename} a chur an àite nan comharra-lìn agad. - domain_blocking_html: Tha thu an impis suas ri %{total_items} àrainn(ean) o %{filename} a chur an àite liosta nam bacaidhean àrainne agad. - following_html: Tha thu an impis suas ri %{total_items} cunntas(an) o %{filename} a leantainn agus sguiridh tu a leantainn duine sam bith eile. - lists_html: Tha thu an impis susbaint %{filename} a chur an àite nan liostaichean agad. Thèid suas ri %{total_items}cunntas(an) a chur ri liostaichean ùra. - muting_html: Tha thu an impis suas ri %{total_items} cunntas(an) o %{filename} a chur an àite liosta nan cunntasan mùchte agad. - preambles: - blocking_html: Tha thu an impis suas ri %{total_items} cunntas(an) o %{filename} a bhacadh. - bookmarks_html: Tha thu an impis suas ri %{total_items} post(aichean) o %{filename} a chur ris na h-annsachdan agad. - domain_blocking_html: Tha thu an impis suas ri %{total_items} àrainn(ean) o %{filename} a bhacadh. - following_html: Tha thu an impis suas ri %{total_items} cunntas(an) o %{filename} a leantainn. - lists_html: Tha thu an impis suas ri %{total_items} cunntas(an) o %{filename} a chur ris na liostaichean agad. Thèid liostaichean ùra a chruthachadh mur eil liostaichean ann airson nan cunntasan a chur ris. - muting_html: Tha thu an impis suas ri %{total_items} cunntas(an) o %{filename} a mhùchadh. preface: "’S urrainn dhut dàta ion-phortadh a dh’às-phortaich thu o fhrithealaiche eile, can liosta nan daoine a leanas tu no a tha thu a’ bacadh." recent_imports: Ion-phortaidhean o chionn goirid states: diff --git a/config/locales/gl.yml b/config/locales/gl.yml index e396761f7e..8460902a68 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -1366,19 +1366,43 @@ gl: overwrite: Sobreescribir overwrite_long: Sustituír rexistros actuais cos novos overwrite_preambles: - blocking_html: Vas substituír a lista de bloqueos por %{total_items} contas desde %{filename}. - bookmarks_html: Vas substituír os marcadores por %{total_items} publicacións desde %{filename}. - domain_blocking_html: Vas substituír a lista de dominios bloqueados por %{total_items} dominios desde %{filename}. - following_html: Vas seguir estas %{total_items} contas desde %{filename} e deixar de seguir a todas as outras contas. - lists_html: Vas substituír as túas listas co contido de %{filename}. Vanse engadir %{total_items} contas ás novas listas. - muting_html: Vas substituír a lista de contas acaladas por %{total_items} contas desde %{filename}. + blocking_html: + one: Vas substituír a lista de bloqueos por %{count} conta desde %{filename}. + other: Vas substituír a lista de bloqueos por %{count} contas desde %{filename}. + bookmarks_html: + one: Vas substituír os marcadores por %{count} publicación desde %{filename}. + other: Vas substituír os marcadores por %{count} publicacións desde %{filename}. + domain_blocking_html: + one: Vas substituír a lista de dominios bloqueados por %{count} dominio desde %{filename}. + other: Vas substituír a lista de dominios bloqueados por %{count} dominios desde %{filename}. + following_html: + one: Vas seguir a %{count} conta desde %{filename} e deixar de seguir a todas as outras contas. + other: Vas seguir a %{count} contas desde %{filename} e deixar de seguir a todas as outras contas. + lists_html: + one: Vas substituír as túas listas co contido de %{filename}. Vaise engadir %{count} conta ás novas listas. + other: Vas substituír as túas listas co contido de %{filename}. Vanse engadir %{count} contas ás novas listas. + muting_html: + one: Vas substituír a lista de contas acaladas por %{count} conta desde %{filename}. + other: Vas substituír a lista de contas acaladas por %{count} contas desde %{filename}. preambles: - blocking_html: Vas bloquear estas %{total_items} contas desde %{filename}. - bookmarks_html: Vas engadir %{total_items} publicacións desde %{filename} aos teus marcadores. - domain_blocking_html: Vas bloquear estes %{total_items} dominios desde %{filename}. - following_html: Vas seguir estas %{total_items} contas desde %{filename}. - lists_html: Vas engadir %{total_items} contas desde %{filename} ás túas listas. Crearánse novas listas se non hai listas ás que engadilas. - muting_html: Vas acalar estas %{total_items} contas desde %{filename}. + blocking_html: + one: Vas bloquear a %{count} conta desde %{filename}. + other: Vas bloquear a %{count} contas desde %{filename}. + bookmarks_html: + one: Vas engadir %{count} publicación desde %{filename} aos teus marcadores. + other: Vas engadir %{count} publicacións desde %{filename} aos teus marcadores. + domain_blocking_html: + one: Vas bloquear a %{count} dominio desde %{filename}. + other: Vas bloquear a %{count} dominios desde %{filename}. + following_html: + one: Vas seguir a %{count} conta desde %{filename}. + other: Vas seguir a %{count} contas desde %{filename}. + lists_html: + one: Vas engadir %{count} conta desde %{filename} ás túas listas. Crearánse novas listas se non hai listas ás que engadilas. + other: Vas engadir %{count} contas desde %{filename} ás túas listas. Crearánse novas listas se non hai listas ás que engadilas. + muting_html: + one: Vas acalar a %{count} conta desde %{filename}. + other: Vas acalar a %{count} contas desde %{filename}. preface: Podes importar os datos que exportaches doutro servidor, tales como a lista de usuarias que estás a seguir ou bloquear. recent_imports: Importacións recentes states: diff --git a/config/locales/he.yml b/config/locales/he.yml index 846b0d14af..f2732678b5 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -1416,19 +1416,67 @@ he: overwrite: דריסה overwrite_long: החלף רשומות נוכחיות בחדשות overwrite_preambles: - blocking_html: אתם עומדים להחליף את רשימת החסימות עד כדי %{total_items} חשבונות מהקובץ %{filename}. - bookmarks_html: אתם עומדים להחליף את רשימת הסימניות עד כדי %{total_items} הודעות מהקובץ %{filename}. - domain_blocking_html: אתם עומדים להחליף את רשימת חסימות השרתים עד כדי %{total_items} שרתים מהקובץ %{filename}. - following_html: אתם עומדים לעקוב עד כדי %{total_items} חשבונות מהקובץ %{filename} ובמקביל להפסיק מעקב אחרי כל משתמש אחר. - lists_html: הפעולה הבאה תחליף את רשימותיך בתוכן של %{filename}. עד %{total_items} חשבונות יתווספו לרשימות חדשות. - muting_html: אתם עומדים להחליף את רשימת ההשתקות עד כדי %{total_items} חשבונות מהקובץ %{filename}. + blocking_html: + many: אתם עומדים להחליף את רשימת החסימות עד כדי %{count} חשבונות מהקובץ %{filename}. + one: אתם עומדים להחליף את רשימת החסימות %{count} בחשבון אחד מהקובץ %{filename}. + other: אתם עומדים להחליף את רשימת החסימות עד כדי %{count} חשבונות מהקובץ %{filename}. + two: אתם עומדים להחליף את רשימת החסימות בעד שני חשבונות מהקובץ %{filename}. + bookmarks_html: + many: אתם עומדים להחליף את רשימת הסימניות עד כדי %{count} הודעות מהקובץ %{filename}. + one: אתם עומדים להחליף את רשימת הסימניות בהודעה אחת מהקובץ %{filename}. + other: אתם עומדים להחליף את רשימת הסימניות עד כדי %{count} הודעות מהקובץ %{filename}. + two: אתם עומדים להחליף את רשימת הסימניות עד כדי שתי הודעות מהקובץ %{filename}. + domain_blocking_html: + many: אתם עומדים להחליף את רשימת חסימות השרתים עד כדי %{count} שרתים מהקובץ %{filename}. + one: אתם עומדים להחליף את רשימת חסימות השרתים בשרת אחד מהקובץ %{filename}. + other: אתם עומדים להחליף את רשימת חסימות השרתים עד כדי %{count} שרתים מהקובץ %{filename}. + two: אתם עומדים להחליף את רשימת חסימות השרתים עד כדי שני שרתים מהקובץ %{filename}. + following_html: + many: אתם עומדים לעקוב אחרי עד כדי %{count} חשבונות מהקובץ %{filename} ובמקביל להפסיק מעקב אחרי כל משתמש אחר. + one: אתם עומדים לעקוב אחרי חשבון אחד מהקובץ %{filename} ובמקביל להפסיק מעקב אחרי כל משתמש אחר. + other: אתם עומדים לעקוב אחרי עד כדי %{count} חשבונות מהקובץ %{filename} ובמקביל להפסיק מעקב אחרי כל משתמש אחר. + two: אתם עומדים לעקוב אחרי עד כדי שני חשבונות מהקובץ %{filename} ובמקביל להפסיק מעקב אחרי כל משתמש אחר. + lists_html: + many: הפעולה הבאה תחליף את רשימותיך בתוכן של %{filename}. עד %{count} חשבונות יתווספו לרשימות חדשות. + one: הפעולה הבאה תחליף את רשימותיך בתוכן של %{filename}. עד חשבון אחד יתווסף לרשימות חדשות. + other: הפעולה הבאה תחליף את רשימותיך בתוכן של %{filename}. עד %{count} חשבונות יתווספו לרשימות חדשות. + two: הפעולה הבאה תחליף את רשימותיך בתוכן של %{filename}. עד שני חשבונות יתווספו לרשימות חדשות. + muting_html: + many: אתם עומדים להחליף את רשימת ההשתקות בעד כדי %{count} חשבונות מהקובץ %{filename}. + one: אתם עומדים להחליף את רשימת ההשתקות בחשבון אחד מהקובץ %{filename}. + other: אתם עומדים להחליף את רשימת ההשתקות בעד כדי %{count} חשבונות מהקובץ %{filename}. + two: אתם עומדים להחליף את רשימת ההשתקות בעד כדי שני חשבונות מהקובץ %{filename}. preambles: - blocking_html: אתם עומדים לחסום עד %{total_items} חשבונות מהקובץ %{filename}. - bookmarks_html: אתם עומדים להוסיף עד %{total_items} הודעות מהקובץ %{filename} לרשימת הסימניות שלכם. - domain_blocking_html: אתם עומדים לחסום עד כדי %{total_items} שרתים מהקובץ %{filename}. - following_html: אתם עומדים לעקוב אחרי עד %{total_items} חשבונות מהקובץ %{filename}. - lists_html: הפעולה הבאה תוסיף עד %{total_items} חשבונות מהקובץ %{filename} אל הרשימות שלך. רשימות חדשות יווצרו אם עוד לא קיימת רשימה להוסיף אליה. - muting_html: אתם עומדים להשתיק עד %{total_items} חשבונות מהקובץ %{filename}. + blocking_html: + many: אתם עומדים לחסום עד %{count} חשבונות מהקובץ %{filename}. + one: אתם עומדים לחסוםחשבון אחד מהקובץ %{filename}. + other: אתם עומדים לחסום עד %{count} חשבונות מהקובץ %{filename}. + two: אתם עומדים לחסום עד שני חשבונות מהקובץ %{filename}. + bookmarks_html: + many: אתם עומדים להוסיף עד %{count} הודעות מהקובץ %{filename} לרשימת הסימניות שלכם. + one: אתם עומדים להוסיףהודעה אחת מהקובץ %{filename} לרשימת הסימניות שלכם. + other: אתם עומדים להוסיף עד %{count} הודעות מהקובץ %{filename} לרשימת הסימניות שלכם. + two: אתם עומדים להוסיף עד שתי הודעות מהקובץ %{filename} לרשימת הסימניות שלכם. + domain_blocking_html: + many: אתם עומדים לחסום עד כדי %{count} שרתים מהקובץ %{filename}. + one: אתם עומדים לחסום עד שרת אחד מהקובץ %{filename}. + other: אתם עומדים לחסום עד כדי %{count} שרתים מהקובץ %{filename}. + two: אתם עומדים לחסום עד כדי שני שרתים מהקובץ %{filename}. + following_html: + many: אתם עומדים לעקוב אחרי עד %{count} חשבונות מהקובץ %{filename}. + one: אתם עומדים לעקוב אחרי עד חשבון אחד מהקובץ %{filename}. + other: אתם עומדים לעקוב אחרי עד %{count} חשבונות מהקובץ %{filename}. + two: אתם עומדים לעקוב אחרי עד שני חשבונות מהקובץ %{filename}. + lists_html: + many: הפעולה הבאה תוסיף עד %{count} חשבונות מהקובץ %{filename} אל הרשימות שלך. רשימות חדשות יווצרו אם עוד לא קיימת רשימה להוסיף אליה. + one: הפעולה הבאה תוסיף עד חשבון אחד מהקובץ %{filename} אל הרשימות שלך. רשימות חדשות יווצרו אם עוד לא קיימת רשימה להוסיף אליה. + other: הפעולה הבאה תוסיף עד %{count} חשבונות מהקובץ %{filename} אל הרשימות שלך. רשימות חדשות יווצרו אם עוד לא קיימת רשימה להוסיף אליה. + two: הפעולה הבאה תוסיף עד שני חשבונות מהקובץ %{filename} אל הרשימות שלך. רשימות חדשות יווצרו אם עוד לא קיימת רשימה להוסיף אליה. + muting_html: + many: אתם עומדים להשתיק עד %{count} חשבונות מהקובץ %{filename}. + one: אתם עומדים להשתיק עד חשבון אחד מהקובץ %{filename}. + other: אתם עומדים להשתיק עד %{count} חשבונות מהקובץ %{filename}. + two: אתם עומדים להשתיק עד שני חשבונות מהקובץ %{filename}. preface: ניתן ליבא מידע מסויים כגון כל הנעקבים או המשתמשים החסומים לתוך חשבונך על שרת זה, מתוך קבצים שנוצרו על ידי יצוא משרת אחר כגון רשימת הנעקבים והחסומים שלך. recent_imports: ייבואים אחרונים states: diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 5a00db9548..15c632adc9 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -1366,19 +1366,43 @@ hu: overwrite: Felülírás overwrite_long: Lecseréljük újakkal a jelenlegi bejegyzéseket overwrite_preambles: - blocking_html: 'Arra készülsz, hogy lecseréld a letiltási listát legfeljebb %{total_items} fiókra a következőből: %{filename}.' - bookmarks_html: 'Arra készülsz, hogy lecseréld a könyvjelzőket legfeljebb %{total_items} bejegyzésre a következőből: %{filename}.' - domain_blocking_html: 'Arra készülsz, hogy lecseréld a domain letiltási listát legfeljebb %{total_items} domainre a következőből: %{filename}.' - following_html: 'Arra készülsz, hogy legfeljebb %{total_items} fiókot kövess a következőből: %{filename}, és abbahagyd mindenki más követését.' - lists_html: Arra készülsz, hogy a listákat lecseréld a %{filename} tartalmával. Legfeljebb %{total_items} fiók kerül fel az új listákra. - muting_html: 'Arra készülsz, hogy lecseréld a némított fiókok listáját legfeljebb %{total_items} fiókra a következőből: %{filename}.' + blocking_html: + one: 'Arra készülsz, hogy lecseréld a letiltási listát legfeljebb %{count} fiókra a következőből: %{filename}.' + other: 'Arra készülsz, hogy lecseréld a letiltási listát legfeljebb %{count} fiókra a következőből: %{filename}.' + bookmarks_html: + one: 'Arra készülsz, hogy lecseréld a könyvjelzőket legfeljebb %{count} bejegyzésre a következőből: %{filename}.' + other: 'Arra készülsz, hogy lecseréld a könyvjelzőket legfeljebb %{count} bejegyzésre a következőből: %{filename}.' + domain_blocking_html: + one: 'Arra készülsz, hogy lecseréld a domain letiltási listát legfeljebb %{count} domainre a következőből: %{filename}.' + other: 'Arra készülsz, hogy lecseréld a domain letiltási listát legfeljebb %{count} domainre a következőből: %{filename}.' + following_html: + one: 'Arra készülsz, hogy legfeljebb %{count} fiókot kövess a következőből: %{filename}, és abbahagyd mindenki más követését.' + other: 'Arra készülsz, hogy legfeljebb %{count} fiókot kövess a következőből: %{filename}, és abbahagyd mindenki más követését.' + lists_html: + one: Arra készülsz, hogy a listákat lecseréld a %{filename} tartalmával. Legfeljebb %{count} fiók kerül fel az új listákra. + other: Arra készülsz, hogy a listákat lecseréld a %{filename} tartalmával. Legfeljebb %{count} fiók kerül fel az új listákra. + muting_html: + one: 'Arra készülsz, hogy lecseréld a némított fiókok listáját legfeljebb %{count} fiókra a következőből: %{filename}.' + other: 'Arra készülsz, hogy lecseréld a némított fiókok listáját legfeljebb %{count} fiókra a következőből: %{filename}.' preambles: - blocking_html: 'Arra készülsz, hogy legfeljebb %{total_items} fiókot letilts a következőből: %{filename}.' - bookmarks_html: 'Arra készülsz, hogy legfeljebb %{total_items} bejegyzést adj hozzá a könyvjelzőkhöz a következőből: %{filename}.' - domain_blocking_html: 'Arra készülsz, hogy legfeljebb %{total_items} domaint letilts a következőből: %{filename}.' - following_html: 'Arra készülsz, hogy legfeljebb %{total_items} fiókot kövess a következőből: %{filename}.' - lists_html: Arra készülsz, hogy legfeljebb %{total_items} fiókot hozzáadj a %{filename} fájlból a listákhoz. Új listák jönnek létre, ha nincs hozzáadható lista. - muting_html: 'Arra készülsz, hogy legfeljebb %{total_items} fiókot némíts a következőből: %{filename}.' + blocking_html: + one: 'Arra készülsz, hogy legfeljebb %{count} fiókot letilts a következőből: %{filename}.' + other: 'Arra készülsz, hogy legfeljebb %{count} fiókot letilts a következőből: %{filename}.' + bookmarks_html: + one: 'Arra készülsz, hogy legfeljebb %{count} bejegyzést adj hozzá a könyvjelzőkhöz a következőből: %{filename}.' + other: 'Arra készülsz, hogy legfeljebb %{count} bejegyzést adj hozzá a könyvjelzőkhöz a következőből: %{filename}.' + domain_blocking_html: + one: 'Arra készülsz, hogy legfeljebb %{count} domaint letilts a következőből: %{filename}.' + other: 'Arra készülsz, hogy legfeljebb %{count} domaint letilts a következőből: %{filename}.' + following_html: + one: 'Arra készülsz, hogy legfeljebb %{count} fiókot kövess a következőből: %{filename}.' + other: 'Arra készülsz, hogy legfeljebb %{count} fiókot kövess a következőből: %{filename}.' + lists_html: + one: Arra készülsz, hogy legfeljebb %{count} fiókot hozzáadj a %{filename} fájlból a listákhoz. Új listák jönnek létre, ha nincs hozzáadható lista. + other: Arra készülsz, hogy legfeljebb %{count} fiókot hozzáadj a %{filename} fájlból a listákhoz. Új listák jönnek létre, ha nincs hozzáadható lista. + muting_html: + one: 'Arra készülsz, hogy legfeljebb %{count} fiókot némíts a következőből: %{filename}.' + other: 'Arra készülsz, hogy legfeljebb %{count} fiókot némíts a következőből: %{filename}.' preface: Itt importálhatod egy másik kiszolgálóról lementett adataidat, például követettjeid és letiltott felhasználóid listáját. recent_imports: Legutóbbi importálások states: diff --git a/config/locales/ia.yml b/config/locales/ia.yml index a8bc48b306..4d9148674d 100644 --- a/config/locales/ia.yml +++ b/config/locales/ia.yml @@ -1346,20 +1346,6 @@ ia: merge_long: Conservar le registros existente e adder noves overwrite: Superscriber overwrite_long: Reimplaciar registros actual con le noves - overwrite_preambles: - blocking_html: Tu es sur le puncto de reimplaciar tu lista de blocadas per usque a %{total_items} contos proveniente de %{filename}. - bookmarks_html: Tu es sur le puncto de reimplaciar tu marcapaginas per usque a %{total_items} messages desde %{filename}. - domain_blocking_html: Tu es sur le puncto de reimplaciar tu lista de blocadas de dominio per usque a %{total_items} dominios proveniente de %{filename}. - following_html: Tu es sur le puncto de sequer usque a %{total_items} contos de %{filename} e cessar de sequer tote le alteres. - lists_html: Tu es sur le puncto de reimplaciar tu listas per le contento de %{filename}. Usque a %{total_items} contos essera addite a nove listas. - muting_html: Tu es sur le puncto de reimplaciar tu lista de contos silentiate con usque a %{total_items} contos desde %{filename}. - preambles: - blocking_html: Tu es sur le puncto de blocar usque a %{total_items} contos a partir de %{filename}. - bookmarks_html: Tu es sur le puncto de adder usque a %{total_items} messages desde %{filename} a tu marcapaginas. - domain_blocking_html: Tu es sur le puncto de blocar usque a %{total_items} dominios a partir de %{filename}. - following_html: Tu es sur le puncto de sequer usque a %{total_items} contos desde %{filename}. - lists_html: Tu es sur le puncto de adder usque %{total_items} contos desde %{filename} a tu listas. Nove listas essera create si il non ha un lista al qual adder los. - muting_html: Tu es sur le puncto de silentiar usque a %{total_items} contos desde %{filename}. preface: Tu pote importar datos que tu ha exportate de un altere servitor, como un lista de personas que tu seque o bloca. recent_imports: Importationes recente states: diff --git a/config/locales/ie.yml b/config/locales/ie.yml index 7e8140a374..94c4b7f4f0 100644 --- a/config/locales/ie.yml +++ b/config/locales/ie.yml @@ -1274,20 +1274,6 @@ ie: merge_long: Conservar existent registres e adjunter li novis overwrite: Remplazzar overwrite_long: Remplazzar existent registres per li novis - overwrite_preambles: - blocking_html: Tu va remplazzar tui liste de bloccat contos per til %{total_items} contos de %{filename}. - bookmarks_html: Tu va remplazzar tui marcatores per til %{total_items} postas de %{filename}. - domain_blocking_html: Tu va remplazzar tui liste de bloccat dominias per til %{total_items} dominias de %{filename}. - following_html: Tu va sequer til %{total_items} contos de %{filename} e dessequer omni altri contos. - lists_html: Tu va remplazzar tui listes per li contenete de %{filename}. Til %{total_items} contos va esser adjuntet a nov listes. - muting_html: Tu va remplazzar tui liste de silentiat contos per til %{total_items} contos de %{filename}. - preambles: - blocking_html: Tu va bloccar til %{total_items} contos de %{filename}. - bookmarks_html: Tu va adjunter til %{total_items} postas de %{filename} a tui marcatores. - domain_blocking_html: Tu va bloccar til %{total_items} dominias de %{filename}. - following_html: Tu va sequer til %{total_items} contos de %{filename}. - lists_html: Tu va adjunter til %{total_items} contos de %{filename} a tui listes. Nov listes va esser creat si ne hay un liste a quel adjunter. - muting_html: Tu va silentiar til %{total_items} contos de %{filename}. preface: Tu posse importar data quel tu ha exportat de un altri servitor, quam un liste del gente quem tu seque o blocca. recent_imports: Recent importationes states: diff --git a/config/locales/io.yml b/config/locales/io.yml index dfb583450a..8ce5f3403b 100644 --- a/config/locales/io.yml +++ b/config/locales/io.yml @@ -1247,20 +1247,6 @@ io: merge_long: Retenez displonebla rekordi e insertez novi overwrite: Remplasez overwrite_long: Remplasez nuna rekordi per novi - overwrite_preambles: - blocking_html: Vu substitucos vua blokusolisto per til %{total_items} konti de %{filename}. - bookmarks_html: Vu substitucos vua libromarki per til %{total_items} posti de %{filename}. - domain_blocking_html: Vu substitucos vua domenoblokusolisto per til %{total_items} domeni de %{filename}. - following_html: Vu sequos til %{total_items} konti de %{filename} e haltar sequar irga altra konto. - lists_html: Vu substitucos vua listi kun la kontenaji di %{filename}. Til %{total_items} konti adjuntesos a nova listi. - muting_html: Vu substitucos vua listo di konti silencigita per til %{total_items} konti de %{filename}. - preambles: - blocking_html: Vu blokusos til %{total_items} konti de %{filename}. - bookmarks_html: Vu adjuntos %{total_items} posti de %{filename} a vua libromarki. - domain_blocking_html: Vu blokusos til %{total_items} domeni de %{filename}. - following_html: Vu sequos til %{total_items} konti de %{filename}. - lists_html: Vu adjuntos til %{total_items} konti de %{filename} a vua listi. Nova listi kreesos se ne existas listo a quo adjuntar. - muting_html: Vu silencigos til %{total_items} konti en %{filename}. preface: Tu povas importacar kelka datumi, tal quala listi de omna homi quin tu sequas o blokusas, a tua konto di ca instaluro, per dosiero exportacita de altra instaluro. recent_imports: Importacaji recenta states: diff --git a/config/locales/is.yml b/config/locales/is.yml index 4af26eea0b..6eefaf1b0e 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -877,6 +877,9 @@ is: message_html: Þú hefur ekki skilgreint neinar reglur fyrir netþjón. sidekiq_process_check: message_html: Ekkert Sidekiq-ferli er í gangi fyrir %{value} biðröð/biðraðir. Endilega athugaðu Sidekiq-uppsetninguna þína + software_version_check: + action: Skoða tiltækar uppfærslur + message_html: Uppfærsla er tiltæk fyrir Mastodon. software_version_critical_check: action: Skoða tiltækar uppfærslur message_html: Áríðandi uppfærsla Mastodon er tiltæk, uppfærðu eins fljótt og auðið er. @@ -1366,20 +1369,6 @@ is: merge_long: Halda fyrirliggjandi færslum og bæta við nýjum overwrite: Skrifa yfir overwrite_long: Skipta út fyrirliggjandi færslum með þeim nýju - overwrite_preambles: - blocking_html: Þú er í þann mund að fara að skipta út útilokanalistanum þínum með allt að %{total_items} aðgöngum úr %{filename}. - bookmarks_html: Þú er í þann mund að fara að skipta út bókamerkjunum þínum með allt að %{total_items} færslum úr %{filename}. - domain_blocking_html: Þú er í þann mund að fara að skipta út listanum þínum yfir útilokuð lén með allt að %{total_items} lénum úr %{filename}. - following_html: Þú er í þann mund að fara að fylgjast með allt að %{total_items} aðgöngum úr %{filename} og hætta að fylgjast með öllum öðrum. - lists_html: Þú ert í þann mund að fara að skipta út listunum þínum með efninu úr %{filename}. Allt að %{total_items} aðgöngum verður bætt við nýju listana. - muting_html: Þú er í þann mund að fara að skipta út listanum þínum yfir útilokaða aðganga með allt að %{total_items} aðgöngum úr %{filename}. - preambles: - blocking_html: Þú er í þann mund að fara að útiloka allt að %{total_items} aðganga úr %{filename}. - bookmarks_html: Þú er í þann mund að fara að bæta við allt að %{total_items} færslum úr %{filename} við bókamerkin þín. - domain_blocking_html: Þú er í þann mund að fara að útiloka allt að %{total_items} lén úr %{filename}. - following_html: Þú er í þann mund að fara að fylgjast með allt að %{total_items} aðgöngum úr %{filename}. - lists_html: Þú ert í þann mund að fara að bæta við allt að %{total_items} aðgöngum úr %{filename} við listana þína. Nýir listar verða útbúnir ef ekki finnst neinn listi til að bæta í. - muting_html: Þú er í þann mund að fara að þagga allt að %{total_items} aðganga úr %{filename}. preface: Þú getur flutt inn gögn sem þú hefur flutt út frá öðrum vefþjóni, svo sem lista yfir fólk sem þú fylgist með eða útilokar. recent_imports: Nýlega flutt inn states: @@ -1696,6 +1685,7 @@ is: delete: Eyðing notandaaðgangs development: Þróun edit_profile: Breyta notandasniði + export: Flytja út featured_tags: Myllumerki með aukið vægi import: Flytja inn import_and_export: Inn- og útflutningur diff --git a/config/locales/it.yml b/config/locales/it.yml index a89fa0a53e..91b67c2b4d 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -1368,19 +1368,43 @@ it: overwrite: Sovrascrivi overwrite_long: Sostituisci record attuali con quelli nuovi overwrite_preambles: - blocking_html: Stai per sostituire la tua lista di blocchi con un massimo di %{total_items} account da %{filename}. - bookmarks_html: Stai per sostituire i tuoi segnalibri con un massimo di %{total_items} post da %{filename}. - domain_blocking_html: Stai per sostituire la tua lista di domini bloccati con un massimo di %{total_items} domini da %{filename}. - following_html: Stai per seguire fino a %{total_items} account da %{filename} e smettere di seguire chiunque altro. - lists_html: Stai per sostituire le tue liste con i contenuti di %{filename}. Fino a %{total_items} profili verranno aggiunti a nuove liste. - muting_html: Stai per sostituire la tua lista di account silenziati con un massimo di %{total_items} account da %{filename}. + blocking_html: + one: Stai per sostituire la tua lista di blocchi con %{count} account da %{filename}. + other: Stai per sostituire la tua lista di blocchi con %{count} account da %{filename}. + bookmarks_html: + one: Stai per sostituire i tuoi segnalibri con %{count} post da %{filename}. + other: Stai per sostituire i tuoi segnalibri con %{count} post da %{filename}. + domain_blocking_html: + one: Stai per sostituire la tua lista di domini bloccati con %{count} dominio da %{filename}. + other: Stai per sostituire la tua lista di domini bloccati con %{count} domini da %{filename}. + following_html: + one: Stai per seguire %{count} account da %{filename} e smettere di seguire chiunque altro. + other: Stai per seguire %{count} account da %{filename} e smettere di seguire chiunque altro. + lists_html: + one: Stai per sostituire le tue liste con il contenuto di %{filename}. Verrà aggiunto %{count} account alle nuove liste. + other: Stai per sostituire le tue liste con il contenuto di %{filename}. Verranno aggiunti %{count} account alle nuove liste. + muting_html: + one: Stai per sostituire la lista degli account silenziati con %{count} account da %{filename}. + other: Stai per sostituire la lista degli account silenziati con %{count} account da %{filename}. preambles: - blocking_html: Stai per bloccare fino a %{total_items} account da %{filename}. - bookmarks_html: Stai per aggiungere fino a %{total_items} post da %{filename} ai tuoi segnalibri. - domain_blocking_html: Stai per bloccare fino a %{total_items} domini da %{filename}. - following_html: Stai per seguire fino a %{total_items} account da %{filename}. - lists_html: Stai per aggiungere fino a %{total_items} profili da %{filename} alla tue liste. Le nuove liste saranno create se non c'è una lista a cui aggiungere. - muting_html: Stai per silenziare fino a %{total_items} account da %{filename}. + blocking_html: + one: Stai per bloccare %{count} account da %{filename}. + other: Stai per bloccare %{count} account da %{filename}. + bookmarks_html: + one: Stai per aggiungere %{count} post da %{filename} ai tuoi segnalibri. + other: Stai per aggiungere %{count} post da %{filename} ai tuoi segnalibri. + domain_blocking_html: + one: Stai per bloccare %{count} dominio da %{filename}. + other: Stai per bloccare %{count} domini da %{filename}. + following_html: + one: Stai per seguire %{count} account da %{filename}. + other: Stai per seguire %{count} account da %{filename}. + lists_html: + one: Stai per aggiungere %{count} account da %{filename} alle tue liste. Saranno create nuove liste, se non ce ne sono altre da aggiungere. + other: Stai per aggiungere %{count} account da %{filename} alle tue liste. Saranno create nuove liste, se non ce ne sono altre da aggiungere. + muting_html: + one: Stai per silenziare %{count} account da %{filename}. + other: Stai per silenziare %{count} account da %{filename}. preface: Puoi importare alcune informazioni, come le persone che segui o hai bloccato su questo server, da file creati da un'esportazione su un altro server. recent_imports: Importazioni recenti states: diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 41f93397da..54b7fb5412 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -1141,6 +1141,9 @@ ja: view_strikes: 過去のストライクを表示 too_fast: フォームの送信が速すぎます。もう一度やり直してください。 use_security_key: セキュリティキーを使用 + author_attribution: + example_title: サンプルテキスト + s_blog: "%{name} のブログ" challenge: confirm: 続ける hint_html: 以後1時間はパスワードの再入力を求めません @@ -1330,20 +1333,6 @@ ja: merge_long: 現在のレコードを保持したまま新しいものを追加します overwrite: 上書き overwrite_long: 現在のレコードを新しいもので置き換えます - overwrite_preambles: - blocking_html: "%{filename}%{total_items}個のアカウントブロックしたアカウントリストを置き換えます。" - bookmarks_html: "%{filename}%{total_items}件の投稿ブックマークの一覧を置き換えます。" - domain_blocking_html: "%{filename}%{total_items}個のドメイン非表示にしたドメインリストを置き換えます。" - following_html: "%{filename}%{total_items}個のアカウントフォローします。また、この中に含まれていないアカウントのフォローを解除します。" - lists_html: "作成済みのリスト%{filename}の内容で置き換えます%{total_items}個のアカウントが新しいリストに追加されます。" - muting_html: "%{filename}%{total_items}個のアカウントミュートしたアカウントリストを置き換えます。" - preambles: - blocking_html: "%{filename}%{total_items}個のアカウントブロックします。" - bookmarks_html: "%{filename}%{total_items}件の投稿ブックマークに追加します。" - domain_blocking_html: "%{filename}%{total_items}個のドメイン非表示にします。" - following_html: "%{filename}%{total_items}個のアカウントフォローします。" - lists_html: "%{filename}%{total_items}個のアカウントリストに追加します。追加先のリストがない場合は新しく作成されます。" - muting_html: "%{filename}%{total_items}個のアカウントミュートします。" preface: 他のサーバーでエクスポートされたファイルから、フォロー/ブロックした情報をこのサーバー上のアカウントにインポートできます。 recent_imports: 最近のインポート states: @@ -1659,6 +1648,7 @@ ja: delete: アカウントの削除 development: 開発 edit_profile: プロフィールを編集 + export: エクスポート featured_tags: 注目のハッシュタグ import: データのインポート import_and_export: インポート・エクスポート @@ -1903,6 +1893,7 @@ ja: instructions_html: 以下のコードをコピーしてwebサイトのHTMLに貼り付けます。次に「プロフィールを編集」タブから、「プロフィール補足情報」のいずれかの欄にwebサイトのURLを記入し、「変更を保存」をクリックしてください。 verification: 認証 verified_links: 確認済みリンク + website_verification: ウェブサイトの認証 webauthn_credentials: add: セキュリティキーを追加 create: diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 3f6c4b39b8..d20d67e4c3 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -1343,19 +1343,31 @@ ko: overwrite: 덮어쓰기 overwrite_long: 기존 것을 모두 지우고 새로 추가 overwrite_preambles: - blocking_html: 나의 차단 목록%{filename}에서 가져온 %{total_items} 개의 계정으로 덮어 씌우려고 합니다. - bookmarks_html: 나의 북마크%{filename}에서 가져온 %{total_items} 개의 게시물로 덮어 씌우려고 합니다. - domain_blocking_html: 나의 도메인 차단 목록%{filename}에서 가져온 %{total_items} 개의 도메인으로 덮어 씌우려고 합니다. - following_html: "%{filename}에서 가져온 %{total_items} 개의 계정팔로우하고 나머지 계정을 팔로우 해제하려고 합니다." - lists_html: 나의 리스트%{filename}에서 가져온 %{total_items} 개의 계정으로 덮어 씌우려고 합니다. - muting_html: 나의 뮤트한 계정 목록%{filename}에서 가져온 %{total_items} 개의 계정으로 덮어 씌우려고 합니다. + blocking_html: + other: 나의 차단 목록%{filename}에서 가져온 %{count} 개의 계정으로 덮어 씌우려고 합니다. + bookmarks_html: + other: 나의 북마크%{filename}에서 가져온 %{count} 개의 게시물로 덮어 씌우려고 합니다. + domain_blocking_html: + other: 나의 도메인 차단 목록%{filename}에서 가져온 %{count} 개의 도메인으로 덮어 씌우려고 합니다. + following_html: + other: "%{filename}에서 가져온 %{count} 개의 계정팔로우하고 나머지 계정을 팔로우 해제하려고 합니다." + lists_html: + other: 나의 리스트%{filename}에서 가져온 %{count} 개의 계정으로 덮어 씌우려고 합니다. + muting_html: + other: 나의 뮤트한 계정 목록%{filename}에서 가져온 %{count} 개의 계정으로 덮어 씌우려고 합니다. preambles: - blocking_html: "%{filename}에서 가져온 %{total_items}개의 계정을 차단하려고 합니다." - bookmarks_html: "%{filename}에서 가져온 %{total_items}개의 게시물을 북마크에 추가하려고 합니다." - domain_blocking_html: "%{filename}에서 가져온 %{total_items}개의 도메인을 차단하려고 합니다." - following_html: "%{filename}에서 가져온 %{total_items}개의 계정을 팔로우하려고 합니다." - lists_html: "%{filename}에서 가져온 %{total_items}개의 계정을 내 리스트에 추가하려고 합니다. 추가할 리스트가 존재하지 않으면 새로 생성될 것입니다." - muting_html: "%{filename}에서 가져온 %{total_items}개의 계정을 뮤트하려고 합니다." + blocking_html: + other: "%{filename}에서 가져온 %{count}개의 계정을 차단하려고 합니다." + bookmarks_html: + other: "%{filename}에서 가져온 %{count}개의 게시물을 북마크에 추가하려고 합니다." + domain_blocking_html: + other: "%{filename}에서 가져온 %{count}개의 도메인을 차단하려고 합니다." + following_html: + other: "%{filename}에서 가져온 %{count}개의 계정을 팔로우하려고 합니다." + lists_html: + other: "%{filename}에서 가져온 %{count}개의 계정을 내 리스트에 추가하려고 합니다. 추가할 리스트가 존재하지 않으면 새로 생성될 것입니다." + muting_html: + other: "%{filename}에서 가져온 %{count}개의 계정을 뮤트하려고 합니다." preface: 다른 서버에서 내보내기 한 파일에서 팔로우 / 차단 정보를 이 계정으로 불러올 수 있습니다. recent_imports: 최근의 가져오기 states: diff --git a/config/locales/lad.yml b/config/locales/lad.yml index 275bdab861..97fcf75180 100644 --- a/config/locales/lad.yml +++ b/config/locales/lad.yml @@ -1323,20 +1323,6 @@ lad: merge_long: Manten rejistros egzistentes i adjusta muevos overwrite: Sobreskrive overwrite_long: Mete muevos rejistros en vez de los aktuales - overwrite_preambles: - blocking_html: Estas a punto de substituyir tu lista de blokos por asta %{total_items} kuentos de %{filename}. - bookmarks_html: Estas a punto de substituyir tus markadores por asta %{total_items} publikasyones ke vinyeron de %{filename}. - domain_blocking_html: Estas a punto de substituyir tu lista de blokos de domeno por asta %{total_items} domenos de %{filename}. - following_html: Estas a punto de segir asta %{total_items} kuentos de %{filename} i deshar de segir todos los otros kuentos. - lists_html: Estas a punto de sustituyir tus listas con el kontenido de %{filename}. Asta %{total_items} kuentos seran adjustados a muevas listas. - muting_html: Estas a punto de substituyir tu lista de kuentos silensyados por asta %{total_items} kuentos de %{filename}. - preambles: - blocking_html: Estas a punto de blokar asta %{total_items} kuentos de %{filename}. - bookmarks_html: Estas a punto de adjustar asta %{total_items} publikasyones de %{filename} a tus markadores. - domain_blocking_html: Estas a punto de blokar asta %{total_items} domenos de %{filename}. - following_html: Estas a punto de segir asta %{total_items} kuentos de %{filename}. - lists_html: Estas a punto de adjustar %{total_items} kuentos dizde %{filename} a tus listas. Se kriyaran muevas listas si no ay listas para adjustarlas. - muting_html: Estas a punto de silensyar asta %{total_items} kuentos de %{filename}. preface: Puedes importar siertos datos, komo todas las personas a las kualas estas sigiendo o blokando en tu kuento en esta instansya, dizde dosyas eksportadas de otra instansya. recent_imports: Importasyones resyentes states: diff --git a/config/locales/lv.yml b/config/locales/lv.yml index 2cc8ff6a49..5f90b575e7 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -1344,20 +1344,6 @@ lv: merge_long: Saglabāt esošos ierakstus un pievienot jaunus overwrite: Pārrakstīt overwrite_long: Nomainīt pašreizējos ierakstus ar jauniem - overwrite_preambles: - blocking_html: Tu gatavojies aizstāt savu bloķēto sarakstu ar līdz pat %{total_items} kontiem no %{filename}. - bookmarks_html: Tu gatavojies aizstāt savas bloķētās izlases ar līdz pat %{total_items} ziņām no %{filename}. - domain_blocking_html: Tu gatavojies aizstāt savu bloķēto domēnu sarakstu ar līdz pat %{total_items} domēniem no %{filename}. - following_html: Tu gatavojies sekot līdz pat %{total_items} kontiem no %{filename} un pārtrauksi sekot citiem. - lists_html: Tu gatavojies aizstāt savus sarakstus ar %{filename} saturu. Līdz %{total_items} kontiem tiks pievienoti jauni saraksti. - muting_html: Tu gatavojies aizstāt savu noklusināto kontu sarakstu ar līdz pat %{total_items} kontiem no %{filename}. - preambles: - blocking_html: Tu gatavojies bloķēt līdz pat %{total_items} kontiem no %{filename}. - bookmarks_html: Tu gatavojies pievienot līdz pat %{total_items} ziņām no %{filename} savām grāmatzīmēm. - domain_blocking_html: Tu gatavojies bloķēt līdz pat %{total_items} domēniem no %{filename}. - following_html: Tu gatavojies sekot līdz pat %{total_items} kontiem no %{filename}. - lists_html: Tu gatavojies pievienot līdz pat %{total_items} kontiem no %{filename} saviem sarakstiem. Jauni saraksti tiks izveidoti, ja nav saraksta, ko pievienot. - muting_html: Tu gatavojies noklusināt līdz pat %{total_items} kontiem no %{filename}. preface: Tu vari ievietot datus, kurus esi izguvis no cita servera, kā, piemēram, cilvēku sarakstu, kuriem Tu seko vai kurus bloķē. recent_imports: Nesen importēts states: diff --git a/config/locales/ms.yml b/config/locales/ms.yml index 9994a34bb5..90493a30b6 100644 --- a/config/locales/ms.yml +++ b/config/locales/ms.yml @@ -1223,20 +1223,6 @@ ms: merge_long: Simpan rekod sedia ada dan tambah rekod baharu overwrite: Tulis ganti overwrite_long: Gantikan rekod semasa dengan yang baharu - overwrite_preambles: - blocking_html: Anda akan menggantikan senarai blok anda dengan sehingga %{total_items} akaun daripada %{filename}. - bookmarks_html: Anda akan menggantikan penanda halaman anda dengan sehingga %{total_items} siaran daripada %{filename}. - domain_blocking_html: Anda akan menggantikan senarai blok domain anda dengan sehingga %{total_items} domain daripada %{filename}. - following_html: Anda akan mengikuti sehingga %{total_items} akaun daripada %{filename} dan berhenti mengikuti orang lain. - lists_html: Anda akan menggantikan senarai anda dengan kandungan %{filename}. Sehingga %{total_items} akaun akan ditambahkan pada senarai baharu. - muting_html: Anda akan menggantikan senarai akaun yang diredamkan dengan sehingga %{total_items} akaun daripada %{filename}. - preambles: - blocking_html: Anda akan menyekat sehingga %{total_items} akaun daripada %{filename}. - bookmarks_html: Anda akan menambah sehingga %{total_items} pos daripada %{filename} ke penanda halaman anda. - domain_blocking_html: Anda akan menyekat sehingga %{total_items} domain daripada %{filename}. - following_html: Anda akan mengikuti sehingga %{total_items} akaun daripada %{filename}. - lists_html: Anda akan menambah sehingga %{total_items} akaun daripada %{filename} ke senarai anda. Senarai baharu akan dibuat jika tiada senarai untuk ditambah. - muting_html: Anda akan membisukan sehingga %{total_items} akaun daripada %{filename}. preface: Anda boleh mengimport data yang telah anda eksport dari server lain, seperti senarai orang yang anda ikuti atau sekat. recent_imports: Import terkini states: diff --git a/config/locales/my.yml b/config/locales/my.yml index 598915fad9..6a330a16c7 100644 --- a/config/locales/my.yml +++ b/config/locales/my.yml @@ -1222,20 +1222,6 @@ my: merge_long: ရှိပြီးသားမှတ်တမ်းများ သိမ်းဆည်းပြီး အသစ်များ ထပ်ထည့်ပါ overwrite: ထပ်ရေးရန် overwrite_long: လက်ရှိမှတ်တမ်းများကို အသစ်များဖြင့် အစားထိုးပါ - overwrite_preambles: - blocking_html: သင်သည် %{filename} မှ %{total_items} အကောင့်များ အထိ သင့်ပိတ်ဆို့စာရင်းကို အစားထိုးပါတော့မည်။ - bookmarks_html: သင်သည် %{filename} မှ %{total_items} ပို့စ်များ အထိ သင့် bookmark များကို အစားထိုးပါတော့မည်။ - domain_blocking_html: သင်သည် %{filename} မှ %{total_items} ဒိုမိန်းများ ဖြင့် သင်၏ ဒိုမိန်းပိတ်ဆို့စာရင်းကို အစားထိုးပါတော့မည်။ - following_html: သင်သည် %{filename} မှ %{total_items} အကောင့်များ အထိ စောင့်ကြည့် ပြီး အခြားမည်သူ့ကိုမျှ စောင့်မကြည့်တော့ပါ ။ - lists_html: သင်သည် %{filename} ၏ အကြောင်းအရာများဖြင့် သင့်စာရင်းများကို အစားထိုး ပါတော့မည်။ %{total_items} အကောင့်များအထိ စာရင်းအသစ်များသို့ ပေါင်းထည့်ပါမည်။ - muting_html: သင်သည် %{filename} မှ %{total_items} အကောင့်များ ဖြင့် အသံပိတ်ထားသော သင့်အကောင့်များစာရင်းကို အစားထိုးပါတော့မည်။ - preambles: - blocking_html: သင်သည် %{filename} မှ %{total_items} အကောင့်များ အထိ ပိတ်ဆို့ပါတော့မည်။ - bookmarks_html: သင်သည် %{filename} မှ %{total_items} ပို့စ်များ အထိ သင့် Bookmark များ သို့ ပေါင်းထည့်တော့မည်။ - domain_blocking_html: သင်သည် %{filename} မှ %{total_items} ဒိုမိန်းများ အထိ ပိတ်ဆို့ပါတော့မည်။ - following_html: သင်သည် %{filename} မှ %{total_items} အကောင့်များ အထိ စောင့်ကြည့် ပါတော့မည်။ - lists_html: သင်သည် %{filename} မှ %{total_items} အကောင့်များ ကို သင့် စာရင်းများ သို့ ပေါင်းထည့်ပါတော့မည်။ ထည့်ရန်စာရင်းမရှိပါက စာရင်းအသစ်များကို ဖန်တီးပါမည်။ - muting_html: သင်သည် %{filename} မှ %{total_items} အကောင့်များ အထိ အသံတိတ်ပါတော့မည်။ preface: သင်စောင့်ကြည့်နေသည့်လူများစာရင်း သို့မဟုတ် ပိတ်ပင်ထားသည့်စာရင်းကဲ့သို့သော အခြားဆာဗာတစ်ခုမှ သင်ထုတ်ယူထားသည့်အချက်အလက်များကို ပြန်လည်ထည့်သွင်းနိုင်သည်။ recent_imports: လတ်တလောထည့်သွင်းမှုများ states: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 7681a04eae..52ec4c89ce 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -1366,19 +1366,43 @@ nl: overwrite: Overschrijven overwrite_long: Huidige gegevens met de nieuwe gegevens vervangen overwrite_preambles: - blocking_html: Je staat op het punt jouw lijst met geblokkeerde accounts te vervangen door %{total_items} accounts vanuit %{filename}. - bookmarks_html: Je staat op het punt jouw bladwijzers te vervangen door %{total_items} berichten vanuit %{filename}. - domain_blocking_html: Je staat op het punt jouw lijst met geblokkeerde domeinen te vervangen door %{total_items} domeinen vanuit %{filename}. - following_html: Je staat op het punt om %{total_items} accounts te volgen vanuit %{filename} en te stoppen met het volgen van alle andere accounts. - lists_html: Je staat op het punt je lijsten te vervangen door inhoud van %{filename}. Er worden totaal %{total_items} accounts aan nieuwe lijsten toegevoegd. - muting_html: Je staat op het punt jouw lijst met genegeerde accounts te vervangen door %{total_items} accounts vanuit %{filename}. + blocking_html: + one: Je staat op het punt om vanuit %{filename} je blokkeerlijst te vervangen met in het totaal %{count} account. + other: Je staat op het punt om vanuit %{filename} je blokkeerlijst te vervangen met in het totaal %{count} accounts. + bookmarks_html: + one: Je staat op het punt om vanuit %{filename} je bladwijzers te vervangen met in het totaal %{count} bericht. + other: Je staat op het punt om vanuit %{filename} je bladwijzers te vervangen met in het totaal %{count} berichten. + domain_blocking_html: + one: Je staat op het punt om vanuit %{filename} je lijst met geblokkeerde domeinen te vervangen met in het totaal %{count} domein. + other: Je staat op het punt om vanuit %{filename} je lijst met geblokkeerde domeinen te vervangen met in het totaal %{count} domeinen. + following_html: + one: Je staat op het punt om vanuit %{filename} in het totaal %{count} account te volgen en de rest te ontvolgen. + other: Je staat op het punt om vanuit %{filename} in het totaal %{count} accounts te volgen en de rest te ontvolgen. + lists_html: + one: Je staat op het punt om met de inhoud van %{filename} je lijsten te vervangen. In het totaal wordt %{count} account aan de nieuwe lijst(en) toegevoegd. + other: Je staat op het punt om met de inhoud van %{filename} je lijsten te vervangen. In het totaal worden %{count} accounts aan de nieuwe lijst(en) toegevoegd. + muting_html: + one: Je staat op het punt om vanuit %{filename} je negeerlijst te vervangen met in het totaal %{count} account. + other: Je staat op het punt om vanuit %{filename} je blokkeerlijst te vervangen met in het totaal %{count} accounts. preambles: - blocking_html: Je staat op het punt om %{total_items} accounts te blokkeren vanuit %{filename}. - bookmarks_html: Je staat op het punt om %{total_items} berichten aan je bladwijzers toe te voegen vanuit %{filename}. - domain_blocking_html: Je staat op het punt om %{total_items} accounts te negeren vanuit %{filename}. - following_html: Je staat op het punt om %{total_items} accounts te volgen vanuit %{filename}. - lists_html: Je staat op het punt om tot %{total_items} accounts van %{filename} toe te voegen aan je lijsten. Nieuwe lijsten worden aangemaakt als er geen lijst is om aan toe te voegen. - muting_html: Je staat op het punt om %{total_items} accounts te negeren vanuit %{filename}. + blocking_html: + one: Je staat op het punt om vanuit %{filename} in het totaal %{count} account te blokkeren. + other: Je staat op het punt om vanuit %{filename} in het totaal %{count} accounts te blokkeren. + bookmarks_html: + one: Je staat op het punt om vanuit %{filename} in het totaal %{count} bericht aan je bladwijzers toe te voegen. + other: Je staat op het punt om vanuit %{filename} in het totaal %{count} berichten aan je bladwijzers toe te voegen. + domain_blocking_html: + one: Je staat op het punt om vanuit %{filename} in het totaal %{count} domein te blokkeren. + other: Je staat op het punt om vanuit %{filename} in het totaal %{count} domeinen te blokkeren. + following_html: + one: Je staat op het punt om vanuit %{filename} in het totaal %{count} account te volgen. + other: Je staat op het punt om vanuit %{filename} in het totaal %{count} accounts te volgen. + lists_html: + one: Je staat op het punt om vanuit %{filename} in het totaal %{count} account aan je lijsten toe te voegen. Er wordt een nieuwe lijst aangemaakt wanneer er geen lijst is om het aan toe te voegen. + other: Je staat op het punt om vanuit %{filename} in het totaal %{count} accounts aan je lijsten toe te voegen. Er worden nieuwe lijsten aangemaakt wanneer er geen lijsten zijn om ze aan toe te voegen. + muting_html: + one: Je staat op het punt om vanuit %{filename} in het totaal %{count} account te negeren. + other: Je staat op het punt om vanuit %{filename} in het totaal %{count} accounts te negeren. preface: Je kunt bepaalde gegevens, zoals de mensen die jij volgt of hebt geblokkeerd, naar jouw account op deze server importeren. Je moet deze gegevens wel eerst op de oorspronkelijke server exporteren. recent_imports: Recent geïmporteerd states: @@ -1526,8 +1550,8 @@ nl: title: Nieuw volgverzoek mention: action: Reageren - body: 'Jij bent door %{name} vermeld in:' - subject: Jij bent vermeld door %{name} + body: 'Je bent door %{name} vermeld in:' + subject: Je bent vermeld door %{name} title: Nieuwe vermelding poll: subject: Een peiling van %{name} is beëindigd diff --git a/config/locales/nn.yml b/config/locales/nn.yml index ca5e34ee55..ec3db6520f 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -1366,19 +1366,9 @@ nn: overwrite: Skriv over overwrite_long: Byt ut dei noverande oppføringane med dei nye overwrite_preambles: - blocking_html: Du skal til å byta ut blokkeringslista di med opp til %{total_items} brukarkontoar frå %{filename}. - bookmarks_html: Du skal til å byta ut bokmerka dine med opp til %{total_items} innlegg frå %{filename}. - domain_blocking_html: Du skal til å byta ut domeneblokkeringslista di med opp til %{total_items} domene frå %{filename}. - following_html: Du skal til å fylgja opp til %{total_items} brukarkontoar frå %{filename} og slutta å fylgja alle andre. - lists_html: Du er i ferd med å erstatta listene dine med innhaldet i %{filename}. Opptil %{total_items} kontoar vil bli lagt til i nye lister. - muting_html: Du skal til å byta ut lista di over dempa brukarkontoar med opp til %{total_items} brukarkontoar frå %{filename}. - preambles: - blocking_html: Du skal til å blokkera opp til %{total_items} brukarkontoar frå %{filename}. - bookmarks_html: Du skal til å leggja til opp til %{total_items} innlegg frå %{filename} til bokmerka dine. - domain_blocking_html: Du skal til å blokkera opp til %{total_items} domene frå %{filename}. - following_html: Du skal til å fylgja opp til %{total_items} brukarkontoar frå %{filename}. - lists_html: Du er i ferd med å leggja til opptil %{total_items} kontoar frå %{filename} til i listene dine. Nye lister vil blir oppretta om ingen lister finst frå før. - muting_html: Du skal til å dempa opp til %{total_items} brukarkontoar frå %{filename}. + blocking_html: + one: Du skal til å byta ut blokkeringslista di med opp til %{count} brukarkonto frå %{filename}. + other: Du skal til å byta ut blokkeringslista di med opp til %{count} brukarkontoar frå %{filename}. preface: Du kan henta inn data som du har eksportert frå ein annan tenar, som t.d. ei liste over folka du fylgjer eller blokkerer. recent_imports: Siste importar states: diff --git a/config/locales/no.yml b/config/locales/no.yml index ec0b14d5a3..94986f4cae 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -1268,20 +1268,6 @@ merge_long: Behold eksisterende og legg til nye overwrite: Overskriv overwrite_long: Erstatt gjeldende med de nye - overwrite_preambles: - blocking_html: Du er i ferd med å erstatte din blokkeringsliste med inntil %{total_items} kontoer fra %{filename}. - bookmarks_html: Du er i ferd med å erstatte dine bokmerker med inntil %{total_items} innlegg fra %{filename}. - domain_blocking_html: Du er i ferd med å erstatte din domene-blokkeringsliste med inntil %{total_items} domener fra %{filename}. - following_html: Du er i ferd med å følge inntil %{total_items} kontoer fra %{filename} og slutte å følge alle andre. - lists_html: Du er i ferd med å erstatte dine lister med innholdet i %{filename}. Inntil %{total_items} kontoer legges til i nye lister. - muting_html: Du er i ferd med å erstatte listen over dempede kontoer med inntil %{total_items} kontoer fra %{filename}. - preambles: - blocking_html: Du er i ferd med å blokkere inntil %{total_items} kontoer fra %{filename}. - bookmarks_html: Du er i ferd med å legge til inntil %{total_items} innlegg fra %{filename} til dine bokmerker. - domain_blocking_html: Du er i ferd med å blokkere inntil %{total_items} domener fra %{filename}. - following_html: Du er i ferd med å følge inntil %{total_items} kontoer fra %{filename}. - lists_html: Du er i ferd med å legge inntil %{total_items} kontoer fra %{filename} til dine lister. Nye lister vil bli opprettet hvis det ikke finnes noen liste å legge til. - muting_html: Du er i ferd med å dempe inntil %{total_items} kontoer fra %{filename}. preface: Du kan importere data om brukere du følger eller blokkerer til kontoen din på denne instansen med eksportfiler fra andre instanser. recent_imports: Siste importer states: diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 3aaf7a5a57..aaf8a9e722 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -1415,20 +1415,6 @@ pl: merge_long: Zachowaj obecne wpisy i dodaj nowe overwrite: Nadpisz overwrite_long: Zastąp obecne wpisy nowymi - overwrite_preambles: - blocking_html: Zamierzasz zastąpić swoją listę bloków maksymalnie %{total_items} kont z %{filename}. - bookmarks_html: Zamierzasz zastąpić swoje zakładki maksymalnie %{total_items} wpisami z %{filename}. - domain_blocking_html: Zamierzasz zastąpić swoją listę bloków domen maksymalnie %{total_items} domenami z %{filename}. - following_html: Zamierzasz zaobserwować maksymalnie %{total_items} kont z %{filename} i przestać obserwować kogokolwiek innego. - lists_html: Zamierzasz zastąpić swoje listy maksymalnie %{total_items} kontami z %{filename}. - muting_html: Zamierzasz zastąpić swoją wyciszonych maksymalnie %{total_items} kontami z %{filename}. - preambles: - blocking_html: Zamierzasz zablokować maksymalnie %{total_items} kont z %{filename}. - bookmarks_html: Zamierzasz dodać maksymalnie %{total_items} wpisów do twoich zakładek z %{filename}. - domain_blocking_html: Zamierzasz zablokować maksymalnie %{total_items} domen z %{filename}. - following_html: Zamierzasz zaobserwować maksymalnie %{total_items} kont z %{filename}. - lists_html: Zamierzasz dodać maksymalnie %{total_items} kont do twoich list z %{filename}. Jeżeli nie ma list, nowe zostaną utworzone. - muting_html: Zamierzasz wyciszyć maksymalnie %{total_items} kont z %{filename}. preface: Możesz zaimportować pewne dane (np. lista kont, które obserwujesz lub blokujesz) do swojego konta na tym serwerze, korzystając z danych wyeksportowanych z innego serwera. recent_imports: Ostatnie importy states: diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 6451e7c601..427703f57e 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -1365,20 +1365,6 @@ pt-BR: merge_long: Manter os registros existentes e adicionar novos overwrite: Sobrescrever overwrite_long: Substituir os registros atuais com os novos - overwrite_preambles: - blocking_html: Você está prestes a substituir sua lista de bloqueios com até contas%{total_items} de %{filename}. - bookmarks_html: Você está prestes a substituir seus favoritos por até %{total_items} posts de %{filename}. - domain_blocking_html: Você está prestes a substituir sua lista de bloqueio de domínio com até domínios%{total_items} de %{filename}. - following_html: Você está prestes a seguir até %{total_items} contas de %{filename} e parar de seguir todos os outros. - lists_html: Você está prestes a substituir sua lista pelo conteúdo de %{filename}. Até %{total_items} contas serão adicionadas a novas listas. - muting_html: Você está prestes a substituir sua lista de contas silenciadas com até %{total_items} contas de %{filename}. - preambles: - blocking_html: Você está prestes a bloquear até %{total_items} contas de %{filename}. - bookmarks_html: Você está prestes a adicionar até %{total_items} posts de %{filename} para seus favoritos. - domain_blocking_html: Você está prestes a bloquear até %{total_items} domínios de %{filename}. - following_html: Você está prestes a seguir até %{total_items} contas de %{filename}. - lists_html: Você está prestes a adicionar até %{total_items} contas a partir de %{filename} para suas listas. Novas listas serão criadas se não houver uma para a qual adicionar. - muting_html: Você está prestes a silenciar até contas%{total_items} de %{filename}. preface: Você pode importar dados que você exportou de outro servidor, como a lista de pessoas que você segue ou bloqueou. recent_imports: Importações recentes states: diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index 6b48e8de26..68217113d2 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -1362,20 +1362,6 @@ pt-PT: merge_long: Manter os registos existentes e adicionar novos registos overwrite: Escrever por cima overwrite_long: Substituir os registos atuais pelos novos - overwrite_preambles: - blocking_html: Está prestes a substituir a sua lista de bloqueios com até %{total_items} contas de %{filename}. - bookmarks_html: Está prestes a substituir os seus marcadores com até %{total_items} publicações de %{filename}. - domain_blocking_html: Está prestes a substituir a sua lista de bloqueios de domínio com até %{total_items} domínios de %{filename}. - following_html: Está prestes a seguir até %{total_items} contas de %{filename} e parar de seguir quaisquer outras contas. - lists_html: Está prestes a substituir as suas listas pelo conteúdo de %{filename}. Até %{total_items} contas serão adicionadas a novas listas. - muting_html: Está prestes a substituir a sua lista de contas silenciadas com até %{total_items} contas de %{filename}. - preambles: - blocking_html: Está prestes a bloquear até %{total_items} contas de %{filename}. - bookmarks_html: Está prestes a adicionar até %{total_items} publicações de %{filename} aos seus marcadores. - domain_blocking_html: Está prestes a bloquear até %{total_items} domínios de %{filename}. - following_html: Está prestes a seguir até %{total_items} contas de %{filename}. - lists_html: Está prestes a adicionar até %{total_items} contas do ficheiro %{filename} para as suas listas. Novas listas serão criadas se não existir uma lista onde as adicionar. - muting_html: Está prestes a silenciar até %{total_items} contas de %{filename}. preface: Podes importar dados que tenhas exportado de outra instância, como a lista de pessoas que segues ou bloqueadas. recent_imports: Importações recentes states: diff --git a/config/locales/ru.yml b/config/locales/ru.yml index c61c7f459f..25ca703732 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -1410,20 +1410,6 @@ ru: merge_long: Сохранить имеющиеся данные и добавить новые. overwrite: Перезаписать overwrite_long: Перезаписать имеющиеся данные новыми. - overwrite_preambles: - blocking_html: Вы собираетесь заменить свой блок-лист на %{total_items} аккаунтов из %{filename}. - bookmarks_html: Вы собираетесь заменить свои закладки на %{total_items} постов из %{filename}. - domain_blocking_html: Вы собираетесь заменить ваш список блокировки доменов на %{total_items} доменов из %{filename}. - following_html: Вы собираетесь следить за %{total_items} аккаунтами из %{filename} и прекратить следить за всеми остальными. - lists_html: Вы собираетесь заменить ваши списки содержимым %{filename}. До %{total_items} аккаунты будут добавлены в новые списки. - muting_html: Вы собираетесь заменить список отключенных аккаунтов на %{total_items} аккаунтов из %{filename}. - preambles: - blocking_html: Вы собираетесь заблокировать до %{total_items} аккаунтов из %{filename}. - bookmarks_html: Вы собираетесь добавить до %{total_items} постов из %{filename} в свои закладки. - domain_blocking_html: Вы собираетесь блокировать до %{total_items} доменов от %{filename}. - following_html: Вы собираетесь следовать за %{total_items} аккаунтами из %{filename}. - lists_html: Вы собираетесь добавить до %{total_items} аккаунтов от %{filename} к вашим спискам. Новые списки будут созданы, если нет списка для добавления. - muting_html: Вы собираетесь отключить до %{total_items} аккаунтов из %{filename}. preface: Вы можете загрузить некоторые данные, например, списки людей, на которых Вы подписаны или которых блокируете, в Вашу учётную запись на этом узле из файлов, экспортированных с другого узла. recent_imports: Недавно импортированное states: diff --git a/config/locales/simple_form.fy.yml b/config/locales/simple_form.fy.yml index e7deca9460..11b56bd50d 100644 --- a/config/locales/simple_form.fy.yml +++ b/config/locales/simple_form.fy.yml @@ -3,6 +3,7 @@ fy: simple_form: hints: account: + attribution_domains_as_text: Beskermet tsjin net korrekte attribúsjes. discoverable: Jo iepenbiere berjochten kinne útljochte wurde op ferskate plakken binnen Mastodon en jo account kin oanrekommandearre wurde oan oare brûkers. display_name: Jo folsleine namme of in aardige bynamme. fields: Jo website, persoanlike foarnammewurden, leeftiid, alles wat jo mar kwyt wolle. @@ -130,6 +131,7 @@ fy: name: Jo kinne elk wurd mei in haadletter begjinne, om sa bygelyks de tekst mear lêsber te meitsjen user: chosen_languages: Allinnich berjochten yn de selektearre talen wurde op de iepenbiere tiidline toand + role: De rol bepaalt hokker rjochten in brûker hat. user_role: color: Kleur dy’t brûkt wurdt foar de rol yn de UI, as RGB yn heksadesimaal formaat highlighted: Dit makket de rol iepenbier sichtber @@ -142,6 +144,7 @@ fy: url: Wêr’t eveneminten nei ta stjoerd wurde labels: account: + attribution_domains_as_text: Allinnich bepaalde websites tastean discoverable: Profyl en bydragen yn sykalgoritmen opnimme litte fields: name: Label diff --git a/config/locales/simple_form.nl.yml b/config/locales/simple_form.nl.yml index 7f8aaa01d6..bf30cdb1bf 100644 --- a/config/locales/simple_form.nl.yml +++ b/config/locales/simple_form.nl.yml @@ -295,7 +295,7 @@ nl: favourite: Wanneer iemand jouw bericht als favoriet markeert follow: Wanneer iemand jou is gaan volgen follow_request: Wanneer iemand jou wil volgen - mention: Wanneer iemand jou heeft vermeld + mention: Je bent door iemand vermeld pending_account: Wanneer een nieuw account moet worden beoordeeld reblog: Wanneer iemand jouw bericht heeft geboost report: Nieuwe rapportage is ingediend diff --git a/config/locales/sl.yml b/config/locales/sl.yml index 286bece877..e9c06bcaa6 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -1398,20 +1398,6 @@ sl: merge_long: Ohrani obstoječe zapise in dodaj nove overwrite: Prepiši overwrite_long: Zamenjaj trenutne zapise z novimi - overwrite_preambles: - blocking_html: Svoj seznam blokiranih računov boste nadomestili z največ %{total_items} računi iz %{filename}. - bookmarks_html: Svoje zaznamke boste nadomestili z največ %{total_items} objavami iz %{filename}. - domain_blocking_html: Svoj seznam blokiranih domen boste nadomestili z največ %{total_items} domenami iz %{filename}. - following_html: "Začeli boste slediti največ %{total_items} računom iz %{filename} in prenehali slediti vsem ostalim." - lists_html: Svoje sezname boste nadomestili z vsebino datoteke %{filename}. Največ %{total_items} računov bo dodanih na nove sezname. - muting_html: Svoj seznam utišanih računov boste nadomestili z največ %{total_items} računi iz %{filename}. - preambles: - blocking_html: "Blokirali boste največ %{total_items} računov iz %{filename}." - bookmarks_html: "Med zaznamke boste dodali boste največ %{total_items} objav iz %{filename}." - domain_blocking_html: "Blokirali boste največ %{total_items} domen iz %{filename}." - following_html: "Začeli boste slediti največ %{total_items} računom iz %{filename}." - lists_html: Dodali boste največ %{total_items} računov iz %{filename} na svoje sezname. Po potrebi bodo ustvarjeni novi seznami. - muting_html: "Utišali boste največ %{total_items} računov iz %{filename}." preface: Podatke, ki ste jih izvozili iz drugega strežnika, lahko uvozite. Na primer seznam oseb, ki jih spremljate ali blokirate. recent_imports: Nedavni uvozi states: diff --git a/config/locales/sq.yml b/config/locales/sq.yml index 2f05d7860c..0b276393a6 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -1359,19 +1359,43 @@ sq: overwrite: Mbishkruaje overwrite_long: Zëvendësoji zërat ekzistues me të rinjtë overwrite_preambles: - blocking_html: Ju ndan një hap nga zëvendësimi i listës tuaj të bllokimeve me %{total_items} llogari nga %{filename}. - bookmarks_html: Ju ndan një hap nga zëvendësimi i faqerojtësve tuaj me %{total_items} postime nga %{filename}. - domain_blocking_html: Ju ndan një hap nga zëvendësimi i listës tuaj të bllokimit të përkatësive me %{total_items} përkatësi nga %{filename}. - following_html: Ju ndan një hap nga ndjekja e %{total_items} llogarive nga %{filename} dhe reshtja së ndjekuri këdo tjetër. - lists_html: Ju ndan një hap nga zëvendësimi i listave tuaja me lëndë nga %{filename}. Te listat e reja do të shtohen deri në %{total_items} llogari. - muting_html: Ju ndan një hpa nga zëvendësimi i listës suaj të llogarive të heshtuara me %{total_items} llogari nga %{filename}. + blocking_html: + one: Ju ndan një hap nga zëvendësimi i listës tuaj të bllokimeve, me %{count} llogari nga %{filename}. + other: Ju ndan një hap nga zëvendësimi i listës tuaj të bllokimeve, me %{count} llogari nga %{filename}. + bookmarks_html: + one: Ju ndan një hap nga zëvendësimi i faqerojtësve tuaj, me %{count} postim nga %{filename}. + other: Ju ndan një hap nga zëvendësimi i faqerojtësve tuaj, me %{count} postime nga %{filename}. + domain_blocking_html: + one: Ju ndan një hap nga zëvendësimi i listës tuaj të bllokimeve të përkatësive, me %{count} përkatësi nga %{filename}. + other: Ju ndan një hap nga zëvendësimi i listës tuaj të bllokimeve të përkatësive, me %{count} përkatësi nga %{filename}. + following_html: + one: Ju ndan një hap nga ndjekja e %{count} llogarie nga %{filename} dhe reshtja e ndjekjes së gjithkujt tjetër. + other: Ju ndan një hap nga ndjekja e deri %{count} llogarish nga %{filename} dhe reshtja e ndjekjes së gjithkujt tjetër. + lists_html: + one: Ju ndan një hap nga zëvendësimi i listave tuaja me lëndën e %{filename}. Te listat e reja do të shtohet deri %{count} llogari. + other: Ju ndan një hap nga zëvendësimi i listave tuaja me lëndën e %{filename}. Te listat e reja do të shtohet deri %{count} llogari. + muting_html: + one: Ju ndan një hap nga zëvendësimi i listës tuaj të llogarisë së heshtuar me %{count} llogari nga from %{filename}. + other: Ju ndan një hap nga zëvendësimi i listës tuaj të llogarive të heshtuara me %{count} llogari nga from %{filename}. preambles: - blocking_html: Ju ndan një hap nga bllokimi i %{total_items} llogarive nga %{filename}. - bookmarks_html: Ju ndan një hap nga shtimi te faqerojtësit tuaj i %{total_items} postimeve nga %{filename}. - domain_blocking_html: Ju ndan një hap nga bllokimi i %{total_items} përkatësive nga %{filename}. - following_html: Ju ndan një hap nga ndjekja e %{total_items} llogarive nga %{filename}. - lists_html: Jui nda një hap nga shtimi te listat tuaja i deri %{total_items} llogarive nga %{filename}. Nëse s’ka listë ku të shtohen, do të krijohen lista të reja. - muting_html: Ju ndan një hap nga heshtimi i %{total_items} llogarive nga %{filename}. + blocking_html: + one: Ju ndan një hap nga bllokimi i deri %{count} llogarie nga %{filename}. + other: Ju ndan një hap nga bllokimi i deri %{count} llogarive nga %{filename}. + bookmarks_html: + one: Ju ndan një hap nga shtimi te faqerojtësit tuaj i deri %{count} postimi nga %{filename}. + other: Ju ndan një hap nga shtimi te faqerojtësit tuaj i deri %{count} postimeve nga %{filename}. + domain_blocking_html: + one: Ju ndan një hap nga bllokimi i deri %{count} përkatësie nga %{filename}. + other: Ju ndan një hap nga bllokimi i deri %{count} përkatësive nga %{filename}. + following_html: + one: Ju ndan një hap nga ndjekja e deri %{count} llogarie nga %{filename}. + other: Ju ndan një hap nga ndjekja e deri %{count} llogarive nga %{filename}. + lists_html: + one: Ju ndan një hap nga shtimi i deri %{count} llogarie nga %{filename} te listat tuaja. Nëse s’ka listë ku të shtohen, do të krijohen lista të reja. + other: Ju ndan një hap nga shtimi i deri %{count} llogarive nga %{filename} te listat tuaja. Nëse s’ka listë ku të shtohen, do të krijohen lista të reja. + muting_html: + one: Ju ndan një hap nga heshtimi i deri %{count} llogarie nga %{filename}. + other: Ju ndan një hap nga heshtimi i deri %{count} llogarive nga %{filename}. preface: Mund të importoni të dhëna që keni eksportuar nga një shërbyes tjetër, bie fjala, një listë të personave që ndiqni ose bllokoni. recent_imports: Importime së fundi states: diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml index ad14d9d131..f56cdb9cb5 100644 --- a/config/locales/sr-Latn.yml +++ b/config/locales/sr-Latn.yml @@ -1302,20 +1302,6 @@ sr-Latn: merge_long: Zadržite postojeće zapise i dodajte nove overwrite: Zameni overwrite_long: Zameni trenutne zapise novima - overwrite_preambles: - blocking_html: Upravo ćete zameniti svoju listu blokiranih sa do %{total_items} naloga iz %{filename}. - bookmarks_html: Upravo ćete zameniti svoje obeleživače sa do %{total_items} objava iz %{filename}. - domain_blocking_html: Upravo ćete zameniti svoju listu blokiranih domena sa do %{total_items} domena iz %{filename}. - following_html: Upravo ćete pratiti do %{total_items} naloga iz %{filename} and i prestati sa praćenjem bilo koga drugog. - lists_html: Spremate se da zamenite svoje liste sadržajem od %{filename}. Do %{total_items} naloga će biti dodato na nove liste. - muting_html: Upravo ćete zameniti svoju listu ignorisanih naloga sa do %{total_items} naloga iz %{filename}. - preambles: - blocking_html: Upravo ćete blokirati do %{total_items} naloga iz %{filename}. - bookmarks_html: Upravo ćete dodati do %{total_items} objava iz %{filename} u vaše obeleživače. - domain_blocking_html: Upravo ćete blokirati do %{total_items} domena iz %{filename}. - following_html: Upravo ćete pratiti do %{total_items} naloga iz %{filename}. - lists_html: Spremate se da dodate do %{total_items} naloga od %{filename} na svoje liste. Nove liste će biti kreirane ako ne postoji lista za dodavanje. - muting_html: Upravo ćete ignorisati do %{total_items} naloga iz %{filename}. preface: Možete uvesti podatke koje ste izvezli sa druge instance, kao što su liste ljudi koje ste pratili ili blokirali. recent_imports: Nedavni uvozi states: diff --git a/config/locales/sr.yml b/config/locales/sr.yml index fc92b98176..45feb0b5fc 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -1332,20 +1332,6 @@ sr: merge_long: Задржите постојеће записе и додајте нове overwrite: Замени overwrite_long: Замени тренутне записе новима - overwrite_preambles: - blocking_html: Управо ћете заменити своју листу блокираних са до %{total_items} налога из %{filename}. - bookmarks_html: Управо ћете заменити своје обележиваче са до %{total_items} објава из %{filename}. - domain_blocking_html: Управо ћете заменити своју листу блокираних домена са до %{total_items} домена из %{filename}. - following_html: Управо ћете пратити до %{total_items} налога из %{filename} and и престати са праћењем било кога другог. - lists_html: Спремате се да замените своје листе садржајем од %{filename}. До %{total_items} налога ће бити додато на нове листе. - muting_html: Управо ћете заменити своју листу игнорисаних налога са до %{total_items} налога из %{filename}. - preambles: - blocking_html: Управо ћете блокирати до %{total_items} налога из %{filename}. - bookmarks_html: Управо ћете додати до %{total_items} објава из %{filename} у ваше обележиваче. - domain_blocking_html: Управо ћете блокирати до %{total_items} домена из %{filename}. - following_html: Управо ћете пратити до %{total_items} налога из %{filename}. - lists_html: Спремате се да додате до %{total_items} налога од %{filename} на своје листе. Нове листе ће бити креиране ако не постоји листа за додавање. - muting_html: Управо ћете игнорисати до %{total_items} налога из %{filename}. preface: Можете увести податке које сте извезли са друге инстанце, као што су листе људи које сте пратили или блокирали. recent_imports: Недавни увози states: diff --git a/config/locales/sv.yml b/config/locales/sv.yml index dadd5f1600..0d19d17c3b 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -1318,20 +1318,6 @@ sv: merge_long: Behåll befintliga uppgifter och lägg till nya overwrite: Skriv över overwrite_long: Ersätt de nuvarande uppgifterna med de nya - overwrite_preambles: - blocking_html: Du är på väg att ersätta din blockeringslista med upp till %{total_items} konton från %{filename}. - bookmarks_html: Du är på väg att ersätta din blockeringslista med upp till %{total_items} inlägg från %{filename}. - domain_blocking_html: Du är på väg att ersätta din blockeringslista med upp till %{total_items} domäner från %{filename}. - following_html: Du är på väg till följ upp till %{total_items} konton från %{filename} och sluta följa någon annan. - lists_html: Du är på väg att ersätta dina listor med innehållet i %{filename}. Upp till %{total_items} konton kommer att läggas till i nya listor. - muting_html: Du är på väg att ersätta din lista med tystade konton med upp till %{total_items} konton från %{filename}. - preambles: - blocking_html: Du är på väg att blockera med upp till %{total_items} konton från %{filename}. - bookmarks_html: Du håller på att lägga upp till %{total_items} inlägg från %{filename} till dina bokmärken. - domain_blocking_html: Du är på väg att blockera upp till %{total_items} domäner från %{filename}. - following_html: Du är på väg att följa upp till %{total_items} konton från %{filename}. - lists_html: Du håller på att lägga upp till %{total_items} konton från %{filename} till dina listor. Nya listor kommer att skapas om det inte finns någon lista att lägga till. - muting_html: Du är på väg att tysta upp till %{total_items} konton från %{filename}. preface: Du kan importera data som du exporterat från en annan instans, till exempel en lista över personer du följer eller blockerar. recent_imports: Nyligen importerade states: diff --git a/config/locales/th.yml b/config/locales/th.yml index 3cb802afe3..c6ba60736d 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -1340,20 +1340,6 @@ th: merge_long: เก็บระเบียนที่มีอยู่และเพิ่มระเบียนใหม่ overwrite: เขียนทับ overwrite_long: แทนที่ระเบียนปัจจุบันด้วยระเบียนใหม่ - overwrite_preambles: - blocking_html: คุณกำลังจะ แทนที่รายการการปิดกั้นของคุณ ด้วยมากถึง %{total_items} บัญชี จาก %{filename} - bookmarks_html: คุณกำลังจะ แทนที่ที่คั่นหน้าของคุณ ด้วยมากถึง %{total_items} โพสต์ จาก %{filename} - domain_blocking_html: คุณกำลังจะ แทนที่รายการการปิดกั้นโดเมนของคุณ ด้วยมากถึง %{total_items} โดเมน จาก %{filename} - following_html: คุณกำลังจะ ติดตาม มากถึง %{total_items} บัญชี จาก %{filename} และ หยุดการติดตามคนอื่นใด - lists_html: คุณกำลังจะ แทนที่รายการของคุณ ด้วยเนื้อหาของ %{filename} จะเพิ่มมากถึง %{total_items} บัญชี ไปยังรายการใหม่ - muting_html: คุณกำลังจะ แทนที่รายการบัญชีที่ซ่อนอยู่ของคุณ ด้วยมากถึง %{total_items} บัญชี จาก %{filename} - preambles: - blocking_html: คุณกำลังจะ ปิดกั้น มากถึง %{total_items} บัญชี จาก %{filename} - bookmarks_html: คุณกำลังจะเพิ่มมากถึง %{total_items} โพสต์ จาก %{filename} ไปยัง ที่คั่นหน้า ของคุณ - domain_blocking_html: คุณกำลังจะ ปิดกั้น มากถึง %{total_items} โดเมน จาก %{filename} - following_html: คุณกำลังจะ ติดตาม มากถึง %{total_items} บัญชี จาก %{filename} - lists_html: คุณกำลังจะเพิ่มมากถึง %{total_items} บัญชี จาก %{filename} ไปยัง รายการ ของคุณ จะสร้างรายการใหม่หากไม่มีรายการที่จะเพิ่มไปยัง - muting_html: คุณกำลังจะ ซ่อน มากถึง %{total_items} บัญชี จาก %{filename} preface: คุณสามารถนำเข้าข้อมูลที่คุณได้ส่งออกจากเซิร์ฟเวอร์อื่น เช่น รายการผู้คนที่คุณกำลังติดตามหรือกำลังปิดกั้น recent_imports: การนำเข้าล่าสุด states: diff --git a/config/locales/tr.yml b/config/locales/tr.yml index f1e0983705..df55aa5a29 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -1366,19 +1366,43 @@ tr: overwrite: Üzerine yaz overwrite_long: Mevcut kayıtları yenileriyle değiştir overwrite_preambles: - blocking_html: "Engel listenizi, %{filename} dosyasından, %{total_items} hesapla değiştirmek üzeresiniz." - bookmarks_html: "Yerimlerinizi, %{filename} dosyasından, %{total_items} gönderiyle değiştirmek üzeresiniz." - domain_blocking_html: "Alan adı engel listenizi, %{filename} dosyasından, %{total_items} alan adıyla değiştirmek üzeresiniz." - following_html: "%{filename} dosyasından %{total_items} hesabı takip etmeye başlamak ve diğer herkesi takipten çıkmak üzeresiniz." - lists_html: Listelerinizi %{filename} içeriğiyle değiştirmek üzeresiniz. Yeni listelere en fazla %{total_items} hesap eklenecek. - muting_html: "Sessize alınmış hesaplar listenizi, %{filename} dosyasından, %{total_items} hesapla değiştirmek üzeresiniz." + blocking_html: + one: "Engelleme listenizi, %{filename} dosyasından %{count} hesap ile değiştirmek üzeresiniz." + other: "Engelleme listenizi, %{filename} dosyasından %{count} hesap ile değiştirmek üzeresiniz." + bookmarks_html: + one: "Yerimlerinizi, %{filename} dosyasından %{count} gönderi ile değiştirmek üzeresiniz." + other: "Yerimlerinizi, %{filename} dosyasından %{count} gönderi ile değiştirmek üzeresiniz." + domain_blocking_html: + one: "Alan adı engelleme listenizi, %{filename} dosyasından %{count} alan adı ile değiştirmek üzeresiniz." + other: "Alan adı engelleme listenizi, %{filename} dosyasından %{count} alan adı ile değiştirmek üzeresiniz." + following_html: + one: "%{filename} dosyasından %{count} hesabı takip etmek ve diğer herkesin takibini bırakmak üzeresiniz." + other: "%{filename} dosyasından %{count} hesabı takip etmek ve diğer herkesin takibini bırakmak üzeresiniz." + lists_html: + one: "Listelerinizi, %{filename} dosya içeriğiyle değiştirmek üzeresiniz. %{count} hesap yeni listelere eklenecektir." + other: "Listelerinizi, %{filename} dosya içeriğiyle değiştirmek üzeresiniz. %{count} hesap yeni listelere eklenecektir." + muting_html: + one: "Sessize alınmış hesap listenizi, %{filename} dosyasından %{count} hesap ile değiştirmek üzeresiniz." + other: "Sessize alınmış hesap listenizi, %{filename} dosyasından %{count} hesap ile değiştirmek üzeresiniz." preambles: - blocking_html: "%{filename} dosyasından %{total_items} hesabı engellemek üzeresiniz." - bookmarks_html: "%{filename} dosyasından %{total_items} gönderiyi yerimlerinize eklemek üzeresiniz." - domain_blocking_html: "%{filename} dosyasından %{total_items} alan adını engellemek üzeresiniz." - following_html: "%{filename} dosyasından %{total_items} hesabı takip etmek üzeresiniz." - lists_html: "Listelerinize %{filename} dosyasından en fazla %{total_items} hesap eklemek üzeresiniz. Eklenecek bir liste olmaması durumunda yeni listeler oluşturulacaktır." - muting_html: "%{filename} dosyasından %{total_items} hesabı sessize almak üzeresiniz." + blocking_html: + one: "%{filename} dosyasından %{count} hesap engellemek üzeresiniz." + other: "%{filename} dosyasından %{count} hesap engellemek üzeresiniz." + bookmarks_html: + one: "Yerimlerinize, %{filename} dosyasından %{count} gönderi eklemek üzeresiniz." + other: "Yerimlerinize, %{filename} dosyasından %{count} gönderi eklemek üzeresiniz." + domain_blocking_html: + one: "%{filename} dosyasından %{count} alan adı engellemek üzeresiniz." + other: "%{filename} dosyasından %{count} alan adı engellemek üzeresiniz." + following_html: + one: "%{filename} dosyasından %{count} hesap takip etmek üzeresiniz." + other: "%{filename} dosyasından %{count} hesap takip etmek üzeresiniz." + lists_html: + one: "Listelerinize, %{filename} %{count} hesap eklemek üzeresiniz. Eklenecek liste yoksa yeni listeler oluşturulacaktır." + other: "Listelerinize, %{filename} %{count} hesap eklemek üzeresiniz. Eklenecek liste yoksa yeni listeler oluşturulacaktır." + muting_html: + one: "%{filename} dosyasından %{count} hesabı sessize almak üzeresiniz." + other: "%{filename} dosyasından %{count} hesabı sessize almak üzeresiniz." preface: Diğer sunucudan alarak oluşturduğunuz dosyalar sayesinde, bu sunucudaki hesabınıza takipçilerinizi aktarabilir veya istemediğiniz kişileri otomatik olarak engelleyebilirsiniz. recent_imports: Son içe aktarmalar states: diff --git a/config/locales/uk.yml b/config/locales/uk.yml index de1847a745..47732198f1 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -1415,20 +1415,6 @@ uk: merge_long: Зберегти наявні записи та додати нові overwrite: Перезаписувати overwrite_long: Замінити наявні записи новими - overwrite_preambles: - blocking_html: Ви збираєтеся замінити ваш список блокування з %{total_items} обліковими записами з %{filename}. - bookmarks_html: Ви збираєтеся замінити ваші закладки з %{total_items} дописами з %{filename}. - domain_blocking_html: Ви збираєтеся замінити ваш список блокування доменів з %{total_items} доменами з %{filename}. - following_html: Ви збираєтеся слідкувати за %{total_items} обліковими записами з %{filename} і перестати слідкувати за всіма іншими. - lists_html: Ви збираєтеся замінити ваші списки вмістом з %{filename}. До нових списків буде додано до %{total_items} облікових записів. - muting_html: Ви збираєтеся замінити ваш список ігнорованих облікових записів з %{total_items} обліковими записами з %{filename}. - preambles: - blocking_html: Ви збираєтеся заблокувати %{total_items} облікових записів з %{filename}. - bookmarks_html: Ви збираєтеся додати %{total_items} дописів з %{filename} до ваших закладок. - domain_blocking_html: Ви збираєтеся заблокувати %{total_items} доменів з %{filename}. - following_html: Ви збираєтеся слідкувати за %{total_items} обліковими записами з %{filename}. - lists_html: Ви збираєтеся додати до %{total_items} облікових записів з %{filename} до ваших списків. Нові списки будуть створені, якщо немає списку для додавання. - muting_html: Ви збираєтеся ігнорувати %{total_items} облікових записів з %{filename}. preface: Ви можете імпортувати дані, які ви експортували з іншого сервера, наприклад, список людей, яких ви відстежуєте або блокуєте. recent_imports: Останні імпорти states: diff --git a/config/locales/vi.yml b/config/locales/vi.yml index 7e44e76e44..17edfba70a 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -1341,19 +1341,31 @@ vi: overwrite: Ghi đè overwrite_long: Thay thế các bản ghi hiện tại bằng các bản ghi mới overwrite_preambles: - blocking_html: Bạn sắp thay thế danh sách chặn với %{total_items} tài khoản từ %{filename}. - bookmarks_html: Bạn sắp thay thế lượt lưu với %{total_items} tút từ %{filename}. - domain_blocking_html: Bạn sắp thay thế danh sách máy chủ chặn với %{total_items} máy chủ từ %{filename}. - following_html: Bạn sắp theo dõi với %{total_items} người từ %{filename}ngừng theo dõi bất kỳ ai. - lists_html: Bạn sắp thay thế các danh sách bằng nội dung từ %{filename}. Hơn %{total_items} tài khoản sẽ được thêm vào những danh sách mới. - muting_html: Bạn sắp thay thế danh sách ẩn với %{total_items} người từ %{filename}. + blocking_html: + other: Bạn sắp thay thế danh sách chặn với %{count} người từ %{filename}. + bookmarks_html: + other: Bạn sắp thay thế danh sách tút đã lưu với %{count} tút từ %{filename}. + domain_blocking_html: + other: Bạn sắp thay thế danh sách máy chủ chặn với %{count} máy chủ từ %{filename}. + following_html: + other: Bạn sắp theo dõi tới %{count} người từ %{filename}ngừng theo dõi mọi người khác. + lists_html: + other: Bạn sắp thay thế danh sách với nội dung của %{filename}. Có %{count} người sẽ được thêm vào những danh sách mới. + muting_html: + other: Bạn sắp they thế danh sách người bạn chặn với %{count} người từ %{filename}. preambles: - blocking_html: Bạn sắp chặn tới %{total_items} người từ %{filename}. - bookmarks_html: Bạn sắp thêm vào %{total_items} tút từ %{filename} vào lượt lưu. - domain_blocking_html: Bạn sắp chặn tới %{total_items} máy chủ từ %{filename}. - following_html: Bạn sắp theo dõi tới %{total_items} người từ %{filename}. - lists_html: Bạn sắp thêm %{total_items} tài khoản từ %{filename} vào danh sách của bạn. Những danh sách mới sẽ được tạo nếu bạn chưa có danh sách nào. - muting_html: Bạn sắp ẩn lên tới %{total_items} người từ %{filename}. + blocking_html: + other: Bạn sắp chặn tới %{count} người từ %{filename}. + bookmarks_html: + other: Bạn sắp thêm tới %{count} tút từ %{filename} vào danh sách tút đã lưu. + domain_blocking_html: + other: Bạn sắp chặn tới %{count} máy chủ từ %{filename}. + following_html: + other: Bạn sắp theo dõi tới %{count} người từ %{filename}. + lists_html: + other: Bạn sắp thêm tới %{count} người từ %{filename} vào danh sách của bạn. Những danh sách mới sẽ được tạo nếu không có danh sách để thêm. + muting_html: + other: Bạn sắp ẩn tới %{count} người từ %{filename}. preface: Bạn có thể nhập dữ liệu mà bạn đã xuất từ một máy chủ khác, chẳng hạn danh sách những người đang theo dõi hoặc chặn. recent_imports: Đã nhập gần đây states: diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index a73871115b..7be8fb5a58 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -1341,19 +1341,31 @@ zh-CN: overwrite: 覆盖 overwrite_long: 将当前记录替换为新记录 overwrite_preambles: - blocking_html: 你即将使用来自 %{filename} 的最多 %{total_items} 个账户替换你的屏蔽列表。 - bookmarks_html: 你即将使用来自 %{filename} %{total_items} 篇嘟文替换你的书签。 - domain_blocking_html: 你即将使用来自 %{filename} 的最多 %{total_items} 个域名替换你的域名屏蔽列表。 - following_html: 你即将从 %{filename} 关注 %{total_items} 个账户,并停止关注其他任何人。 - lists_html: 你即将用 %{filename} 的内容替换你的列表。新列表中将添加 %{total_items} 个账户。 - muting_html: 你即将使用来自 %{filename} 的最多 %{total_items} 个账户替换你已隐藏的账户列表。 + blocking_html: + other: 你即将使用来自 %{filename} 的最多 %{count} 个帐户替换你的屏蔽列表。 + bookmarks_html: + other: 你即将使用来自 %{filename} 的最多 %{count} 条嘟文替换你的书签。 + domain_blocking_html: + other: 你即将使用来自 %{filename} 的最多 %{count} 个域名替换你的域名屏蔽列表。 + following_html: + other: 你即将关注来自 %{filename} 的最多 %{count} 个账户,并停止关注其他所有人。 + lists_html: + other: 你即将使用来自 %{filename} 的内容替换你的列表。最多将会有 %{count} 个账户 被添加到新列表。 + muting_html: + other: 你即将使用来自 %{filename} 的最多 %{count} 个帐户替换你的已隐藏账户列表。 preambles: - blocking_html: 你即将从 %{filename} 封锁多达 %{total_items} 个账户。 - bookmarks_html: 你即将把来自 %{filename} %{total_items} 篇嘟文添加到你的书签中。 - domain_blocking_html: 你即将从 %{filename} 屏蔽 %{total_items} 个域名。 - following_html: 你即将从 %{filename} 关注最多 %{total_items} 个账户。 - lists_html: 你即将从 %{filename} 中添加最多 %{total_items} 个账户到你的列表中。如果没有可用列表,将创建新的列表。 - muting_html: 你即将从 %{filename} 隐藏 %{total_items} 个账户。 + blocking_html: + other: 你即将屏蔽来自 %{filename} 的最多 %{count} 个账号。 + bookmarks_html: + other: 你即将把来自 %{filename} %{count} 篇嘟文添加到你的书签中。 + domain_blocking_html: + other: 你即将屏蔽来自 %{filename} 的最多 %{count} 个域名。 + following_html: + other: 你即将关注来自 %{filename} 的最多 %{count} 个账号。 + lists_html: + other: 你即将从 %{filename} 中添加最多 %{count} 个账户到你的列表中。如果没有可用列表,将创建新的列表。 + muting_html: + other: 你即将隐藏来自 %{filename} 的最多 %{count} 个账号。 preface: 你可以在此导入你在其他实例导出的数据,比如你所关注或屏蔽的用户列表。 recent_imports: 最近导入 states: diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml index c0726fc2f7..e33ebeadb4 100644 --- a/config/locales/zh-HK.yml +++ b/config/locales/zh-HK.yml @@ -1249,20 +1249,6 @@ zh-HK: merge_long: 留下舊有記錄並添加新的資訊 overwrite: 覆蓋 overwrite_long: 用新記錄覆蓋當前記錄 - overwrite_preambles: - blocking_html: 你將以%{filename}的最多%{total_items}個帳號,來取代你現有的封鎖列表。 - bookmarks_html: 你將以%{filename}的最多%{total_items}個帳號,來取代你現有的書籤。 - domain_blocking_html: 你將以%{filename}的最多%{total_items} 個帳號,來取代你現有的網域封鎖列表。 - following_html: 你將從%{filename}追蹤最多%{total_items} 個帳號,並取消追蹤其他人。 - lists_html: 你將根據%{filename}的內容取代的你列表。最多新增 %{total_items} 個帳號 到新列表。 - muting_html: 你將根據%{filename}中最多 %{total_items} 個帳號取代你的靜音帳號列表。 - preambles: - blocking_html: 你將根據%{filename}封鎖最多 %{total_items} 個帳號。 - bookmarks_html: 你將加入 %{filename} 中最多 %{total_items} 篇帖文到你的書籤中。 - domain_blocking_html: 你將封鎖來自%{filename}的最多 %{total_items} 個網域。 - following_html: 你將追蹤 來自 %{filename} 最多 %{total_items} 個帳號。 - lists_html: 你將加入來自%{filename}最多 %{total_items} 個帳號到你的列表中。如果現時沒有列表,將會建立新列表。 - muting_html: 你將靜音來自%{filename}的最多 %{total_items} 個帳號。 preface: 你可以在此匯入你在其他服務站所匯出的資料檔,包括︰你所關注的用戶,被你封鎖的用戶。 recent_imports: 最近的匯入 states: diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 4079f68a50..96aedf0a1c 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -1343,19 +1343,31 @@ zh-TW: overwrite: 覆蓋 overwrite_long: 以新的紀錄覆蓋目前紀錄 overwrite_preambles: - blocking_html: 您將要自 %{filename} 中之 %{total_items} 個帳號取代您的封鎖帳號列表。 - bookmarks_html: 您將要自 %{filename} 中之 %{total_items} 個嘟文取代您的書籤。 - domain_blocking_html: 您將要自 %{filename} 中之 %{total_items} 個網域取代您的封鎖網域列表。 - following_html: 您將要 跟隨%{filename} 中之 %{total_items} 個帳號 並且 取消跟隨其他所有人。 - lists_html: 您將以 %{filename} 之內容取代您的列表。這將會新增 %{total_items} 個帳號至新列表。 - muting_html: 您將要自 %{filename} 中之 %{total_items} 個帳號取代您的靜音帳號列表。 + blocking_html: + other: 您將要自 %{filename} 中之 %{count} 個帳號取代您的封鎖帳號列表。 + bookmarks_html: + other: 您將要自 %{filename} 中之 %{count} 個嘟文取代您的書籤。 + domain_blocking_html: + other: 您將要自 %{filename} 中之 %{count} 個網域取代您的封鎖網域列表。 + following_html: + other: 您將要 跟隨%{filename} 中之 %{count} 個帳號 並且 取消跟隨其他所有人。 + lists_html: + other: 您將以 %{filename} 之內容取代您的列表。這將會新增 %{count} 個帳號至新列表。 + muting_html: + other: 您將要自 %{filename} 中之 %{count} 個帳號取代您的靜音帳號列表。 preambles: - blocking_html: 您將要 封鎖%{filename} 中之 %{total_items} 個帳號。 - bookmarks_html: 您將要自 %{filename} 中之 %{total_items} 個嘟文加入至您的書籤。 - domain_blocking_html: 您將要 封鎖%{filename} 中之 %{total_items} 個網域。 - following_html: 您將要 跟隨%{filename} 中之 %{total_items} 個帳號。 - lists_html: 您將自 %{filename} 新增 %{total_items} 個帳號至您的列表。若不存在列表用以新增帳號,則會建立新列表。 - muting_html: 您將要 靜音%{filename} 中之 %{total_items} 個帳號。 + blocking_html: + other: 您將要 封鎖%{filename} 中之 %{count} 個帳號。 + bookmarks_html: + other: 您將要自 %{filename} 中之 %{count} 個嘟文加入至您的書籤。 + domain_blocking_html: + other: 您將要 封鎖%{filename} 中之 %{count} 個網域。 + following_html: + other: 您將要 跟隨%{filename} 中之 %{count} 個帳號。 + lists_html: + other: 您將自 %{filename} 新增 %{count} 個帳號至您的列表。若不存在列表用以新增帳號,則會建立新列表。 + muting_html: + other: 您將要 靜音%{filename} 中之 %{count} 個帳號。 preface: 您能於此匯入您於其他伺服器所匯出的資料檔,包括跟隨中的使用者、封鎖的使用者名單等。 recent_imports: 最近匯入的 states: From 0ce2db4f7d3dad317803a41d33409dd83165bfc6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 09:07:07 +0200 Subject: [PATCH 095/150] Update dependency postcss-preset-env to v10.0.6 (#32260) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9aeb2b02a8..35fca2f8ad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13417,9 +13417,9 @@ __metadata: languageName: node linkType: hard -"postcss-custom-media@npm:^11.0.1": - version: 11.0.1 - resolution: "postcss-custom-media@npm:11.0.1" +"postcss-custom-media@npm:^11.0.2": + version: 11.0.2 + resolution: "postcss-custom-media@npm:11.0.2" dependencies: "@csstools/cascade-layer-name-parser": "npm:^2.0.1" "@csstools/css-parser-algorithms": "npm:^3.0.1" @@ -13427,7 +13427,7 @@ __metadata: "@csstools/media-query-list-parser": "npm:^3.0.1" peerDependencies: postcss: ^8.4 - checksum: 10c0/771b281a28f105370ede7c4a86f9e3dd8d9ec3bf2d2883d4f2cfe9c42b5ec1bf88f713458b356870315d0ba3a285fbeb7bb514a1203d1c4fb113bd9044369bf2 + checksum: 10c0/7bec2b1e0b5d786c33c5715b611ffc8b9737252ee6bf77ca59255ac16f91ce614406923f43250e5c88b04f1bb050f155dc5ed4d9350dbd704c45fbd72e5a9a04 languageName: node linkType: hard @@ -13906,8 +13906,8 @@ __metadata: linkType: hard "postcss-preset-env@npm:^10.0.0": - version: 10.0.5 - resolution: "postcss-preset-env@npm:10.0.5" + version: 10.0.6 + resolution: "postcss-preset-env@npm:10.0.6" dependencies: "@csstools/postcss-cascade-layers": "npm:^5.0.0" "@csstools/postcss-color-function": "npm:^4.0.2" @@ -13950,7 +13950,7 @@ __metadata: postcss-color-functional-notation: "npm:^7.0.2" postcss-color-hex-alpha: "npm:^10.0.0" postcss-color-rebeccapurple: "npm:^10.0.0" - postcss-custom-media: "npm:^11.0.1" + postcss-custom-media: "npm:^11.0.2" postcss-custom-properties: "npm:^14.0.1" postcss-custom-selectors: "npm:^8.0.1" postcss-dir-pseudo-class: "npm:^9.0.0" @@ -13972,7 +13972,7 @@ __metadata: postcss-selector-not: "npm:^8.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/db5eb1175cb26bed3f1a4c47acc67935ffc784520321470520e59de366ac6f91be1e609fe36056af707ed20f7910721287cff0fae416c437dd3e944de13ffd05 + checksum: 10c0/01660acf3b9ddf4d612a31819e9a5de9fe5383e9eddd2c130180f66ae90c5a881eb408e73454fd50e1839eae71678d738bf72073de08f9013c183b0bd9950fe5 languageName: node linkType: hard From a59160cf01142a49a15b3237d76a19dcfd9de100 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 7 Oct 2024 09:46:03 +0200 Subject: [PATCH 096/150] Add missing `on_delete: :cascade` on `notification_permissions` (#32281) --- ...ix_notification_permission_foreign_keys.rb | 39 +++++++++++++++++++ db/schema.rb | 6 +-- 2 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20241007071624_fix_notification_permission_foreign_keys.rb diff --git a/db/migrate/20241007071624_fix_notification_permission_foreign_keys.rb b/db/migrate/20241007071624_fix_notification_permission_foreign_keys.rb new file mode 100644 index 0000000000..11b82de8a6 --- /dev/null +++ b/db/migrate/20241007071624_fix_notification_permission_foreign_keys.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +class FixNotificationPermissionForeignKeys < ActiveRecord::Migration[7.1] + def up + safety_assured do + execute <<~SQL.squish + ALTER TABLE notification_permissions + DROP CONSTRAINT fk_rails_7c0bed08df, + ADD CONSTRAINT fk_rails_7c0bed08df + FOREIGN KEY (account_id) + REFERENCES accounts(id) + ON DELETE CASCADE, + + DROP CONSTRAINT fk_rails_e3e0aaad70, + ADD CONSTRAINT fk_rails_e3e0aaad70 + FOREIGN KEY (from_account_id) + REFERENCES accounts(id) + ON DELETE CASCADE + SQL + end + end + + def down + safety_assured do + execute <<~SQL.squish + ALTER TABLE notification_permissions + DROP CONSTRAINT fk_rails_7c0bed08df, + ADD CONSTRAINT fk_rails_7c0bed08df + FOREIGN KEY (account_id) + REFERENCES accounts(id), + + DROP CONSTRAINT fk_rails_e3e0aaad70, + ADD CONSTRAINT fk_rails_e3e0aaad70 + FOREIGN KEY (from_account_id) + REFERENCES accounts(id) + SQL + end + end +end diff --git a/db/schema.rb b/db/schema.rb index f9f2d97395..68067841e0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_09_16_190140) do +ActiveRecord::Schema[7.1].define(version: 2024_10_07_071624) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -1291,8 +1291,8 @@ ActiveRecord::Schema[7.1].define(version: 2024_09_16_190140) do add_foreign_key "mentions", "statuses", on_delete: :cascade add_foreign_key "mutes", "accounts", column: "target_account_id", name: "fk_eecff219ea", on_delete: :cascade add_foreign_key "mutes", "accounts", name: "fk_b8d8daf315", on_delete: :cascade - add_foreign_key "notification_permissions", "accounts" - add_foreign_key "notification_permissions", "accounts", column: "from_account_id" + add_foreign_key "notification_permissions", "accounts", column: "from_account_id", on_delete: :cascade + add_foreign_key "notification_permissions", "accounts", on_delete: :cascade add_foreign_key "notification_policies", "accounts", on_delete: :cascade add_foreign_key "notification_requests", "accounts", column: "from_account_id", on_delete: :cascade add_foreign_key "notification_requests", "accounts", on_delete: :cascade From 1f5bd571cd26ddb44228b8e6a9498e765037e639 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 7 Oct 2024 11:35:42 +0200 Subject: [PATCH 097/150] Fix missing avatar fallback interfering with transparency in web UI (#32270) --- .../__snapshots__/avatar-test.jsx.snap | 8 ++++-- app/javascript/mastodon/components/avatar.tsx | 25 +++++++++++++++---- .../styles/mastodon/components.scss | 7 ++++-- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.jsx.snap b/app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.jsx.snap index 2f0a2de324..124b50d8c7 100644 --- a/app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.jsx.snap +++ b/app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.jsx.snap @@ -2,7 +2,7 @@ exports[` Autoplay renders a animated avatar 1`] = `
Autoplay renders a animated avatar 1`] = ` >
@@ -21,7 +23,7 @@ exports[` Autoplay renders a animated avatar 1`] = ` exports[` Still renders a still avatar 1`] = `
Still renders a still avatar 1`] = ` >
diff --git a/app/javascript/mastodon/components/avatar.tsx b/app/javascript/mastodon/components/avatar.tsx index 8b16296c2c..f61d9676de 100644 --- a/app/javascript/mastodon/components/avatar.tsx +++ b/app/javascript/mastodon/components/avatar.tsx @@ -1,10 +1,11 @@ +import { useState, useCallback } from 'react'; + import classNames from 'classnames'; +import { useHovering } from 'mastodon/../hooks/useHovering'; +import { autoPlayGif } from 'mastodon/initial_state'; import type { Account } from 'mastodon/models/account'; -import { useHovering } from '../../hooks/useHovering'; -import { autoPlayGif } from '../initial_state'; - interface Props { account: Account | undefined; // FIXME: remove `undefined` once we know for sure its always there size: number; @@ -25,6 +26,8 @@ export const Avatar: React.FC = ({ counterBorderColor, }) => { const { hovering, handleMouseEnter, handleMouseLeave } = useHovering(animate); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(false); const style = { ...styleFromParent, @@ -37,16 +40,28 @@ export const Avatar: React.FC = ({ ? account?.get('avatar') : account?.get('avatar_static'); + const handleLoad = useCallback(() => { + setLoading(false); + }, [setLoading]); + + const handleError = useCallback(() => { + setError(true); + }, [setError]); + return (
- {src && } + {src && !error && ( + + )} + {counter && (
[data-popper-placement] { display: block; position: relative; border-radius: var(--avatar-border-radius); - background-color: var(--surface-background-color); img { width: 100%; @@ -2087,7 +2086,11 @@ body > [data-popper-placement] { display: inline-block; // to not show broken images } - &-inline { + &--loading { + background-color: var(--surface-background-color); + } + + &--inline { display: inline-block; vertical-align: middle; margin-inline-end: 5px; From bfabd6a2b882c4eca186e8fe47ce98a47f74662f Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 7 Oct 2024 08:02:04 -0400 Subject: [PATCH 098/150] Move account suspension-related methods to concern (#28351) --- app/models/account.rb | 38 +------------------ app/models/concerns/account/suspensions.rb | 44 ++++++++++++++++++++++ 2 files changed, 45 insertions(+), 37 deletions(-) create mode 100644 app/models/concerns/account/suspensions.rb diff --git a/app/models/account.rb b/app/models/account.rb index 3b841e7c77..708415b6ee 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -89,6 +89,7 @@ class Account < ApplicationRecord include Account::Merging include Account::Search include Account::StatusesSearch + include Account::Suspensions include Account::AttributionDomains include DomainMaterializable include DomainNormalizable @@ -127,9 +128,7 @@ class Account < ApplicationRecord scope :local, -> { where(domain: nil) } scope :partitioned, -> { order(Arel.sql('row_number() over (partition by domain)')) } scope :silenced, -> { where.not(silenced_at: nil) } - scope :suspended, -> { where.not(suspended_at: nil) } scope :sensitized, -> { where.not(sensitized_at: nil) } - scope :without_suspended, -> { where(suspended_at: nil) } scope :without_silenced, -> { where(silenced_at: nil) } scope :without_instance_actor, -> { where.not(id: INSTANCE_ACTOR_ID) } scope :recent, -> { reorder(id: :desc) } @@ -255,41 +254,6 @@ class Account < ApplicationRecord update!(silenced_at: nil) end - def suspended? - suspended_at.present? && !instance_actor? - end - - def suspended_locally? - suspended? && suspension_origin_local? - end - - def suspended_permanently? - suspended? && deletion_request.nil? - end - - def suspended_temporarily? - suspended? && deletion_request.present? - end - - alias unavailable? suspended? - alias permanently_unavailable? suspended_permanently? - - def suspend!(date: Time.now.utc, origin: :local, block_email: true) - transaction do - create_deletion_request! - update!(suspended_at: date, suspension_origin: origin) - create_canonical_email_block! if block_email - end - end - - def unsuspend! - transaction do - deletion_request&.destroy! - update!(suspended_at: nil, suspension_origin: nil) - destroy_canonical_email_block! - end - end - def sensitized? sensitized_at.present? end diff --git a/app/models/concerns/account/suspensions.rb b/app/models/concerns/account/suspensions.rb new file mode 100644 index 0000000000..c981fb5a29 --- /dev/null +++ b/app/models/concerns/account/suspensions.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module Account::Suspensions + extend ActiveSupport::Concern + + included do + scope :suspended, -> { where.not(suspended_at: nil) } + scope :without_suspended, -> { where(suspended_at: nil) } + end + + def suspended? + suspended_at.present? && !instance_actor? + end + alias unavailable? suspended? + + def suspended_locally? + suspended? && suspension_origin_local? + end + + def suspended_permanently? + suspended? && deletion_request.nil? + end + alias permanently_unavailable? suspended_permanently? + + def suspended_temporarily? + suspended? && deletion_request.present? + end + + def suspend!(date: Time.now.utc, origin: :local, block_email: true) + transaction do + create_deletion_request! + update!(suspended_at: date, suspension_origin: origin) + create_canonical_email_block! if block_email + end + end + + def unsuspend! + transaction do + deletion_request&.destroy! + update!(suspended_at: nil, suspension_origin: nil) + destroy_canonical_email_block! + end + end +end From 4238da6ee3c93dfd5752e9133cbec958f8ebb18a Mon Sep 17 00:00:00 2001 From: Leni Kadali <52788034+lenikadali@users.noreply.github.com> Date: Mon, 7 Oct 2024 15:05:46 +0300 Subject: [PATCH 099/150] Add error message when user tries to follow their own account (#31910) --- app/controllers/api/v1/accounts_controller.rb | 5 +++++ config/locales/en.yml | 1 + spec/requests/api/v1/accounts_spec.rb | 20 +++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb index 84b604b305..28acaeea05 100644 --- a/app/controllers/api/v1/accounts_controller.rb +++ b/app/controllers/api/v1/accounts_controller.rb @@ -16,6 +16,7 @@ class Api::V1::AccountsController < Api::BaseController before_action :check_account_confirmation, except: [:index, :create] before_action :check_enabled_registrations, only: [:create] before_action :check_accounts_limit, only: [:index] + before_action :check_following_self, only: [:follow] skip_before_action :require_authenticated_user!, only: :create @@ -101,6 +102,10 @@ class Api::V1::AccountsController < Api::BaseController raise(Mastodon::ValidationError) if account_ids.size > DEFAULT_ACCOUNTS_LIMIT end + def check_following_self + render json: { error: I18n.t('accounts.self_follow_error') }, status: 403 if current_user.account.id == @account.id + end + def relationships(**options) AccountRelationshipsPresenter.new([@account], current_user.account_id, **options) end diff --git a/config/locales/en.yml b/config/locales/en.yml index 42327ae183..c88ef3fa20 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -21,6 +21,7 @@ en: one: Post other: Posts posts_tab_heading: Posts + self_follow_error: Following your own account is not allowed admin: account_actions: action: Perform action diff --git a/spec/requests/api/v1/accounts_spec.rb b/spec/requests/api/v1/accounts_spec.rb index 45e66f0744..16010ae2e7 100644 --- a/spec/requests/api/v1/accounts_spec.rb +++ b/spec/requests/api/v1/accounts_spec.rb @@ -163,6 +163,26 @@ RSpec.describe '/api/v1/accounts' do end end + context 'when user tries to follow their own account' do + subject do + post "/api/v1/accounts/#{other_account.id}/follow", headers: headers + end + + let(:locked) { false } + let(:other_account) { user.account } + + it 'returns http forbidden and error message' do + subject + + error_msg = I18n.t('accounts.self_follow_error') + + expect(response).to have_http_status(403) + expect(response.parsed_body[:error]).to eq(error_msg) + end + + it_behaves_like 'forbidden for wrong scope', 'read:accounts' + end + context 'when modifying follow options' do let(:locked) { false } From 9ca99b7dc1ad1eccaea0da220fb0499f0cfd7069 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 7 Oct 2024 08:53:29 +0200 Subject: [PATCH 100/150] [Glitch] Fix wrong width on logo in detailed link card in web UI Port 889edc560ae94b0663bab0e4cdb7cbad7e3cc6f8 to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/styles/components.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/flavours/glitch/styles/components.scss b/app/javascript/flavours/glitch/styles/components.scss index a17591293f..70dccc0d88 100644 --- a/app/javascript/flavours/glitch/styles/components.scss +++ b/app/javascript/flavours/glitch/styles/components.scss @@ -11172,6 +11172,7 @@ noscript { gap: 8px; .logo { + width: 16px; height: 16px; color: $darker-text-color; } From ee170817935ba62fd2689ff655066d6cdd95516b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 7 Oct 2024 11:35:42 +0200 Subject: [PATCH 101/150] [Glitch] Fix missing avatar fallback interfering with transparency in web UI Port cae93e79a406a1156b51091784e35f8f0126ea12 to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/components/avatar.tsx | 25 +++++++++++++++---- .../flavours/glitch/styles/components.scss | 7 ++++-- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/app/javascript/flavours/glitch/components/avatar.tsx b/app/javascript/flavours/glitch/components/avatar.tsx index c8bf388d26..bb146f0edb 100644 --- a/app/javascript/flavours/glitch/components/avatar.tsx +++ b/app/javascript/flavours/glitch/components/avatar.tsx @@ -1,10 +1,11 @@ +import { useState, useCallback } from 'react'; + import classNames from 'classnames'; +import { useHovering } from 'flavours/glitch/hooks/useHovering'; +import { autoPlayGif } from 'flavours/glitch/initial_state'; import type { Account } from 'flavours/glitch/models/account'; -import { useHovering } from '../hooks/useHovering'; -import { autoPlayGif } from '../initial_state'; - interface Props { account: Account | undefined; // FIXME: remove `undefined` once we know for sure its always there size: number; @@ -25,6 +26,8 @@ export const Avatar: React.FC = ({ counterBorderColor, }) => { const { hovering, handleMouseEnter, handleMouseLeave } = useHovering(animate); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(false); const style = { ...styleFromParent, @@ -37,17 +40,29 @@ export const Avatar: React.FC = ({ ? account?.get('avatar') : account?.get('avatar_static'); + const handleLoad = useCallback(() => { + setLoading(false); + }, [setLoading]); + + const handleError = useCallback(() => { + setError(true); + }, [setError]); + return (
- {src && } + {src && !error && ( + + )} + {counter && (
[data-popper-placement] { display: block; position: relative; border-radius: var(--avatar-border-radius); - background-color: var(--surface-background-color); img { width: 100%; @@ -2269,7 +2268,11 @@ body > [data-popper-placement] { display: inline-block; // to not show broken images } - &-inline { + &--loading { + background-color: var(--surface-background-color); + } + + &--inline { display: inline-block; vertical-align: middle; margin-inline-end: 5px; From 0c163659913f1d9d02cd8b5e45913846f2039c96 Mon Sep 17 00:00:00 2001 From: Jake Anto <64896514+jake-anto@users.noreply.github.com> Date: Tue, 8 Oct 2024 02:03:14 +0530 Subject: [PATCH 102/150] Prefer native apps over PWA (#27254) --- app/serializers/manifest_serializer.rb | 27 +++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/app/serializers/manifest_serializer.rb b/app/serializers/manifest_serializer.rb index cf0164c24a..3496f329f8 100644 --- a/app/serializers/manifest_serializer.rb +++ b/app/serializers/manifest_serializer.rb @@ -8,7 +8,8 @@ class ManifestSerializer < ActiveModel::Serializer attributes :id, :name, :short_name, :icons, :theme_color, :background_color, :display, :start_url, :scope, - :share_target, :shortcuts + :share_target, :shortcuts, + :prefer_related_applications, :related_applications def id # This is set to `/home` because that was the old value of `start_url` and @@ -89,4 +90,28 @@ class ManifestSerializer < ActiveModel::Serializer }, ] end + + def prefer_related_applications + true + end + + def related_applications + [ + { + platform: 'play', + url: 'https://play.google.com/store/apps/details?id=org.joinmastodon.android', + id: 'org.joinmastodon.android', + }, + { + platform: 'itunes', + url: 'https://apps.apple.com/us/app/mastodon-for-iphone/id1571998974', + id: 'id1571998974', + }, + { + platform: 'f-droid', + url: 'https://f-droid.org/en/packages/org.joinmastodon.android/', + id: 'org.joinmastodon.android', + }, + ] + end end From c60d4ecc82ce3dd2f2a00eaccf5231f03f24c31d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 09:38:43 +0200 Subject: [PATCH 103/150] Update dependency @reduxjs/toolkit to v2.2.8 (#32296) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 35fca2f8ad..5fc15f27e0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3110,8 +3110,8 @@ __metadata: linkType: hard "@reduxjs/toolkit@npm:^2.0.1": - version: 2.2.7 - resolution: "@reduxjs/toolkit@npm:2.2.7" + version: 2.2.8 + resolution: "@reduxjs/toolkit@npm:2.2.8" dependencies: immer: "npm:^10.0.3" redux: "npm:^5.0.1" @@ -3125,7 +3125,7 @@ __metadata: optional: true react-redux: optional: true - checksum: 10c0/7761a91adac2b5e1d50a8163ba5441480bb86a3a80b7583037c27a88463394b132dd7592862fc2be03aa7ab98a6e1710549889986dc0d3f033c169a3ba2cb02e + checksum: 10c0/bf1356d71bfb82e5a181692c79c19b7bc19355260a9966f6562604c995f0cd0ce1154177ccd14095e8b319e73f64cfe86a4e46a83d24edba7876d4ae71fd5ae0 languageName: node linkType: hard From 562105c69a9166d3a7f8eb09f2221e3571697ba0 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 8 Oct 2024 10:00:05 +0200 Subject: [PATCH 104/150] Fix source strings being uploaded to crowdin in merge groups (#32298) --- .github/workflows/crowdin-upload.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/crowdin-upload.yml b/.github/workflows/crowdin-upload.yml index 62ad1150bc..4f4d917d15 100644 --- a/.github/workflows/crowdin-upload.yml +++ b/.github/workflows/crowdin-upload.yml @@ -1,7 +1,6 @@ name: Crowdin / Upload translations on: - merge_group: push: branches: - 'main' From ff3e2c9cfa857b5091a9119337728bf972763856 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 08:10:39 +0000 Subject: [PATCH 105/150] New Crowdin Translations (automated) (#32295) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/be.json | 1 + app/javascript/mastodon/locales/de.json | 2 +- config/locales/ca.yml | 1 + config/locales/da.yml | 1 + config/locales/de.yml | 1 + config/locales/eo.yml | 1 + config/locales/es-AR.yml | 1 + config/locales/es-MX.yml | 1 + config/locales/es.yml | 1 + config/locales/fi.yml | 1 + config/locales/fo.yml | 1 + config/locales/gl.yml | 1 + config/locales/he.yml | 1 + config/locales/is.yml | 1 + config/locales/ja.yml | 1 + config/locales/ko.yml | 1 + config/locales/nl.yml | 1 + config/locales/nn.yml | 1 + config/locales/pl.yml | 1 + config/locales/pt-BR.yml | 1 + config/locales/tr.yml | 1 + config/locales/uk.yml | 1 + config/locales/vi.yml | 1 + config/locales/zh-CN.yml | 1 + config/locales/zh-TW.yml | 1 + 25 files changed, 25 insertions(+), 1 deletion(-) diff --git a/app/javascript/mastodon/locales/be.json b/app/javascript/mastodon/locales/be.json index 797d8cc22e..d3a29eae40 100644 --- a/app/javascript/mastodon/locales/be.json +++ b/app/javascript/mastodon/locales/be.json @@ -85,6 +85,7 @@ "alert.rate_limited.title": "Ліміт перавышаны", "alert.unexpected.message": "Узнікла нечаканая памылка.", "alert.unexpected.title": "Вой!", + "alt_text_badge.title": "Альтернативный текст", "announcement.announcement": "Аб'ява", "attachments_list.unprocessed": "(неапрацаваны)", "audio.hide": "Схаваць аўдыя", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 3d8b57db4a..b807d93ab3 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -62,7 +62,7 @@ "account.requested_follow": "{name} möchte dir folgen", "account.share": "Profil von @{name} teilen", "account.show_reblogs": "Geteilte Beiträge von @{name} anzeigen", - "account.statuses_counter": "{count, plural, one {{counter} post} other {{counter} posts}}", + "account.statuses_counter": "{count, plural, one {{counter} Beitrag} other {{counter} Beiträge}}", "account.unblock": "Blockierung von @{name} aufheben", "account.unblock_domain": "Blockierung von {domain} aufheben", "account.unblock_short": "Blockierung aufheben", diff --git a/config/locales/ca.yml b/config/locales/ca.yml index bb81aaa59c..cc2da496a6 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -21,6 +21,7 @@ ca: one: Tut other: Tuts posts_tab_heading: Tuts + self_follow_error: No es permet seguir el compte propi admin: account_actions: action: Realitza l'acció diff --git a/config/locales/da.yml b/config/locales/da.yml index 1f80503e91..923102c11f 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -21,6 +21,7 @@ da: one: Indlæg other: Indlæg posts_tab_heading: Indlæg + self_follow_error: Det er ikke tilladt at følge sin egen konto admin: account_actions: action: Udfør handling diff --git a/config/locales/de.yml b/config/locales/de.yml index 5f0b4ae353..cfd0d6510e 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -21,6 +21,7 @@ de: one: Beitrag other: Beiträge posts_tab_heading: Beiträge + self_follow_error: Es ist nicht erlaubt, deinem eigenen Konto zu folgen admin: account_actions: action: Aktion ausführen diff --git a/config/locales/eo.yml b/config/locales/eo.yml index 10b297f1a8..1e683b1725 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -21,6 +21,7 @@ eo: one: Afiŝo other: Mesaĝoj posts_tab_heading: Afiŝoj + self_follow_error: Sekvi vian propran konton ne estas permesita admin: account_actions: action: Plenumi agon diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index cfc24ce270..04ff7880a1 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -21,6 +21,7 @@ es-AR: one: Mensaje other: Mensajes posts_tab_heading: Mensajes + self_follow_error: No está permitido seguir tu propia cuenta admin: account_actions: action: Ejecutar acción diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index 4e7ee657e6..2c18465a26 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -21,6 +21,7 @@ es-MX: one: Toot other: Toots posts_tab_heading: Toots + self_follow_error: No se permite seguir tu propia cuenta admin: account_actions: action: Realizar acción diff --git a/config/locales/es.yml b/config/locales/es.yml index bb9e5daff5..47d32c62c8 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -21,6 +21,7 @@ es: one: Publicación other: Publicaciones posts_tab_heading: Publicaciones + self_follow_error: No está permitido seguir tu propia cuenta admin: account_actions: action: Realizar acción diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 1767f9e63e..52ea0b374c 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -21,6 +21,7 @@ fi: one: Julkaisu other: viestiä posts_tab_heading: Julkaisut + self_follow_error: Oman tilisi seuraaminen ei ole sallittua admin: account_actions: action: Suorita toimi diff --git a/config/locales/fo.yml b/config/locales/fo.yml index 55104eb6ff..fcf3eb031e 100644 --- a/config/locales/fo.yml +++ b/config/locales/fo.yml @@ -21,6 +21,7 @@ fo: one: Uppslag other: Uppsløg posts_tab_heading: Uppsløg + self_follow_error: Tað er ikki loyvt at fylgja tíni egnu kontu admin: account_actions: action: Frem atgerð diff --git a/config/locales/gl.yml b/config/locales/gl.yml index 8460902a68..cdc9421324 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -21,6 +21,7 @@ gl: one: Publicación other: Publicacións posts_tab_heading: Publicacións + self_follow_error: Non está permitido seguir a túa propia conta admin: account_actions: action: Executar acción diff --git a/config/locales/he.yml b/config/locales/he.yml index f2732678b5..54b6b6f38d 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -25,6 +25,7 @@ he: other: הודעות two: הודעותיים posts_tab_heading: הודעות + self_follow_error: בלתי אפשרי לך לעקוב אחרי חשבונך admin: account_actions: action: בצע/י פעולה diff --git a/config/locales/is.yml b/config/locales/is.yml index 6eefaf1b0e..f181470e49 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -21,6 +21,7 @@ is: one: Færsla other: Færslur posts_tab_heading: Færslur + self_follow_error: Ekki er leyft að fylgjast með eigin aðgangi admin: account_actions: action: Framkvæma aðgerð diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 54b7fb5412..bda5b2d8f6 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -19,6 +19,7 @@ ja: posts: other: 投稿 posts_tab_heading: 投稿 + self_follow_error: 自分のアカウントをフォローすることはできません admin: account_actions: action: アクションを実行 diff --git a/config/locales/ko.yml b/config/locales/ko.yml index d20d67e4c3..615783738a 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -19,6 +19,7 @@ ko: posts: other: 게시물 posts_tab_heading: 게시물 + self_follow_error: 본인의 계정을 팔로우할 수는 없습니다 admin: account_actions: action: 조치 취하기 diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 52ec4c89ce..968dcc3e7c 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -21,6 +21,7 @@ nl: one: Toot other: Berichten posts_tab_heading: Berichten + self_follow_error: Het volgen van je eigen account is niet toegestaan admin: account_actions: action: Actie uitvoeren diff --git a/config/locales/nn.yml b/config/locales/nn.yml index ec3db6520f..b28cf30162 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -21,6 +21,7 @@ nn: one: Tut other: Tut posts_tab_heading: Tut + self_follow_error: Det er ikkje tillate å følgje din eigen konto admin: account_actions: action: Utfør diff --git a/config/locales/pl.yml b/config/locales/pl.yml index aaf8a9e722..ba1f4812e9 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -25,6 +25,7 @@ pl: one: wpis other: Wpisów posts_tab_heading: Wpisy + self_follow_error: Nie możesz obserwować swojego konta admin: account_actions: action: Wykonaj działanie diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 427703f57e..8e806f670c 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -21,6 +21,7 @@ pt-BR: one: Publicação other: Publicações posts_tab_heading: Publicações + self_follow_error: Seguir sua conta não é permitido admin: account_actions: action: Tomar uma atitude diff --git a/config/locales/tr.yml b/config/locales/tr.yml index df55aa5a29..ee74f237ee 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -21,6 +21,7 @@ tr: one: Gönderi other: Gönderiler posts_tab_heading: Gönderiler + self_follow_error: Kendi hesabınızı takip etmenize izin yok admin: account_actions: action: Eylemi gerçekleştir diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 47732198f1..dec4299fb9 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -25,6 +25,7 @@ uk: one: Допис other: Дописів posts_tab_heading: Дописів + self_follow_error: Ви не можете стежити за власним обліковим записом admin: account_actions: action: Виконати дію diff --git a/config/locales/vi.yml b/config/locales/vi.yml index 17edfba70a..7c30c5b127 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -19,6 +19,7 @@ vi: posts: other: Tút posts_tab_heading: Tút + self_follow_error: Bạn không thể tự theo dõi chính bạn admin: account_actions: action: Thực hiện hành động diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 7be8fb5a58..2654804697 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -19,6 +19,7 @@ zh-CN: posts: other: 嘟文 posts_tab_heading: 嘟文 + self_follow_error: 不可以关注自己 admin: account_actions: action: 执行操作 diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 96aedf0a1c..c461aabcdc 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -19,6 +19,7 @@ zh-TW: posts: other: 嘟文 posts_tab_heading: 嘟文 + self_follow_error: 無法跟隨您自己的帳號 admin: account_actions: action: 執行動作 From 1de6d511f44c432f0f1954ea0c7153e80be9729b Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 8 Oct 2024 13:41:11 +0200 Subject: [PATCH 106/150] Fix download of stable translation files in glitch-soc --- .github/workflows/crowdin-download-stable.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/crowdin-download-stable.yml b/.github/workflows/crowdin-download-stable.yml index de21e2e58f..18911d49c2 100644 --- a/.github/workflows/crowdin-download-stable.yml +++ b/.github/workflows/crowdin-download-stable.yml @@ -26,6 +26,7 @@ jobs: - name: crowdin action uses: crowdin/github-action@v2 with: + config: crowdin-glitch.yml upload_sources: false upload_translations: false download_translations: true From c3a38c7d8c123f5bf736e20e0417fb3d70022391 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 8 Oct 2024 14:24:59 +0200 Subject: [PATCH 107/150] Update changelog and security policy (#32300) --- CHANGELOG.md | 26 ++++++++++++++++---------- SECURITY.md | 11 ++++++----- docker-compose.yml | 6 +++--- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5eef082ccc..566c474356 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -## [4.3.0] - UNRELEASED +## [4.3.0] - 2024-10-08 The following changelog entries focus on changes visible to users, administrators, client developers or federated software developers, but there has also been a lot of code modernization, refactoring, and tooling work, in particular by @mjankowski. @@ -11,12 +11,12 @@ The following changelog entries focus on changes visible to users, administrator - **Add confirmation interstitial instead of silently redirecting logged-out visitors to remote resources** (#27792, #28902, and #30651 by @ClearlyClaire and @Gargron)\ This fixes a longstanding open redirect in Mastodon, at the cost of added friction when local links to remote resources are shared. - Fix ReDoS vulnerability on some Ruby versions ([GHSA-jpxp-r43f-rhvx](https://github.com/mastodon/mastodon/security/advisories/GHSA-jpxp-r43f-rhvx)) -- Change `form-action` Content-Security-Policy directive to be more restrictive (#26897 by @ClearlyClaire) +- Change `form-action` Content-Security-Policy directive to be more restrictive (#26897 and #32241 by @ClearlyClaire) - Update dependencies ### Added -- **Add server-side notification grouping** (#29889, #30576, #30685, #30688, #30707, #30776, #30779, #30781, #30440, #31062, #31098, #31076, #31111, #31123, #31223, #31214, #31224, #31299, #31325, #31347, #31304, #31326, #31384, #31403, #31433, #31509, #31486, #31513, #31592, #31594, #31638, #31746, #31652, #31709, #31725, #31745, #31613, #31657, #31840, #31610, #31929, #32089 and #32085 by @ClearlyClaire, @Gargron, @mgmn, and @renchap)\ +- **Add server-side notification grouping** (#29889, #30576, #30685, #30688, #30707, #30776, #30779, #30781, #30440, #31062, #31098, #31076, #31111, #31123, #31223, #31214, #31224, #31299, #31325, #31347, #31304, #31326, #31384, #31403, #31433, #31509, #31486, #31513, #31592, #31594, #31638, #31746, #31652, #31709, #31725, #31745, #31613, #31657, #31840, #31610, #31929, #32089, #32085, #32243, #32179 and #32254 by @ClearlyClaire, @Gargron, @mgmn, and @renchap)\ Group notifications of the same type for the same target, so that your notifications no longer get cluttered by boost and favorite notifications as soon as a couple of your posts get traction.\ This is done server-side so that clients can efficiently get relevant groups without having to go through numerous pages of individual notifications.\ As part of this, the visual design of the entire notifications feature has been revamped.\ @@ -28,7 +28,7 @@ The following changelog entries focus on changes visible to users, administrator - `GET /api/v2/notifications/:group_key/accounts`: https://docs.joinmastodon.org/methods/grouped_notifications/#get-group-accounts - `POST /api/v2/notifications/:group_key/dimsiss`: https://docs.joinmastodon.org/methods/grouped_notifications/#dismiss-group - `GET /api/v2/notifications/:unread_count`: https://docs.joinmastodon.org/methods/grouped_notifications/#unread-group-count -- **Add notification policies, filtered notifications and notification requests** (#29366, #29529, #29433, #29565, #29567, #29572, #29575, #29588, #29646, #29652, #29658, #29666, #29693, #29699, #29737, #29706, #29570, #29752, #29810, #29826, #30114, #30251, #30559, #29868, #31008, #31011, #30996, #31149, #31220, #31222, #31225, #31242, #31262, #31250, #31273, #31310, #31316, #31322, #31329, #31324, #31331, #31343, #31342, #31309, #31358, #31378, #31406, #31256, #31456, #31419, #31457, #31508, #31540, #31541, #31723 and #32062 by @ClearlyClaire, @Gargron, @TheEssem, @mgmn, @oneiros, and @renchap)\ +- **Add notification policies, filtered notifications and notification requests** (#29366, #29529, #29433, #29565, #29567, #29572, #29575, #29588, #29646, #29652, #29658, #29666, #29693, #29699, #29737, #29706, #29570, #29752, #29810, #29826, #30114, #30251, #30559, #29868, #31008, #31011, #30996, #31149, #31220, #31222, #31225, #31242, #31262, #31250, #31273, #31310, #31316, #31322, #31329, #31324, #31331, #31343, #31342, #31309, #31358, #31378, #31406, #31256, #31456, #31419, #31457, #31508, #31540, #31541, #31723, #32062 and #32281 by @ClearlyClaire, @Gargron, @TheEssem, @mgmn, @oneiros, and @renchap)\ The old “Block notifications from non-followers”, “Block notifications from people you don't follow” and “Block direct messages from people you don't follow” notification settings have been replaced by a new set of settings found directly in the notification column.\ You can now separately filter or drop notifications from people you don't follow, people who don't follow you, accounts created within the past 30 days, as well as unsolicited private mentions, and accounts limited by the moderation.\ Instead of being outright dropped, notifications that you chose to filter are put in a separate “Filtered notifications” box that you can review separately without it clogging your main notifications.\ @@ -61,7 +61,7 @@ The following changelog entries focus on changes visible to users, administrator - **Add timeline of public posts about a trending link** (#30381 and #30840 by @Gargron)\ You can now see public posts mentioning currently-trending articles from people who have opted into discovery features.\ This adds a new REST API endpoint: https://docs.joinmastodon.org/methods/timelines/#link -- **Add author highlight for news articles whose authors are on the fediverse** (#30398, #30670, #30521, #30846, #31819, and #31900 by @Gargron and @oneiros)\ +- **Add author highlight for news articles whose authors are on the fediverse** (#30398, #30670, #30521, #30846, #31819, #31900 and #32188 by @Gargron, @mjankowski and @oneiros)\ This adds a mechanism to [highlight the author of news articles](https://blog.joinmastodon.org/2024/07/highlighting-journalism-on-mastodon/) shared on Mastodon.\ Articles hosted outside the fediverse can indicate a fediverse author with a meta tag: ```html @@ -150,10 +150,12 @@ The following changelog entries focus on changes visible to users, administrator - Add groundwork for annual reports for accounts (#28693 by @Gargron)\ This lays the groundwork for a “year-in-review”/“wrapped” style report for local users, but is currently not in use. - Add notification email on invalid second authenticator (#28822 by @ClearlyClaire) +- Add date of account deletion in list of accounts in the admin interface (#25640 by @tribela) - Add new emojis from `jdecked/twemoji` 15.0 (#28404 by @TheEssem) - Add configurable error handling in attachment batch deletion (#28184 by @vmstan)\ This makes the S3 batch size configurable through the `S3_BATCH_DELETE_LIMIT` environment variable (defaults to 1000), and adds some retry logic, configurable through the `S3_BATCH_DELETE_RETRY` environment variable (defaults to 3). - Add VAPID public key to instance serializer (#28006 by @ThisIsMissEm) +- Add support for serving JRD `/.well-known/host-meta.json` in addition to XRD host-meta (#32206 by @c960657) - Add `nodeName` and `nodeDescription` to nodeinfo `metadata` (#28079 by @6543) - Add Thai diacritics and tone marks in `HASHTAG_INVALID_CHARS_RE` (#26576 by @ppnplus) - Add variable delay before link verification of remote account links (#27774 by @ClearlyClaire) @@ -168,7 +170,7 @@ The following changelog entries focus on changes visible to users, administrator ### Changed -- **Change icons throughout the web interface** (#27385, #27539, #27555, #27579, #27700, #27817, #28519, #28709, #28064, #28775, #28780, #27924, #29294, #29395, #29537, #29569, #29610, #29612, #29649, #29844, #27780, #30974, #30963, #30962, #30961, #31362, #31363, #31359, #31371, #31360, #31512, #31511, and #31525 by @ClearlyClaire, @Gargron, @arbolitoloco1, @mjankowski, @nclm, @renchap, @ronilaukkarinen, and @zunda)\ +- **Change icons throughout the web interface** (#27385, #27539, #27555, #27579, #27700, #27817, #28519, #28709, #28064, #28775, #28780, #27924, #29294, #29395, #29537, #29569, #29610, #29612, #29649, #29844, #27780, #30974, #30963, #30962, #30961, #31362, #31363, #31359, #31371, #31360, #31512, #31511, #31525, #32153, and #32201 by @ClearlyClaire, @Gargron, @arbolitoloco1, @mjankowski, @nclm, @renchap, @ronilaukkarinen, and @zunda)\ This changes all the interface icons from FontAwesome to Material Symbols for a more modern look, consistent with the official Mastodon Android app.\ In addition, better care is given to pixel alignment, and icon variants are used to better highlight active/inactive state. - **Change design of compose form in web UI** (#28119, #29059, #29248, #29372, #29384, #29417, #29456, #29406, #29651, #29659, #31889 and #32033 by @ClearlyClaire, @Gargron, @eai04191, @hinaloe, and @ronilaukkarinen)\ @@ -192,9 +194,9 @@ The following changelog entries focus on changes visible to users, administrator Administrators may need to update their setup accordingly. - Change how content warnings and filters are displayed in web UI (#31365, and #31761 by @Gargron) - Change preview card processing to ignore `undefined` as canonical url (#31882 by @oneiros) -- Change embedded posts to use web UI (#31766 and #32135 by @Gargron) +- Change embedded posts to use web UI (#31766, #32135 and #32271 by @Gargron) - Change inner borders in media galleries in web UI (#31852 by @Gargron) -- Change design of media attachments and profile media tab in web UI (#31807, #32048, and #31967 by @Gargron) +- Change design of media attachments and profile media tab in web UI (#31807, #32048, #31967, #32217, #32224 and #32257 by @ClearlyClaire and @Gargron) - Change labels on thread indicators in web UI (#31806 by @Gargron) - Change label of "Data export" menu item in settings interface (#32099 by @c960657) - Change responsive break points on navigation panel in web UI (#32034 by @Gargron) @@ -284,9 +286,10 @@ The following changelog entries focus on changes visible to users, administrator - Fix error when accepting an appeal for sensitive posts deleted in the meantime (#32037 by @ClearlyClaire) - Fix error when encountering reblog of deleted post in feed rebuild (#32001 by @ClearlyClaire) - Fix Safari browser glitch related to horizontal scrolling (#31960 by @Gargron) +- Fix unresolvable mentions sometimes preventing processing incoming posts (#29215 by @tribela and @ClearlyClaire) - Fix too many requests caused by relationship look-ups in web UI (#32042 by @Gargron) - Fix links for reblogs in moderation interface (#31979 by @ClearlyClaire) -- Fix the appearance of avatars when they do not load (#31966 by @renchap) +- Fix the appearance of avatars when they do not load (#31966 and #32270 by @Gargron and @renchap) - Fix spurious error notifications for aborted requests in web UI (#31952 by @c960657) - Fix HTTP 500 error in `/api/v1/polls/:id/votes` when required `choices` parameter is missing (#25598 by @danielmbrasil) - Fix security context sometimes not being added in LD-Signed activities (#31871 by @ClearlyClaire) @@ -309,10 +312,12 @@ The following changelog entries focus on changes visible to users, administrator - Fix “Redirect URI” field not being marked as required in “New application” form (#30311 by @ThisIsMissEm) - Fix right-to-left text in preview cards (#30930 by @ClearlyClaire) - Fix rack attack `match_type` value typo in logging config (#30514 by @mjankowski) -- Fix various cases of duplicate, missing, or inconsistent borders or scrollbar styles (#31068, #31286, #31268, #31275, #31284, #31305, #31346, #31372, #31373, #31389, #31432, #31391, #31445 and #32091 by @ClearlyClaire, @valtlai and @vmstan) +- Fix various cases of duplicate, missing, or inconsistent borders or scrollbar styles (#31068, #31286, #31268, #31275, #31284, #31305, #31346, #31372, #31373, #31389, #31432, #31391, #31445, #32091, #32147 and #32137 by @ClearlyClaire, @mjankowski, @valtlai and @vmstan) +- Fix editing description of media uploads with custom thumbnails (#32221 by @ClearlyClaire) - Fix race condition in `POST /api/v1/push/subscription` (#30166 by @ClearlyClaire) - Fix post deletion not being delayed when those are part of an account warning (#30163 by @ClearlyClaire) - Fix rendering error on `/start` when not logged in (#30023 by @timothyjrogers) +- Fix unneeded requests to blocked domains when receiving relayed signed activities from them (#31161 by @ClearlyClaire) - Fix logo pushing header buttons out of view on certain conditions in mobile layout (#29787 by @ClearlyClaire) - Fix notification-related records not being reattributed when merging accounts (#29694 by @ClearlyClaire) - Fix results/query in `api/v1/featured_tags/suggestions` (#29597 by @mjankowski) @@ -322,6 +327,7 @@ The following changelog entries focus on changes visible to users, administrator - Fix full date display not respecting the locale 12/24h format (#29448 by @renchap) - Fix filters title and keywords overflow (#29396 by @GeopJr) - Fix incorrect date format in “Follows and followers” (#29390 by @JasonPunyon) +- Fix navigation item active highlight for some paths (#32159 by @mjankowski) - Fix “Edit media” modal sizing and layout when space-constrained (#27095 by @ronilaukkarinen) - Fix modal container bounds (#29185 by @nico3333fr) - Fix inefficient HTTP signature parsing using regexps and `StringScanner` (#29133 by @ClearlyClaire) diff --git a/SECURITY.md b/SECURITY.md index 156954ce02..43ab4454c4 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -13,8 +13,9 @@ A "vulnerability in Mastodon" is a vulnerability in the code distributed through ## Supported Versions -| Version | Supported | -| ------- | --------- | -| 4.2.x | Yes | -| 4.1.x | Yes | -| < 4.1 | No | +| Version | Supported | +| ------- | ---------------- | +| 4.3.x | Yes | +| 4.2.x | Yes | +| 4.1.x | Until 2025-04-08 | +| < 4.1 | No | diff --git a/docker-compose.yml b/docker-compose.yml index 41876d26f9..37cb16497f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -59,7 +59,7 @@ services: web: # You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes # build: . - image: ghcr.io/mastodon/mastodon:v4.3.0-rc.1 + image: ghcr.io/mastodon/mastodon:v4.3.0 restart: always env_file: .env.production command: bundle exec puma -C config/puma.rb @@ -83,7 +83,7 @@ services: # build: # dockerfile: ./streaming/Dockerfile # context: . - image: ghcr.io/mastodon/mastodon-streaming:v4.3.0-rc.1 + image: ghcr.io/mastodon/mastodon-streaming:v4.3.0 restart: always env_file: .env.production command: node ./streaming/index.js @@ -101,7 +101,7 @@ services: sidekiq: build: . - image: ghcr.io/mastodon/mastodon:v4.3.0-rc.1 + image: ghcr.io/mastodon/mastodon:v4.3.0 restart: always env_file: .env.production command: bundle exec sidekiq From 022c1ae6f2911db8c479e0b6b88cff1e3a79c47e Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 8 Oct 2024 08:52:52 -0400 Subject: [PATCH 108/150] Remove unused deprecator configuration (#32288) --- config/application.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/config/application.rb b/config/application.rb index 0013c78858..5e2f44453d 100644 --- a/config/application.rb +++ b/config/application.rb @@ -96,10 +96,6 @@ module Mastodon config.middleware.use Rack::Attack config.middleware.use Mastodon::RackMiddleware - initializer :deprecator do |app| - app.deprecators[:mastodon] = ActiveSupport::Deprecation.new('4.3', 'mastodon/mastodon') - end - config.before_configuration do require 'mastodon/redis_configuration' ::REDIS_CONFIGURATION = Mastodon::RedisConfiguration.new From d20a899bb90c78c2290a947e36f19fff6654ad47 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 8 Oct 2024 09:21:36 -0400 Subject: [PATCH 109/150] Bring icon vertical middle to applications list style (#32293) --- app/javascript/styles/mastodon/admin.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index 0712a0d3f4..c7b32a9c9e 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -1029,6 +1029,12 @@ a.name-tag, color: var(--user-role-accent); } +.applications-list { + .icon { + vertical-align: middle; + } +} + .announcements-list, .filters-list { border: 1px solid var(--background-border-color); From 3cf2d35c4947cb8fb12cb33c22b2832f823cb3a4 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 8 Oct 2024 09:23:30 -0400 Subject: [PATCH 110/150] Reference `IpBlock.severities` keys from CLI option check (#32291) --- lib/mastodon/cli/ip_blocks.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mastodon/cli/ip_blocks.rb b/lib/mastodon/cli/ip_blocks.rb index 3c5fdb275c..ef24f2e047 100644 --- a/lib/mastodon/cli/ip_blocks.rb +++ b/lib/mastodon/cli/ip_blocks.rb @@ -5,7 +5,7 @@ require_relative 'base' module Mastodon::CLI class IpBlocks < Base - option :severity, required: true, enum: %w(no_access sign_up_requires_approval sign_up_block), desc: 'Severity of the block' + option :severity, required: true, enum: IpBlock.severities.keys, desc: 'Severity of the block' option :comment, aliases: [:c], desc: 'Optional comment' option :duration, aliases: [:d], type: :numeric, desc: 'Duration of the block in seconds' option :force, type: :boolean, aliases: [:f], desc: 'Overwrite existing blocks' From f49161ab1d57969b105bd115af8c827fc817db61 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 8 Oct 2024 09:30:54 -0400 Subject: [PATCH 111/150] Oauth system spec cleanup / helper method extraction (#32287) --- spec/system/oauth_spec.rb | 96 +++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 40 deletions(-) diff --git a/spec/system/oauth_spec.rb b/spec/system/oauth_spec.rb index 64ac75879e..14ffc163f0 100644 --- a/spec/system/oauth_spec.rb +++ b/spec/system/oauth_spec.rb @@ -24,28 +24,28 @@ RSpec.describe 'Using OAuth from an external app' do subject # It presents the user with an authorization page - expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.authorize')) - - # Upon authorizing, it redirects to the apps' callback URL - click_on I18n.t('doorkeeper.authorizations.buttons.authorize') - expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) + expect(page).to have_content(oauth_authorize_text) # It grants the app access to the account - expect(Doorkeeper::AccessGrant.exists?(application: client_app, resource_owner_id: user.id)).to be true + expect { click_on oauth_authorize_text } + .to change { user_has_grant_with_client_app? }.to(true) + + # Upon authorizing, it redirects to the apps' callback URL + expect(page).to redirect_to_callback_url end it 'when rejecting the authorization request' do subject # It presents the user with an authorization page - expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.deny')) - - # Upon denying, it redirects to the apps' callback URL - click_on I18n.t('doorkeeper.authorizations.buttons.deny') - expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) + expect(page).to have_content(oauth_deny_text) # It does not grant the app access to the account - expect(Doorkeeper::AccessGrant.exists?(application: client_app, resource_owner_id: user.id)).to be false + expect { click_on oauth_deny_text } + .to_not change { user_has_grant_with_client_app? }.from(false) + + # Upon denying, it redirects to the apps' callback URL + expect(page).to redirect_to_callback_url end # The tests in this context ensures that requests without PKCE parameters @@ -133,7 +133,6 @@ RSpec.describe 'Using OAuth from an external app' do end it 'when accepting the authorization request' do - params = { client_id: client_app.uid, response_type: 'code', redirect_uri: client_app.redirect_uri, scope: 'read' } visit "/oauth/authorize?#{params.to_query}" # It presents the user with a log-in page @@ -145,18 +144,17 @@ RSpec.describe 'Using OAuth from an external app' do # Logging in redirects to an authorization page fill_in_auth_details(email, password) - expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.authorize')) - - # Upon authorizing, it redirects to the apps' callback URL - click_on I18n.t('doorkeeper.authorizations.buttons.authorize') - expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) + expect(page).to have_content(oauth_authorize_text) # It grants the app access to the account - expect(Doorkeeper::AccessGrant.exists?(application: client_app, resource_owner_id: user.id)).to be true + expect { click_on oauth_authorize_text } + .to change { user_has_grant_with_client_app? }.to(true) + + # Upon authorizing, it redirects to the apps' callback URL + expect(page).to redirect_to_callback_url end it 'when rejecting the authorization request' do - params = { client_id: client_app.uid, response_type: 'code', redirect_uri: client_app.redirect_uri, scope: 'read' } visit "/oauth/authorize?#{params.to_query}" # It presents the user with a log-in page @@ -168,21 +166,20 @@ RSpec.describe 'Using OAuth from an external app' do # Logging in redirects to an authorization page fill_in_auth_details(email, password) - expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.authorize')) - - # Upon denying, it redirects to the apps' callback URL - click_on I18n.t('doorkeeper.authorizations.buttons.deny') - expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) + expect(page).to have_content(oauth_authorize_text) # It does not grant the app access to the account - expect(Doorkeeper::AccessGrant.exists?(application: client_app, resource_owner_id: user.id)).to be false + expect { click_on oauth_deny_text } + .to_not change { user_has_grant_with_client_app? }.from(false) + + # Upon denying, it redirects to the apps' callback URL + expect(page).to redirect_to_callback_url end context 'when the user has set up TOTP' do let(:user) { Fabricate(:user, email: email, password: password, otp_required_for_login: true, otp_secret: User.generate_otp_secret) } it 'when accepting the authorization request' do - params = { client_id: client_app.uid, response_type: 'code', redirect_uri: client_app.redirect_uri, scope: 'read' } visit "/oauth/authorize?#{params.to_query}" # It presents the user with a log-in page @@ -202,18 +199,17 @@ RSpec.describe 'Using OAuth from an external app' do # Filling in the correct TOTP code redirects to an app authorization page fill_in_otp_details(user.current_otp) - expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.authorize')) - - # Upon authorizing, it redirects to the apps' callback URL - click_on I18n.t('doorkeeper.authorizations.buttons.authorize') - expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) + expect(page).to have_content(oauth_authorize_text) # It grants the app access to the account - expect(Doorkeeper::AccessGrant.exists?(application: client_app, resource_owner_id: user.id)).to be true + expect { click_on oauth_authorize_text } + .to change { user_has_grant_with_client_app? }.to(true) + + # Upon authorizing, it redirects to the apps' callback URL + expect(page).to redirect_to_callback_url end it 'when rejecting the authorization request' do - params = { client_id: client_app.uid, response_type: 'code', redirect_uri: client_app.redirect_uri, scope: 'read' } visit "/oauth/authorize?#{params.to_query}" # It presents the user with a log-in page @@ -233,14 +229,14 @@ RSpec.describe 'Using OAuth from an external app' do # Filling in the correct TOTP code redirects to an app authorization page fill_in_otp_details(user.current_otp) - expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.authorize')) - - # Upon denying, it redirects to the apps' callback URL - click_on I18n.t('doorkeeper.authorizations.buttons.deny') - expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) + expect(page).to have_content(oauth_authorize_text) # It does not grant the app access to the account - expect(Doorkeeper::AccessGrant.exists?(application: client_app, resource_owner_id: user.id)).to be false + expect { click_on oauth_deny_text } + .to_not change { user_has_grant_with_client_app? }.from(false) + + # Upon denying, it redirects to the apps' callback URL + expect(page).to redirect_to_callback_url end end # TODO: external auth @@ -252,4 +248,24 @@ RSpec.describe 'Using OAuth from an external app' do fill_in 'user_otp_attempt', with: value click_on I18n.t('auth.login') end + + def oauth_authorize_text + I18n.t('doorkeeper.authorizations.buttons.authorize') + end + + def oauth_deny_text + I18n.t('doorkeeper.authorizations.buttons.deny') + end + + def redirect_to_callback_url + have_current_path(/\A#{client_app.redirect_uri}/, url: true) + end + + def user_has_grant_with_client_app? + Doorkeeper::AccessGrant + .exists?( + application: client_app, + resource_owner_id: user.id + ) + end end From e8ec6667bd24028422abb68525db5b8f6a44c801 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 8 Oct 2024 09:53:35 -0400 Subject: [PATCH 112/150] Extract wrapper constant for `HTTP::*` error classes (#32285) --- app/controllers/application_controller.rb | 2 +- app/controllers/concerns/api/error_handling.rb | 2 +- app/controllers/concerns/signature_verification.rb | 2 +- app/controllers/media_proxy_controller.rb | 2 +- app/lib/activitypub/activity/create.rb | 4 ++-- app/models/account_alias.rb | 2 +- app/models/account_migration.rb | 2 +- app/models/concerns/remotable.rb | 2 +- app/models/form/redirect.rb | 2 +- app/models/remote_follow.rb | 2 +- app/services/activitypub/process_account_service.rb | 6 +++--- app/services/activitypub/process_status_update_service.rb | 2 +- app/services/fetch_link_card_service.rb | 2 +- app/services/fetch_resource_service.rb | 2 +- app/services/import_service.rb | 2 +- app/services/process_mentions_service.rb | 2 +- app/services/software_update_check_service.rb | 2 +- app/services/verify_link_service.rb | 2 +- app/workers/refollow_worker.rb | 2 +- lib/exceptions.rb | 6 ++++++ lib/mastodon/cli/accounts.rb | 2 +- 21 files changed, 29 insertions(+), 23 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 62e3355ae6..40cae15b48 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -32,7 +32,7 @@ class ApplicationController < ActionController::Base rescue_from ActionController::InvalidAuthenticityToken, with: :unprocessable_entity rescue_from Mastodon::RateLimitExceededError, with: :too_many_requests - rescue_from HTTP::Error, OpenSSL::SSL::SSLError, with: :internal_server_error + rescue_from(*Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, with: :internal_server_error) rescue_from Mastodon::RaceConditionError, Stoplight::Error::RedLight, ActiveRecord::SerializationFailure, with: :service_unavailable rescue_from Seahorse::Client::NetworkingError do |e| diff --git a/app/controllers/concerns/api/error_handling.rb b/app/controllers/concerns/api/error_handling.rb index ad559fe2d7..9ce4795b02 100644 --- a/app/controllers/concerns/api/error_handling.rb +++ b/app/controllers/concerns/api/error_handling.rb @@ -20,7 +20,7 @@ module Api::ErrorHandling render json: { error: 'Record not found' }, status: 404 end - rescue_from HTTP::Error, Mastodon::UnexpectedResponseError do + rescue_from(*Mastodon::HTTP_CONNECTION_ERRORS, Mastodon::UnexpectedResponseError) do render json: { error: 'Remote data could not be fetched' }, status: 503 end diff --git a/app/controllers/concerns/signature_verification.rb b/app/controllers/concerns/signature_verification.rb index 68f09ee023..6773c11099 100644 --- a/app/controllers/concerns/signature_verification.rb +++ b/app/controllers/concerns/signature_verification.rb @@ -80,7 +80,7 @@ module SignatureVerification fail_with! "Verification failed for #{actor.to_log_human_identifier} #{actor.uri} using rsa-sha256 (RSASSA-PKCS1-v1_5 with SHA-256)", signed_string: compare_signed_string, signature: signature_params['signature'] rescue SignatureVerificationError => e fail_with! e.message - rescue HTTP::Error, OpenSSL::SSL::SSLError => e + rescue *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError => e fail_with! "Failed to fetch remote data: #{e.message}" rescue Mastodon::UnexpectedResponseError fail_with! 'Failed to fetch remote data (got unexpected reply from server)' diff --git a/app/controllers/media_proxy_controller.rb b/app/controllers/media_proxy_controller.rb index c4230d62c3..09a28c7e37 100644 --- a/app/controllers/media_proxy_controller.rb +++ b/app/controllers/media_proxy_controller.rb @@ -13,7 +13,7 @@ class MediaProxyController < ApplicationController rescue_from ActiveRecord::RecordInvalid, with: :not_found rescue_from Mastodon::UnexpectedResponseError, with: :not_found rescue_from Mastodon::NotPermittedError, with: :not_found - rescue_from HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError, with: :internal_server_error + rescue_from(*Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, with: :internal_server_error) def show with_redis_lock("media_download:#{params[:id]}") do diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 928803cd64..fd836f2305 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -199,7 +199,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity return if account.nil? @mentions << Mention.new(account: account, silent: false) - rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError + rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError @unresolved_mentions << tag['href'] end @@ -250,7 +250,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity media_attachment.download_file! media_attachment.download_thumbnail! media_attachment.save - rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError + rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError RedownloadMediaWorker.perform_in(rand(30..600).seconds, media_attachment.id) rescue Seahorse::Client::NetworkingError => e Rails.logger.warn "Error storing media attachment: #{e}" diff --git a/app/models/account_alias.rb b/app/models/account_alias.rb index 3b75919afe..a4a7427e24 100644 --- a/app/models/account_alias.rb +++ b/app/models/account_alias.rb @@ -35,7 +35,7 @@ class AccountAlias < ApplicationRecord def set_uri target_account = ResolveAccountService.new.call(acct) self.uri = ActivityPub::TagManager.instance.uri_for(target_account) unless target_account.nil? - rescue Webfinger::Error, HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error + rescue Webfinger::Error, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Mastodon::Error # Validation will take care of it end diff --git a/app/models/account_migration.rb b/app/models/account_migration.rb index 7a01e250e2..5df857e3ba 100644 --- a/app/models/account_migration.rb +++ b/app/models/account_migration.rb @@ -61,7 +61,7 @@ class AccountMigration < ApplicationRecord def set_target_account self.target_account = ResolveAccountService.new.call(acct, skip_cache: true) - rescue Webfinger::Error, HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error, Addressable::URI::InvalidURIError + rescue Webfinger::Error, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Mastodon::Error, Addressable::URI::InvalidURIError # Validation will take care of it end diff --git a/app/models/concerns/remotable.rb b/app/models/concerns/remotable.rb index 8382c91599..80a99b35df 100644 --- a/app/models/concerns/remotable.rb +++ b/app/models/concerns/remotable.rb @@ -26,7 +26,7 @@ module Remotable public_send(:"#{attachment_name}=", ResponseWithLimit.new(response, limit)) end - rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError => e + rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError => e Rails.logger.debug { "Error fetching remote #{attachment_name}: #{e}" } public_send(:"#{attachment_name}=", nil) if public_send(:"#{attachment_name}_file_name").present? raise e unless suppress_errors diff --git a/app/models/form/redirect.rb b/app/models/form/redirect.rb index 3cd5731e6d..ecacaa4d94 100644 --- a/app/models/form/redirect.rb +++ b/app/models/form/redirect.rb @@ -32,7 +32,7 @@ class Form::Redirect def set_target_account @target_account = ResolveAccountService.new.call(acct, skip_cache: true) - rescue Webfinger::Error, HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error, Addressable::URI::InvalidURIError + rescue Webfinger::Error, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Mastodon::Error, Addressable::URI::InvalidURIError # Validation will take care of it end diff --git a/app/models/remote_follow.rb b/app/models/remote_follow.rb index fa0586f57e..f9719b8670 100644 --- a/app/models/remote_follow.rb +++ b/app/models/remote_follow.rb @@ -66,7 +66,7 @@ class RemoteFollow def acct_resource @acct_resource ||= Webfinger.new("acct:#{acct}").perform - rescue Webfinger::Error, HTTP::ConnectionError + rescue Webfinger::Error, *Mastodon::HTTP_CONNECTION_ERRORS nil end diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index a7422b5d02..d9482efac1 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -127,13 +127,13 @@ class ActivityPub::ProcessAccountService < BaseService begin @account.avatar_remote_url = image_url('icon') || '' unless skip_download? @account.avatar = nil if @account.avatar_remote_url.blank? - rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError + rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError RedownloadAvatarWorker.perform_in(rand(30..600).seconds, @account.id) end begin @account.header_remote_url = image_url('image') || '' unless skip_download? @account.header = nil if @account.header_remote_url.blank? - rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError + rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError RedownloadHeaderWorker.perform_in(rand(30..600).seconds, @account.id) end @account.statuses_count = outbox_total_items if outbox_total_items.present? @@ -276,7 +276,7 @@ class ActivityPub::ProcessAccountService < BaseService total_items = collection.is_a?(Hash) && collection['totalItems'].present? && collection['totalItems'].is_a?(Numeric) ? collection['totalItems'] : nil has_first_page = collection.is_a?(Hash) && collection['first'].present? @collections[type] = [total_items, has_first_page] - rescue HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::LengthValidationError + rescue *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Mastodon::LengthValidationError @collections[type] = [nil, nil] end diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb index 1dbed27f28..9ec3f2b430 100644 --- a/app/services/activitypub/process_status_update_service.rb +++ b/app/services/activitypub/process_status_update_service.rb @@ -109,7 +109,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService media_attachment.download_file! if media_attachment.remote_url_previously_changed? media_attachment.download_thumbnail! if media_attachment.thumbnail_remote_url_previously_changed? media_attachment.save - rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError + rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError RedownloadMediaWorker.perform_in(rand(30..600).seconds, media_attachment.id) rescue Seahorse::Client::NetworkingError => e Rails.logger.warn "Error storing media attachment: #{e}" diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb index 7662fc1f29..bb526099d6 100644 --- a/app/services/fetch_link_card_service.rb +++ b/app/services/fetch_link_card_service.rb @@ -29,7 +29,7 @@ class FetchLinkCardService < BaseService end attach_card if @card&.persisted? - rescue HTTP::Error, OpenSSL::SSL::SSLError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, Encoding::UndefinedConversionError, ActiveRecord::RecordInvalid => e + rescue *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, Encoding::UndefinedConversionError, ActiveRecord::RecordInvalid => e Rails.logger.debug { "Error fetching link #{@original_url}: #{e}" } nil end diff --git a/app/services/fetch_resource_service.rb b/app/services/fetch_resource_service.rb index b69015a5e9..949c289b6a 100644 --- a/app/services/fetch_resource_service.rb +++ b/app/services/fetch_resource_service.rb @@ -12,7 +12,7 @@ class FetchResourceService < BaseService return if url.blank? process(url) - rescue HTTP::Error, OpenSSL::SSL::SSLError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError => e + rescue *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError => e Rails.logger.debug { "Error fetching resource #{@url}: #{e}" } nil end diff --git a/app/services/import_service.rb b/app/services/import_service.rb index 6dafb5a0bb..26fabacb96 100644 --- a/app/services/import_service.rb +++ b/app/services/import_service.rb @@ -115,7 +115,7 @@ class ImportService < BaseService next if status.nil? && ActivityPub::TagManager.instance.local_uri?(uri) status || ActivityPub::FetchRemoteStatusService.new.call(uri) - rescue HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::UnexpectedResponseError + rescue *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Mastodon::UnexpectedResponseError nil rescue => e Rails.logger.warn "Unexpected error when importing bookmark: #{e}" diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb index 1c4c7805f1..2d3c766304 100644 --- a/app/services/process_mentions_service.rb +++ b/app/services/process_mentions_service.rb @@ -44,7 +44,7 @@ class ProcessMentionsService < BaseService if mention_undeliverable?(mentioned_account) begin mentioned_account = ResolveAccountService.new.call(Regexp.last_match(1)) - rescue Webfinger::Error, HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::UnexpectedResponseError + rescue Webfinger::Error, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Mastodon::UnexpectedResponseError mentioned_account = nil end end diff --git a/app/services/software_update_check_service.rb b/app/services/software_update_check_service.rb index c8ce1753f5..b9818c8199 100644 --- a/app/services/software_update_check_service.rb +++ b/app/services/software_update_check_service.rb @@ -22,7 +22,7 @@ class SoftwareUpdateCheckService < BaseService Request.new(:get, "#{api_url}?version=#{version}").add_headers('Accept' => 'application/json', 'User-Agent' => 'Mastodon update checker').perform do |res| return Oj.load(res.body_with_limit, mode: :strict) if res.code == 200 end - rescue HTTP::Error, OpenSSL::SSL::SSLError, Oj::ParseError + rescue *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Oj::ParseError nil end diff --git a/app/services/verify_link_service.rb b/app/services/verify_link_service.rb index c4f4191e1f..af5a5e4a95 100644 --- a/app/services/verify_link_service.rb +++ b/app/services/verify_link_service.rb @@ -10,7 +10,7 @@ class VerifyLinkService < BaseService return unless link_back_present? field.mark_verified! - rescue OpenSSL::SSL::SSLError, HTTP::Error, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, IPAddr::AddressFamilyError => e + rescue OpenSSL::SSL::SSLError, *Mastodon::HTTP_CONNECTION_ERRORS, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, IPAddr::AddressFamilyError => e Rails.logger.debug { "Error fetching link #{@url}: #{e}" } nil end diff --git a/app/workers/refollow_worker.rb b/app/workers/refollow_worker.rb index 4b712d3aae..078c8502d8 100644 --- a/app/workers/refollow_worker.rb +++ b/app/workers/refollow_worker.rb @@ -21,7 +21,7 @@ class RefollowWorker # Schedule re-follow begin FollowService.new.call(follower, target_account, reblogs: reblogs, notify: notify, languages: languages, bypass_limit: true) - rescue Mastodon::NotPermittedError, ActiveRecord::RecordNotFound, Mastodon::UnexpectedResponseError, HTTP::Error, OpenSSL::SSL::SSLError + rescue Mastodon::NotPermittedError, ActiveRecord::RecordNotFound, Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError next end end diff --git a/lib/exceptions.rb b/lib/exceptions.rb index c2ff162a6e..9c32cb6dda 100644 --- a/lib/exceptions.rb +++ b/lib/exceptions.rb @@ -36,4 +36,10 @@ module Mastodon super() end end + + HTTP_CONNECTION_ERRORS = [ + HTTP::ConnectionError, + HTTP::Error, + HTTP::TimeoutError, + ].freeze end diff --git a/lib/mastodon/cli/accounts.rb b/lib/mastodon/cli/accounts.rb index 08a28e5f5c..6f0de0fd6a 100644 --- a/lib/mastodon/cli/accounts.rb +++ b/lib/mastodon/cli/accounts.rb @@ -305,7 +305,7 @@ module Mastodon::CLI begin code = Request.new(:head, account.uri).perform(&:code) - rescue HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError, Mastodon::PrivateNetworkAddressError + rescue *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Mastodon::PrivateNetworkAddressError skip_domains << account.domain end From 258dce125668ccac45d6d0958da1c841ab7cfcee Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 8 Oct 2024 10:59:51 -0400 Subject: [PATCH 113/150] Add `OpenSSL::SSL::SSLError` to http connection errors wrapper (#32307) --- app/controllers/application_controller.rb | 2 +- app/controllers/concerns/signature_verification.rb | 2 +- app/controllers/media_proxy_controller.rb | 2 +- app/lib/activitypub/activity/create.rb | 4 ++-- app/models/account_alias.rb | 2 +- app/models/account_migration.rb | 2 +- app/models/concerns/remotable.rb | 2 +- app/models/form/redirect.rb | 2 +- app/services/activitypub/process_account_service.rb | 6 +++--- app/services/activitypub/process_status_update_service.rb | 2 +- app/services/fetch_link_card_service.rb | 2 +- app/services/fetch_resource_service.rb | 2 +- app/services/import_service.rb | 2 +- app/services/process_mentions_service.rb | 2 +- app/services/software_update_check_service.rb | 2 +- app/services/verify_link_service.rb | 2 +- app/workers/refollow_worker.rb | 2 +- lib/exceptions.rb | 1 + lib/mastodon/cli/accounts.rb | 2 +- 19 files changed, 22 insertions(+), 21 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 40cae15b48..d493bd43bf 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -32,7 +32,7 @@ class ApplicationController < ActionController::Base rescue_from ActionController::InvalidAuthenticityToken, with: :unprocessable_entity rescue_from Mastodon::RateLimitExceededError, with: :too_many_requests - rescue_from(*Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, with: :internal_server_error) + rescue_from(*Mastodon::HTTP_CONNECTION_ERRORS, with: :internal_server_error) rescue_from Mastodon::RaceConditionError, Stoplight::Error::RedLight, ActiveRecord::SerializationFailure, with: :service_unavailable rescue_from Seahorse::Client::NetworkingError do |e| diff --git a/app/controllers/concerns/signature_verification.rb b/app/controllers/concerns/signature_verification.rb index 6773c11099..4ae63632c0 100644 --- a/app/controllers/concerns/signature_verification.rb +++ b/app/controllers/concerns/signature_verification.rb @@ -80,7 +80,7 @@ module SignatureVerification fail_with! "Verification failed for #{actor.to_log_human_identifier} #{actor.uri} using rsa-sha256 (RSASSA-PKCS1-v1_5 with SHA-256)", signed_string: compare_signed_string, signature: signature_params['signature'] rescue SignatureVerificationError => e fail_with! e.message - rescue *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError => e + rescue *Mastodon::HTTP_CONNECTION_ERRORS => e fail_with! "Failed to fetch remote data: #{e.message}" rescue Mastodon::UnexpectedResponseError fail_with! 'Failed to fetch remote data (got unexpected reply from server)' diff --git a/app/controllers/media_proxy_controller.rb b/app/controllers/media_proxy_controller.rb index 09a28c7e37..f68d85e44e 100644 --- a/app/controllers/media_proxy_controller.rb +++ b/app/controllers/media_proxy_controller.rb @@ -13,7 +13,7 @@ class MediaProxyController < ApplicationController rescue_from ActiveRecord::RecordInvalid, with: :not_found rescue_from Mastodon::UnexpectedResponseError, with: :not_found rescue_from Mastodon::NotPermittedError, with: :not_found - rescue_from(*Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, with: :internal_server_error) + rescue_from(*Mastodon::HTTP_CONNECTION_ERRORS, with: :internal_server_error) def show with_redis_lock("media_download:#{params[:id]}") do diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index fd836f2305..d04f7226a0 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -199,7 +199,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity return if account.nil? @mentions << Mention.new(account: account, silent: false) - rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError + rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS @unresolved_mentions << tag['href'] end @@ -250,7 +250,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity media_attachment.download_file! media_attachment.download_thumbnail! media_attachment.save - rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError + rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS RedownloadMediaWorker.perform_in(rand(30..600).seconds, media_attachment.id) rescue Seahorse::Client::NetworkingError => e Rails.logger.warn "Error storing media attachment: #{e}" diff --git a/app/models/account_alias.rb b/app/models/account_alias.rb index a4a7427e24..41623ddedb 100644 --- a/app/models/account_alias.rb +++ b/app/models/account_alias.rb @@ -35,7 +35,7 @@ class AccountAlias < ApplicationRecord def set_uri target_account = ResolveAccountService.new.call(acct) self.uri = ActivityPub::TagManager.instance.uri_for(target_account) unless target_account.nil? - rescue Webfinger::Error, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Mastodon::Error + rescue Webfinger::Error, *Mastodon::HTTP_CONNECTION_ERRORS, Mastodon::Error # Validation will take care of it end diff --git a/app/models/account_migration.rb b/app/models/account_migration.rb index 5df857e3ba..7bda388f2a 100644 --- a/app/models/account_migration.rb +++ b/app/models/account_migration.rb @@ -61,7 +61,7 @@ class AccountMigration < ApplicationRecord def set_target_account self.target_account = ResolveAccountService.new.call(acct, skip_cache: true) - rescue Webfinger::Error, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Mastodon::Error, Addressable::URI::InvalidURIError + rescue Webfinger::Error, *Mastodon::HTTP_CONNECTION_ERRORS, Mastodon::Error, Addressable::URI::InvalidURIError # Validation will take care of it end diff --git a/app/models/concerns/remotable.rb b/app/models/concerns/remotable.rb index 80a99b35df..15133e7bde 100644 --- a/app/models/concerns/remotable.rb +++ b/app/models/concerns/remotable.rb @@ -26,7 +26,7 @@ module Remotable public_send(:"#{attachment_name}=", ResponseWithLimit.new(response, limit)) end - rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError => e + rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS => e Rails.logger.debug { "Error fetching remote #{attachment_name}: #{e}" } public_send(:"#{attachment_name}=", nil) if public_send(:"#{attachment_name}_file_name").present? raise e unless suppress_errors diff --git a/app/models/form/redirect.rb b/app/models/form/redirect.rb index ecacaa4d94..c5b3c1f8f3 100644 --- a/app/models/form/redirect.rb +++ b/app/models/form/redirect.rb @@ -32,7 +32,7 @@ class Form::Redirect def set_target_account @target_account = ResolveAccountService.new.call(acct, skip_cache: true) - rescue Webfinger::Error, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Mastodon::Error, Addressable::URI::InvalidURIError + rescue Webfinger::Error, *Mastodon::HTTP_CONNECTION_ERRORS, Mastodon::Error, Addressable::URI::InvalidURIError # Validation will take care of it end diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index d9482efac1..df6f23c021 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -127,13 +127,13 @@ class ActivityPub::ProcessAccountService < BaseService begin @account.avatar_remote_url = image_url('icon') || '' unless skip_download? @account.avatar = nil if @account.avatar_remote_url.blank? - rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError + rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS RedownloadAvatarWorker.perform_in(rand(30..600).seconds, @account.id) end begin @account.header_remote_url = image_url('image') || '' unless skip_download? @account.header = nil if @account.header_remote_url.blank? - rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError + rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS RedownloadHeaderWorker.perform_in(rand(30..600).seconds, @account.id) end @account.statuses_count = outbox_total_items if outbox_total_items.present? @@ -276,7 +276,7 @@ class ActivityPub::ProcessAccountService < BaseService total_items = collection.is_a?(Hash) && collection['totalItems'].present? && collection['totalItems'].is_a?(Numeric) ? collection['totalItems'] : nil has_first_page = collection.is_a?(Hash) && collection['first'].present? @collections[type] = [total_items, has_first_page] - rescue *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Mastodon::LengthValidationError + rescue *Mastodon::HTTP_CONNECTION_ERRORS, Mastodon::LengthValidationError @collections[type] = [nil, nil] end diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb index 9ec3f2b430..141ad24e92 100644 --- a/app/services/activitypub/process_status_update_service.rb +++ b/app/services/activitypub/process_status_update_service.rb @@ -109,7 +109,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService media_attachment.download_file! if media_attachment.remote_url_previously_changed? media_attachment.download_thumbnail! if media_attachment.thumbnail_remote_url_previously_changed? media_attachment.save - rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError + rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS RedownloadMediaWorker.perform_in(rand(30..600).seconds, media_attachment.id) rescue Seahorse::Client::NetworkingError => e Rails.logger.warn "Error storing media attachment: #{e}" diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb index bb526099d6..4141fb43df 100644 --- a/app/services/fetch_link_card_service.rb +++ b/app/services/fetch_link_card_service.rb @@ -29,7 +29,7 @@ class FetchLinkCardService < BaseService end attach_card if @card&.persisted? - rescue *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, Encoding::UndefinedConversionError, ActiveRecord::RecordInvalid => e + rescue *Mastodon::HTTP_CONNECTION_ERRORS, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, Encoding::UndefinedConversionError, ActiveRecord::RecordInvalid => e Rails.logger.debug { "Error fetching link #{@original_url}: #{e}" } nil end diff --git a/app/services/fetch_resource_service.rb b/app/services/fetch_resource_service.rb index 949c289b6a..911950ccca 100644 --- a/app/services/fetch_resource_service.rb +++ b/app/services/fetch_resource_service.rb @@ -12,7 +12,7 @@ class FetchResourceService < BaseService return if url.blank? process(url) - rescue *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError => e + rescue *Mastodon::HTTP_CONNECTION_ERRORS, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError => e Rails.logger.debug { "Error fetching resource #{@url}: #{e}" } nil end diff --git a/app/services/import_service.rb b/app/services/import_service.rb index 26fabacb96..a695df2fc9 100644 --- a/app/services/import_service.rb +++ b/app/services/import_service.rb @@ -115,7 +115,7 @@ class ImportService < BaseService next if status.nil? && ActivityPub::TagManager.instance.local_uri?(uri) status || ActivityPub::FetchRemoteStatusService.new.call(uri) - rescue *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Mastodon::UnexpectedResponseError + rescue *Mastodon::HTTP_CONNECTION_ERRORS, Mastodon::UnexpectedResponseError nil rescue => e Rails.logger.warn "Unexpected error when importing bookmark: #{e}" diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb index 2d3c766304..3839eb4df4 100644 --- a/app/services/process_mentions_service.rb +++ b/app/services/process_mentions_service.rb @@ -44,7 +44,7 @@ class ProcessMentionsService < BaseService if mention_undeliverable?(mentioned_account) begin mentioned_account = ResolveAccountService.new.call(Regexp.last_match(1)) - rescue Webfinger::Error, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Mastodon::UnexpectedResponseError + rescue Webfinger::Error, *Mastodon::HTTP_CONNECTION_ERRORS, Mastodon::UnexpectedResponseError mentioned_account = nil end end diff --git a/app/services/software_update_check_service.rb b/app/services/software_update_check_service.rb index b9818c8199..24a6955b88 100644 --- a/app/services/software_update_check_service.rb +++ b/app/services/software_update_check_service.rb @@ -22,7 +22,7 @@ class SoftwareUpdateCheckService < BaseService Request.new(:get, "#{api_url}?version=#{version}").add_headers('Accept' => 'application/json', 'User-Agent' => 'Mastodon update checker').perform do |res| return Oj.load(res.body_with_limit, mode: :strict) if res.code == 200 end - rescue *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Oj::ParseError + rescue *Mastodon::HTTP_CONNECTION_ERRORS, Oj::ParseError nil end diff --git a/app/services/verify_link_service.rb b/app/services/verify_link_service.rb index af5a5e4a95..17c86426be 100644 --- a/app/services/verify_link_service.rb +++ b/app/services/verify_link_service.rb @@ -10,7 +10,7 @@ class VerifyLinkService < BaseService return unless link_back_present? field.mark_verified! - rescue OpenSSL::SSL::SSLError, *Mastodon::HTTP_CONNECTION_ERRORS, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, IPAddr::AddressFamilyError => e + rescue *Mastodon::HTTP_CONNECTION_ERRORS, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, IPAddr::AddressFamilyError => e Rails.logger.debug { "Error fetching link #{@url}: #{e}" } nil end diff --git a/app/workers/refollow_worker.rb b/app/workers/refollow_worker.rb index 078c8502d8..7b26e4a062 100644 --- a/app/workers/refollow_worker.rb +++ b/app/workers/refollow_worker.rb @@ -21,7 +21,7 @@ class RefollowWorker # Schedule re-follow begin FollowService.new.call(follower, target_account, reblogs: reblogs, notify: notify, languages: languages, bypass_limit: true) - rescue Mastodon::NotPermittedError, ActiveRecord::RecordNotFound, Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError + rescue Mastodon::NotPermittedError, ActiveRecord::RecordNotFound, Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS next end end diff --git a/lib/exceptions.rb b/lib/exceptions.rb index 9c32cb6dda..1910d37a13 100644 --- a/lib/exceptions.rb +++ b/lib/exceptions.rb @@ -41,5 +41,6 @@ module Mastodon HTTP::ConnectionError, HTTP::Error, HTTP::TimeoutError, + OpenSSL::SSL::SSLError, ].freeze end diff --git a/lib/mastodon/cli/accounts.rb b/lib/mastodon/cli/accounts.rb index 6f0de0fd6a..e76735298f 100644 --- a/lib/mastodon/cli/accounts.rb +++ b/lib/mastodon/cli/accounts.rb @@ -305,7 +305,7 @@ module Mastodon::CLI begin code = Request.new(:head, account.uri).perform(&:code) - rescue *Mastodon::HTTP_CONNECTION_ERRORS, OpenSSL::SSL::SSLError, Mastodon::PrivateNetworkAddressError + rescue *Mastodon::HTTP_CONNECTION_ERRORS, Mastodon::PrivateNetworkAddressError skip_domains << account.domain end From 7033b3476e066bda836848da20b7caa96ebaa98d Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 8 Oct 2024 19:10:59 +0200 Subject: [PATCH 114/150] Fix discrepancy with upstream regarding `latest` docker image tag (#2877) --- .github/workflows/build-security.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-security.yml b/.github/workflows/build-security.yml index e9f1862f5d..37c8ba59a3 100644 --- a/.github/workflows/build-security.yml +++ b/.github/workflows/build-security.yml @@ -32,7 +32,7 @@ jobs: labels: | org.opencontainers.image.description=Nightly build image used for testing purposes flavor: | - latest=true + latest=auto tags: | type=raw,value=edge type=raw,value=nightly @@ -53,7 +53,7 @@ jobs: labels: | org.opencontainers.image.description=Nightly build image used for testing purposes flavor: | - latest=true + latest=auto tags: | type=raw,value=edge type=raw,value=nightly From 0d91db3d77b0376cd4e17cbdb62585dfa2847fbd Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 9 Oct 2024 14:13:32 +0200 Subject: [PATCH 115/150] Fix `latest` tag for 4.3 docker image builds (#32350) --- .github/workflows/build-releases.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-releases.yml b/.github/workflows/build-releases.yml index 3f0bef32ac..da9a458282 100644 --- a/.github/workflows/build-releases.yml +++ b/.github/workflows/build-releases.yml @@ -23,7 +23,7 @@ jobs: # Only tag with latest when ran against the latest stable branch # This needs to be updated after each minor version release flavor: | - latest=${{ startsWith(github.ref, 'refs/tags/v4.2.') }} + latest=${{ startsWith(github.ref, 'refs/tags/v4.3.') }} tags: | type=pep440,pattern={{raw}} type=pep440,pattern=v{{major}}.{{minor}} From 6d6565eee720c961bfe1ef56f289f0b0a0c0fbb4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 9 Oct 2024 16:24:24 +0200 Subject: [PATCH 116/150] Update dependency express to v4.21.1 (#32336) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index 5fc15f27e0..0c62c70f92 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6392,10 +6392,10 @@ __metadata: languageName: node linkType: hard -"cookie@npm:0.6.0": - version: 0.6.0 - resolution: "cookie@npm:0.6.0" - checksum: 10c0/f2318b31af7a31b4ddb4a678d024514df5e705f9be5909a192d7f116cfb6d45cbacf96a473fa733faa95050e7cff26e7832bb3ef94751592f1387b71c8956686 +"cookie@npm:0.7.1": + version: 0.7.1 + resolution: "cookie@npm:0.7.1" + checksum: 10c0/5de60c67a410e7c8dc8a46a4b72eb0fe925871d057c9a5d2c0e8145c4270a4f81076de83410c4d397179744b478e33cd80ccbcc457abf40a9409ad27dcd21dde languageName: node linkType: hard @@ -8396,15 +8396,15 @@ __metadata: linkType: hard "express@npm:^4.17.1, express@npm:^4.18.2": - version: 4.21.0 - resolution: "express@npm:4.21.0" + version: 4.21.1 + resolution: "express@npm:4.21.1" dependencies: accepts: "npm:~1.3.8" array-flatten: "npm:1.1.1" body-parser: "npm:1.20.3" content-disposition: "npm:0.5.4" content-type: "npm:~1.0.4" - cookie: "npm:0.6.0" + cookie: "npm:0.7.1" cookie-signature: "npm:1.0.6" debug: "npm:2.6.9" depd: "npm:2.0.0" @@ -8430,7 +8430,7 @@ __metadata: type-is: "npm:~1.6.18" utils-merge: "npm:1.0.1" vary: "npm:~1.1.2" - checksum: 10c0/4cf7ca328f3fdeb720f30ccb2ea7708bfa7d345f9cc460b64a82bf1b2c91e5b5852ba15a9a11b2a165d6089acf83457fc477dc904d59cd71ed34c7a91762c6cc + checksum: 10c0/0c287867e5f6129d3def1edd9b63103a53c40d4dc8628839d4b6827e35eb8f0de5a4656f9d85f4457eba584f9871ebb2ad26c750b36bd75d9bbb8bcebdc4892c languageName: node linkType: hard From c574f5b53fd13d2668a3730f7d3257fdafca0220 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 9 Oct 2024 18:36:19 +0200 Subject: [PATCH 117/150] Change how migrations duplicated between glitch and upstream are handled (#2878) --- config/initializers/0_duplicate_migrations.rb | 56 ------------------- ...20180410220657_glitch_create_bookmarks.rb} | 11 ++-- db/migrate/20180831171112_create_bookmarks.rb | 11 +++- 3 files changed, 15 insertions(+), 63 deletions(-) delete mode 100644 config/initializers/0_duplicate_migrations.rb rename db/migrate/{20180410220657_create_bookmarks.rb => 20180410220657_glitch_create_bookmarks.rb} (70%) diff --git a/config/initializers/0_duplicate_migrations.rb b/config/initializers/0_duplicate_migrations.rb deleted file mode 100644 index f993571877..0000000000 --- a/config/initializers/0_duplicate_migrations.rb +++ /dev/null @@ -1,56 +0,0 @@ -# frozen_string_literal: true - -# Some migrations have been present in glitch-soc for a long time and have then -# been merged in upstream Mastodon, under a different version number. -# -# This puts us in an uneasy situation in which if we remove upstream's -# migration file, people migrating from upstream will end up having a conflict -# with their already-ran migration. -# -# On the other hand, if we keep upstream's migration and remove our own, -# any current glitch-soc user will have a conflict during migration. -# -# For lack of a better solution, as those migrations are indeed identical, -# we decided monkey-patching Rails' Migrator to completely ignore the duplicate, -# keeping only the one that has run, or an arbitrary one. - -ALLOWED_DUPLICATES = [2018_04_10_220657, 2018_08_31_171112].freeze - -module ActiveRecord - class Migrator - def self.new(direction, migrations, schema_migration, internal_metadata, target_version = nil) - migrated = Set.new(Base.connection.migration_context.get_all_versions) - - migrations.group_by(&:name).each_value do |duplicates| - next unless duplicates.length > 1 && duplicates.all? { |m| ALLOWED_DUPLICATES.include?(m.version) } - - # We have a set of allowed duplicates. Keep the migrated one, if any. - non_migrated = duplicates.reject { |m| migrated.include?(m.version.to_i) } - - migrations = begin - if duplicates.length == non_migrated.length || non_migrated.empty? - # There weren't any migrated one, so we have to pick one “canonical” migration - migrations - duplicates[1..] - else - # Just reject every duplicate which hasn't been migrated yet - migrations - non_migrated - end - end - end - - super - end - end - - class MigrationContext - def needs_migration? - # A set of duplicated migrations is considered migrated if at least one of - # them is migrated. - migrated = get_all_versions - migrations.group_by(&:name).each_value do |duplicates| - return true unless duplicates.any? { |m| migrated.include?(m.version.to_i) } - end - false - end - end -end diff --git a/db/migrate/20180410220657_create_bookmarks.rb b/db/migrate/20180410220657_glitch_create_bookmarks.rb similarity index 70% rename from db/migrate/20180410220657_create_bookmarks.rb rename to db/migrate/20180410220657_glitch_create_bookmarks.rb index aba21f5eaa..5a2e0d35e5 100644 --- a/db/migrate/20180410220657_create_bookmarks.rb +++ b/db/migrate/20180410220657_glitch_create_bookmarks.rb @@ -1,10 +1,11 @@ # frozen_string_literal: true -# This migration is a duplicate of 20180831171112 and may get ignored, see -# config/initializers/0_duplicate_migrations.rb +# This migration is a duplicate of 20180831171112 + +class GlitchCreateBookmarks < ActiveRecord::Migration[5.1] + def up + return if table_exists?(:bookmarks) -class CreateBookmarks < ActiveRecord::Migration[5.1] - def change create_table :bookmarks do |t| t.references :account, null: false t.references :status, null: false @@ -19,4 +20,6 @@ class CreateBookmarks < ActiveRecord::Migration[5.1] add_index :bookmarks, [:account_id, :status_id], unique: true end + + def down; end end diff --git a/db/migrate/20180831171112_create_bookmarks.rb b/db/migrate/20180831171112_create_bookmarks.rb index 4fa4c323d6..88fb75a597 100644 --- a/db/migrate/20180831171112_create_bookmarks.rb +++ b/db/migrate/20180831171112_create_bookmarks.rb @@ -1,10 +1,11 @@ # frozen_string_literal: true -# This migration is a duplicate of 20180410220657 and may get ignored, see -# config/initializers/0_duplicate_migrations.rb +# This migration is a duplicate of 20180410220657 class CreateBookmarks < ActiveRecord::Migration[5.2] - def change + def up + return if table_exists?(:bookmarks) + create_table :bookmarks do |t| t.references :account, null: false t.references :status, null: false @@ -19,4 +20,8 @@ class CreateBookmarks < ActiveRecord::Migration[5.2] add_index :bookmarks, [:account_id, :status_id], unique: true end + + def down + drop_table :bookmarks + end end From fda52b2a521af9b743d97ae35964ec6fc0e97879 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 9 Oct 2024 19:16:57 +0200 Subject: [PATCH 118/150] Fix 4 columns barely not fitting on 1920px screen (#32361) --- app/javascript/styles/mastodon/components.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 4ed05ead3f..6e386ff687 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -2863,7 +2863,7 @@ $ui-header-logo-wordmark-width: 99px; } .column { - width: 400px; + width: clamp(380px, calc((100% - 350px) / 4), 400px); position: relative; box-sizing: border-box; display: flex; From 03dbebdfef47eda19b1b86e56004119f723e667e Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 9 Oct 2024 19:24:22 +0200 Subject: [PATCH 119/150] Fix list edition modal styling (#32358) --- .../styles/mastodon/components.scss | 111 ++++++++---------- 1 file changed, 50 insertions(+), 61 deletions(-) diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 6e386ff687..78e5290139 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -7961,7 +7961,6 @@ noscript { justify-content: flex-start; gap: 15px; align-items: center; - border: 1px solid var(--background-border-color); border-top: 0; label { @@ -7988,79 +7987,23 @@ noscript { background: rgba($base-overlay-background, 0.5); } +.list-adder, .list-editor { - background: $ui-base-color; + backdrop-filter: var(--background-filter); + background: var(--modal-background-color); + border: 1px solid var(--modal-border-color); flex-direction: column; border-radius: 8px; - box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4); width: 380px; overflow: hidden; @media screen and (width <= 420px) { width: 90%; } - - h4 { - padding: 15px 0; - background: lighten($ui-base-color, 13%); - font-weight: 500; - font-size: 16px; - text-align: center; - border-radius: 8px 8px 0 0; - } - - .drawer__pager { - height: 50vh; - border-radius: 4px; - } - - .drawer__inner { - border-radius: 0 0 8px 8px; - - &.backdrop { - width: calc(100% - 60px); - box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4); - border-radius: 0 0 0 8px; - } - } - - &__accounts { - overflow-y: auto; - } - - .account__display-name { - &:hover strong { - text-decoration: none; - } - } - - .account__avatar { - cursor: default; - } - - .search { - margin-bottom: 0; - } } .list-adder { - background: $ui-base-color; - flex-direction: column; - border-radius: 8px; - box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4); - width: 380px; - overflow: hidden; - - @media screen and (width <= 420px) { - width: 90%; - } - - &__account { - background: lighten($ui-base-color, 13%); - } - &__lists { - background: lighten($ui-base-color, 13%); height: 50vh; border-radius: 0 0 8px 8px; overflow-y: auto; @@ -8081,6 +8024,52 @@ noscript { text-decoration: none; font-size: 16px; padding: 10px; + display: flex; + align-items: center; + gap: 4px; + } +} + +.list-editor { + h4 { + padding: 15px 0; + background: lighten($ui-base-color, 13%); + font-weight: 500; + font-size: 16px; + text-align: center; + border-radius: 8px 8px 0 0; + } + + .drawer__pager { + height: 50vh; + border: 0; + } + + .drawer__inner { + &.backdrop { + width: calc(100% - 60px); + box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4); + border-radius: 0 0 0 8px; + } + } + + &__accounts { + background: unset; + overflow-y: auto; + } + + .account__display-name { + &:hover strong { + text-decoration: none; + } + } + + .account__avatar { + cursor: default; + } + + .search { + margin-bottom: 0; } } From d9fbb071da1904f3a4da90d055368f47b174224c Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 9 Oct 2024 19:29:02 +0200 Subject: [PATCH 120/150] Fix notification requests from suspended accounts still being listed (#32354) --- .../v1/notifications/requests_controller.rb | 2 +- app/models/notification_policy.rb | 2 +- app/models/notification_request.rb | 2 ++ spec/models/notification_policy_spec.rb | 18 ++++++++++++------ 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/app/controllers/api/v1/notifications/requests_controller.rb b/app/controllers/api/v1/notifications/requests_controller.rb index 36ee073b9c..3c90f13ce2 100644 --- a/app/controllers/api/v1/notifications/requests_controller.rb +++ b/app/controllers/api/v1/notifications/requests_controller.rb @@ -52,7 +52,7 @@ class Api::V1::Notifications::RequestsController < Api::BaseController private def load_requests - requests = NotificationRequest.where(account: current_account).includes(:last_status, from_account: [:account_stat, :user]).to_a_paginated_by_id( + requests = NotificationRequest.where(account: current_account).without_suspended.includes(:last_status, from_account: [:account_stat, :user]).to_a_paginated_by_id( limit_param(DEFAULT_ACCOUNTS_LIMIT), params_slice(:max_id, :since_id, :min_id) ) diff --git a/app/models/notification_policy.rb b/app/models/notification_policy.rb index 3b16f33d88..d22f871a37 100644 --- a/app/models/notification_policy.rb +++ b/app/models/notification_policy.rb @@ -62,6 +62,6 @@ class NotificationPolicy < ApplicationRecord private def pending_notification_requests - @pending_notification_requests ||= notification_requests.limit(MAX_MEANINGFUL_COUNT).pick(Arel.sql('count(*), coalesce(sum(notifications_count), 0)::bigint')) + @pending_notification_requests ||= notification_requests.without_suspended.limit(MAX_MEANINGFUL_COUNT).pick(Arel.sql('count(*), coalesce(sum(notifications_count), 0)::bigint')) end end diff --git a/app/models/notification_request.rb b/app/models/notification_request.rb index f0778b3af3..eb9ff93ab7 100644 --- a/app/models/notification_request.rb +++ b/app/models/notification_request.rb @@ -26,6 +26,8 @@ class NotificationRequest < ApplicationRecord before_save :prepare_notifications_count + scope :without_suspended, -> { joins(:from_account).merge(Account.without_suspended) } + def self.preload_cache_collection(requests) cached_statuses_by_id = yield(requests.filter_map(&:last_status)).index_by(&:id) # Call cache_collection in block diff --git a/spec/models/notification_policy_spec.rb b/spec/models/notification_policy_spec.rb index 02a582bb08..7d1b494dd5 100644 --- a/spec/models/notification_policy_spec.rb +++ b/spec/models/notification_policy_spec.rb @@ -7,19 +7,25 @@ RSpec.describe NotificationPolicy do subject { Fabricate(:notification_policy) } let(:sender) { Fabricate(:account) } + let(:suspended_sender) { Fabricate(:account) } before do Fabricate.times(2, :notification, account: subject.account, activity: Fabricate(:status, account: sender), filtered: true, type: :mention) Fabricate(:notification_request, account: subject.account, from_account: sender) + + Fabricate(:notification, account: subject.account, activity: Fabricate(:status, account: suspended_sender), filtered: true, type: :mention) + Fabricate(:notification_request, account: subject.account, from_account: suspended_sender) + + suspended_sender.suspend! + subject.summarize! end - it 'sets pending_requests_count' do - expect(subject.pending_requests_count).to eq 1 - end - - it 'sets pending_notifications_count' do - expect(subject.pending_notifications_count).to eq 2 + it 'sets pending_requests_count and pending_notifications_count' do + expect(subject).to have_attributes( + pending_requests_count: 1, + pending_notifications_count: 2 + ) end end end From cdf603239e8bc78b4f7c06e3df96da6e6d7c7a57 Mon Sep 17 00:00:00 2001 From: Michael Stanclift Date: Wed, 9 Oct 2024 14:33:28 -0500 Subject: [PATCH 121/150] Restore list column border (#32367) --- app/javascript/styles/mastodon/components.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 78e5290139..1f69dab7be 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -7961,6 +7961,7 @@ noscript { justify-content: flex-start; gap: 15px; align-items: center; + border: 1px solid var(--background-border-color); border-top: 0; label { From a5a3733c9772424c29735b2ae1542e270186d24c Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 10 Oct 2024 13:04:38 +0200 Subject: [PATCH 122/150] =?UTF-8?q?Fix=20=E2=80=9CMention=E2=80=9D=20appea?= =?UTF-8?q?ring=20for=20otherwise=20filtered=20posts=20(#32356)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/notification_with_status.tsx | 9 +++- app/javascript/mastodon/selectors/filters.ts | 50 +++++++++++++++++++ app/javascript/mastodon/selectors/index.js | 15 +----- 3 files changed, 60 insertions(+), 14 deletions(-) create mode 100644 app/javascript/mastodon/selectors/filters.ts diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_with_status.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_with_status.tsx index a1c275a1f3..3e6428287d 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/notification_with_status.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_with_status.tsx @@ -13,6 +13,7 @@ import { import type { IconProp } from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon'; import Status from 'mastodon/containers/status_container'; +import { getStatusHidden } from 'mastodon/selectors/filters'; import { useAppSelector, useAppDispatch } from 'mastodon/store'; import { DisplayedName } from './displayed_name'; @@ -48,6 +49,12 @@ export const NotificationWithStatus: React.FC<{ (state) => state.statuses.getIn([statusId, 'visibility']) === 'direct', ); + const isFiltered = useAppSelector( + (state) => + statusId && + getStatusHidden(state, { id: statusId, contextType: 'notifications' }), + ); + const handlers = useMemo( () => ({ open: () => { @@ -73,7 +80,7 @@ export const NotificationWithStatus: React.FC<{ [dispatch, statusId], ); - if (!statusId) return null; + if (!statusId || isFiltered) return null; return ( diff --git a/app/javascript/mastodon/selectors/filters.ts b/app/javascript/mastodon/selectors/filters.ts new file mode 100644 index 0000000000..f84d01216a --- /dev/null +++ b/app/javascript/mastodon/selectors/filters.ts @@ -0,0 +1,50 @@ +import { createSelector } from '@reduxjs/toolkit'; + +import type { RootState } from 'mastodon/store'; +import { toServerSideType } from 'mastodon/utils/filters'; + +// TODO: move to `app/javascript/mastodon/models` and use more globally +type Filter = Immutable.Map; + +// TODO: move to `app/javascript/mastodon/models` and use more globally +type FilterResult = Immutable.Map; + +export const getFilters = createSelector( + [ + (state: RootState) => state.filters as Immutable.Map, + (_, { contextType }: { contextType: string }) => contextType, + ], + (filters, contextType) => { + if (!contextType) { + return null; + } + + const now = new Date(); + const serverSideType = toServerSideType(contextType); + + return filters.filter((filter) => { + const context = filter.get('context') as Immutable.List; + const expiration = filter.get('expires_at') as Date | null; + return ( + context.includes(serverSideType) && + (expiration === null || expiration > now) + ); + }); + }, +); + +export const getStatusHidden = ( + state: RootState, + { id, contextType }: { id: string; contextType: string }, +) => { + const filters = getFilters(state, { contextType }); + if (filters === null) return false; + + const filtered = state.statuses.getIn([id, 'filtered']) as + | Immutable.List + | undefined; + return filtered?.some( + (result) => + filters.getIn([result.get('filter'), 'filter_action']) === 'hide', + ); +}; diff --git a/app/javascript/mastodon/selectors/index.js b/app/javascript/mastodon/selectors/index.js index 10e1b167ca..345ceac49a 100644 --- a/app/javascript/mastodon/selectors/index.js +++ b/app/javascript/mastodon/selectors/index.js @@ -1,23 +1,12 @@ import { createSelector } from '@reduxjs/toolkit'; import { List as ImmutableList, Map as ImmutableMap } from 'immutable'; -import { toServerSideType } from 'mastodon/utils/filters'; - import { me } from '../initial_state'; +import { getFilters } from './filters'; + export { makeGetAccount } from "./accounts"; -const getFilters = createSelector([state => state.get('filters'), (_, { contextType }) => contextType], (filters, contextType) => { - if (!contextType) { - return null; - } - - const now = new Date(); - const serverSideType = toServerSideType(contextType); - - return filters.filter(filter => filter.get('context').includes(serverSideType) && (filter.get('expires_at') === null || filter.get('expires_at') > now)); -}); - export const makeGetStatus = () => { return createSelector( [ From 9350cd31d74486c0b6a523f497a353350792b955 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 13:21:48 +0000 Subject: [PATCH 123/150] Update dependency postcss-preset-env to v10.0.7 (#32389) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 388 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 199 insertions(+), 189 deletions(-) diff --git a/yarn.lock b/yarn.lock index 0c62c70f92..548d94fc2e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1533,13 +1533,13 @@ __metadata: languageName: node linkType: hard -"@csstools/cascade-layer-name-parser@npm:^2.0.1": - version: 2.0.1 - resolution: "@csstools/cascade-layer-name-parser@npm:2.0.1" +"@csstools/cascade-layer-name-parser@npm:^2.0.2": + version: 2.0.2 + resolution: "@csstools/cascade-layer-name-parser@npm:2.0.2" peerDependencies: - "@csstools/css-parser-algorithms": ^3.0.1 - "@csstools/css-tokenizer": ^3.0.1 - checksum: 10c0/e1f9030285d1a16ca0424018289e5288e58dee2d6f6cc392e27d9e8eca0deeea4ced9b749eef09a8322746cb15b6304bc7e2d04bb9dc7405c29b3717ec80e736 + "@csstools/css-parser-algorithms": ^3.0.2 + "@csstools/css-tokenizer": ^3.0.2 + checksum: 10c0/2cc840445328400bb3e1e4186e6081e6519a23d9abde36a16c95892b6ad75155b3af3410d79fdda1c53a068384f970cabff4b5f5ba6867578168cbd3419016c8 languageName: node linkType: hard @@ -1550,42 +1550,42 @@ __metadata: languageName: node linkType: hard -"@csstools/css-calc@npm:^2.0.1": - version: 2.0.1 - resolution: "@csstools/css-calc@npm:2.0.1" +"@csstools/css-calc@npm:^2.0.2": + version: 2.0.2 + resolution: "@csstools/css-calc@npm:2.0.2" peerDependencies: - "@csstools/css-parser-algorithms": ^3.0.1 - "@csstools/css-tokenizer": ^3.0.1 - checksum: 10c0/84c0ba3dac51466c9ac22c3540360f6058cf351a3676d71d4412584b165a91abc7c69a4ddf5a5dacc6e6082806d2317cf50ddbc0a0562275b2aedaee41cb87a9 + "@csstools/css-parser-algorithms": ^3.0.2 + "@csstools/css-tokenizer": ^3.0.2 + checksum: 10c0/b36e655b4abc8ea39b300725e33cd43b1875d759dd60bee8155bf7841065615a7f24cf53199382e30aa10bb137f64021043e4af7e11b7199b674a6e6cf3ccd01 languageName: node linkType: hard -"@csstools/css-color-parser@npm:^3.0.2": - version: 3.0.2 - resolution: "@csstools/css-color-parser@npm:3.0.2" +"@csstools/css-color-parser@npm:^3.0.3": + version: 3.0.3 + resolution: "@csstools/css-color-parser@npm:3.0.3" dependencies: "@csstools/color-helpers": "npm:^5.0.1" - "@csstools/css-calc": "npm:^2.0.1" + "@csstools/css-calc": "npm:^2.0.2" peerDependencies: - "@csstools/css-parser-algorithms": ^3.0.1 - "@csstools/css-tokenizer": ^3.0.1 - checksum: 10c0/31f42cc22426c937f5c6999889f72b40aec8504189a6badf3319552f27a5af73dd5f46be9ebc54eb87e526468eb2546ffbd60a6879fe599efa6c98e51d6cfa3d + "@csstools/css-parser-algorithms": ^3.0.2 + "@csstools/css-tokenizer": ^3.0.2 + checksum: 10c0/02367ffc222254132c47f9cbc856f65fe0b81ee4a5e7381251b95c4064138b5ed99a5e5a79c0c8689f9e75e3d900f94773258a161a97f467c3f0420838c10e04 languageName: node linkType: hard -"@csstools/css-parser-algorithms@npm:^3.0.1": - version: 3.0.1 - resolution: "@csstools/css-parser-algorithms@npm:3.0.1" +"@csstools/css-parser-algorithms@npm:^3.0.1, @csstools/css-parser-algorithms@npm:^3.0.2": + version: 3.0.2 + resolution: "@csstools/css-parser-algorithms@npm:3.0.2" peerDependencies: - "@csstools/css-tokenizer": ^3.0.1 - checksum: 10c0/064c6d519197b5af43bbf5efe8f4cdbd361b006113aa82160d637e925b50c643a52d33d512ca01c63042d952d723a2a10798231a714668356b76668fb11294e3 + "@csstools/css-tokenizer": ^3.0.2 + checksum: 10c0/246afbf518ee9eaa24ed7f083360eb66884f1172fd4f8c663bff8c6099de2a8abd1e2a31d5b6fe42e010277d238469d780cff62bc7fdc6a52e7a90626b8924dc languageName: node linkType: hard -"@csstools/css-tokenizer@npm:^3.0.1": - version: 3.0.1 - resolution: "@csstools/css-tokenizer@npm:3.0.1" - checksum: 10c0/c9ed4373e5731b5375ea9791590081019c04e95f08b46b272977e5e7b8c3d560affc62e82263cb8def1df1e57f0673140e7e16a14a5e7be04e6a234be088d1d3 +"@csstools/css-tokenizer@npm:^3.0.1, @csstools/css-tokenizer@npm:^3.0.2": + version: 3.0.2 + resolution: "@csstools/css-tokenizer@npm:3.0.2" + checksum: 10c0/a74e5829420ed35982fd33be272c2a19cb2380179d357abe750aa848be6d6699d0437008f47a57eb7c6ff64a34b0c8f91a97dd63dbddd08249b7cf7983767e5e languageName: node linkType: hard @@ -1599,6 +1599,16 @@ __metadata: languageName: node linkType: hard +"@csstools/media-query-list-parser@npm:^4.0.0": + version: 4.0.0 + resolution: "@csstools/media-query-list-parser@npm:4.0.0" + peerDependencies: + "@csstools/css-parser-algorithms": ^3.0.2 + "@csstools/css-tokenizer": ^3.0.2 + checksum: 10c0/416417bcfd84c18a2df8dc77f31c87830e151dc20530fe7f0d8f13a0848b1a9090858abdf7792d82bf2edb41ddedb7b57b34eb78b68b5c10755ae02c019e496a + languageName: node + linkType: hard + "@csstools/postcss-cascade-layers@npm:^5.0.0": version: 5.0.0 resolution: "@csstools/postcss-cascade-layers@npm:5.0.0" @@ -1611,60 +1621,60 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-color-function@npm:^4.0.2": - version: 4.0.2 - resolution: "@csstools/postcss-color-function@npm:4.0.2" +"@csstools/postcss-color-function@npm:^4.0.3": + version: 4.0.3 + resolution: "@csstools/postcss-color-function@npm:4.0.3" dependencies: - "@csstools/css-color-parser": "npm:^3.0.2" - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/css-color-parser": "npm:^3.0.3" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/c987ccc7ab326668895396d3fe69c05087cf6e245be6f70e8c33da0cdeb56f8ac3d117cfad984191ec57be9691ab56d427aaa28c61c4a7446521972993dd5039 + checksum: 10c0/c994660ca0e2652755d9ad181c8cb46a07220c972086c97c843fa9bacf690be10c642770f898aeec4acc47c2b718dfc7372107285a678361f34d84d9e9c11e0c languageName: node linkType: hard -"@csstools/postcss-color-mix-function@npm:^3.0.2": - version: 3.0.2 - resolution: "@csstools/postcss-color-mix-function@npm:3.0.2" +"@csstools/postcss-color-mix-function@npm:^3.0.3": + version: 3.0.3 + resolution: "@csstools/postcss-color-mix-function@npm:3.0.3" dependencies: - "@csstools/css-color-parser": "npm:^3.0.2" - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/css-color-parser": "npm:^3.0.3" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/cfdc641f504f9d02b9a7b53d6bd933d4e767ecaee5f3d2df45d897f69b8a38b5b79b538d307b16fb56dcb7c19dc7e107518c356772e89771e28e04fd846d9035 + checksum: 10c0/4ba358eb9030fc485bfe2922d897eeb712725762cc399eaba60ba665c84dc3e56a4d5a52dfb320093c0b217d32fedb9b5197fa45738cade53d9afcbefdadf04f languageName: node linkType: hard -"@csstools/postcss-content-alt-text@npm:^2.0.1": - version: 2.0.1 - resolution: "@csstools/postcss-content-alt-text@npm:2.0.1" +"@csstools/postcss-content-alt-text@npm:^2.0.2": + version: 2.0.2 + resolution: "@csstools/postcss-content-alt-text@npm:2.0.2" dependencies: - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/693e4cfa9a30a9c384120bd24846a7cd5ba1e1ebf975eb81b0e0131a21ac28a0301c7dcfa13706bc7d8b5343536fb43a46de636c3257d0fd05041c7255366e87 + checksum: 10c0/e52d40f6567b9b23b32a6c40f9b2a74d57f99a9921b4cae015f51f72453474236c760bb13120682f8815698a615e0ad7bed22314c29dca89c34b5480d83a7a6d languageName: node linkType: hard -"@csstools/postcss-exponential-functions@npm:^2.0.1": - version: 2.0.1 - resolution: "@csstools/postcss-exponential-functions@npm:2.0.1" +"@csstools/postcss-exponential-functions@npm:^2.0.2": + version: 2.0.2 + resolution: "@csstools/postcss-exponential-functions@npm:2.0.2" dependencies: - "@csstools/css-calc": "npm:^2.0.1" - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/css-calc": "npm:^2.0.2" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" peerDependencies: postcss: ^8.4 - checksum: 10c0/ddcaedfa48cc0cf93611c8d2ed5a75d56c1d196a97015db644b45881adabb47f3255242acaef6ea869a1e5ba66328725d254bf6d29eb5e988cde8b040bc5f55d + checksum: 10c0/034ff89089872f63a6b00bda670c5ff11361babd221ed3e441dde969a718059e5d44ab0ed331868f137bb205331b808ecbcc4cb641d5c945238ebca28aa3ed59 languageName: node linkType: hard @@ -1680,46 +1690,46 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-gamut-mapping@npm:^2.0.2": - version: 2.0.2 - resolution: "@csstools/postcss-gamut-mapping@npm:2.0.2" +"@csstools/postcss-gamut-mapping@npm:^2.0.3": + version: 2.0.3 + resolution: "@csstools/postcss-gamut-mapping@npm:2.0.3" dependencies: - "@csstools/css-color-parser": "npm:^3.0.2" - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/css-color-parser": "npm:^3.0.3" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" peerDependencies: postcss: ^8.4 - checksum: 10c0/8b6504f81c5036e3c2a9f9516c371f48a283112469b746546c8c7f6f0da2467c915d4dac6dfe8bb05d7dab3a7503911391eb9e666cb7632e09a032e801c029f5 + checksum: 10c0/21f5708f63e9c3b7603f8b72b5f288e0a021e9710a6abf4aaa713ff4d04bae057d1861e1f28d7670ea39ba463ac04f1507876d4a11178934e7cc7a1c6a780084 languageName: node linkType: hard -"@csstools/postcss-gradients-interpolation-method@npm:^5.0.2": - version: 5.0.2 - resolution: "@csstools/postcss-gradients-interpolation-method@npm:5.0.2" +"@csstools/postcss-gradients-interpolation-method@npm:^5.0.3": + version: 5.0.3 + resolution: "@csstools/postcss-gradients-interpolation-method@npm:5.0.3" dependencies: - "@csstools/css-color-parser": "npm:^3.0.2" - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/css-color-parser": "npm:^3.0.3" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/4fa27437ad9861b1457c28228f2503c17bcc2f77dcb38da1314a4a5d38fd010e7e5d11b5f9d69e0a2cb2999bbfeca1e99ce2f59422bda5b382658dcb03f7326e + checksum: 10c0/062d27148438309c940a1973bfc7d42a06caa9397bf2382c7a61979f5be3d6f3fae1bc8ddf94d2dd8e6c807e0530a9e76179510266aaddc439677bf79447a765 languageName: node linkType: hard -"@csstools/postcss-hwb-function@npm:^4.0.2": - version: 4.0.2 - resolution: "@csstools/postcss-hwb-function@npm:4.0.2" +"@csstools/postcss-hwb-function@npm:^4.0.3": + version: 4.0.3 + resolution: "@csstools/postcss-hwb-function@npm:4.0.3" dependencies: - "@csstools/css-color-parser": "npm:^3.0.2" - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/css-color-parser": "npm:^3.0.3" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/46dc9596e37830de4c38f70764d6da9f2fc7bc339217b4291eced75daa8998c4e05fb743c271701e44818df4ac111c285019b7bb3a728e8b61d86899bbeb74eb + checksum: 10c0/faf2bfbafeec765391e37c7a5cbc7b4647d9ab1ffa51e922c7dfffa545c3d436d15604dfdfb9d7684e760042e62bb42e0243dd4ebd8c3c14694a9f7be4e57b30 languageName: node linkType: hard @@ -1757,17 +1767,17 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-light-dark-function@npm:^2.0.4": - version: 2.0.4 - resolution: "@csstools/postcss-light-dark-function@npm:2.0.4" +"@csstools/postcss-light-dark-function@npm:^2.0.5": + version: 2.0.5 + resolution: "@csstools/postcss-light-dark-function@npm:2.0.5" dependencies: - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/0176422ad9747953964b1ceff002df1ecb1952ebc481db6192070d68777135b582ea6fd32ae819b9c64c96cb9170bd6907c647c85b48daa4984b7ed3d7f9bccb + checksum: 10c0/80635ee312d2a8f42aa5ce6792f1dc4a71199c384c66a3270d37e998d96db55beaa6836d689cda3b7e4828227960582fae04659ba5e4e0f64fd4543cbf15c6ab languageName: node linkType: hard @@ -1809,42 +1819,42 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-logical-viewport-units@npm:^3.0.1": - version: 3.0.1 - resolution: "@csstools/postcss-logical-viewport-units@npm:3.0.1" +"@csstools/postcss-logical-viewport-units@npm:^3.0.2": + version: 3.0.2 + resolution: "@csstools/postcss-logical-viewport-units@npm:3.0.2" dependencies: - "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/css-tokenizer": "npm:^3.0.2" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/f54f91ec4d308562371576e82131c3cc1ff461a951c9a38f0b42b783c26f37a93cc846fcd025d3c4a8437b55a4fff1192ebfac8ccf84abb6478b2c515d232552 + checksum: 10c0/31f525e774bc053f545a159eb53bb21465ea2930118e87c40207ad90fa97d3151e6de83efd02f84803fb0e93ed4a4b42a3904b734423410e73ac4c6ce9666ab4 languageName: node linkType: hard -"@csstools/postcss-media-minmax@npm:^2.0.1": - version: 2.0.1 - resolution: "@csstools/postcss-media-minmax@npm:2.0.1" +"@csstools/postcss-media-minmax@npm:^2.0.2": + version: 2.0.2 + resolution: "@csstools/postcss-media-minmax@npm:2.0.2" dependencies: - "@csstools/css-calc": "npm:^2.0.1" - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" - "@csstools/media-query-list-parser": "npm:^3.0.1" + "@csstools/css-calc": "npm:^2.0.2" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" + "@csstools/media-query-list-parser": "npm:^4.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/23c1fb0c3ed8bf82f3223f161d0d65ba62045b917bc19624581f64aaa5d678485d22c23af2591a3f634ba02030ccb419c2b30209aa22f9fd2baa1a6474af810a + checksum: 10c0/83cf10742884fca3baa7ae26e2cb34123ce5a022622390566c139b4587ea8583fab00acbb85545786b36398e2201d2a94301e0fae805e55f375f1b5c38f67ce8 languageName: node linkType: hard -"@csstools/postcss-media-queries-aspect-ratio-number-values@npm:^3.0.1": - version: 3.0.1 - resolution: "@csstools/postcss-media-queries-aspect-ratio-number-values@npm:3.0.1" +"@csstools/postcss-media-queries-aspect-ratio-number-values@npm:^3.0.2": + version: 3.0.2 + resolution: "@csstools/postcss-media-queries-aspect-ratio-number-values@npm:3.0.2" dependencies: - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" - "@csstools/media-query-list-parser": "npm:^3.0.1" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" + "@csstools/media-query-list-parser": "npm:^4.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/e491cb149fb4fff85b2f03191511e43654ae00716e3c1ea9f1dc22ec4e7042c35f034d372082a69d3621c86cafbe46e8f419872fa36f4a534f145f584d655768 + checksum: 10c0/3ac4073d2e958bfb24ae45f673070dd805f0fcf07bc8d00a9a98f596d1096e7be282c8d8e87df3abde90f33fcbe2c7705e972b8c1a58e43ec44729f470b76096 languageName: node linkType: hard @@ -1871,18 +1881,18 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-oklab-function@npm:^4.0.2": - version: 4.0.2 - resolution: "@csstools/postcss-oklab-function@npm:4.0.2" +"@csstools/postcss-oklab-function@npm:^4.0.3": + version: 4.0.3 + resolution: "@csstools/postcss-oklab-function@npm:4.0.3" dependencies: - "@csstools/css-color-parser": "npm:^3.0.2" - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/css-color-parser": "npm:^3.0.3" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/3209a7cec6d3577544a7ef41f2d5cca25f77891d4ec0d7f39d32f9a79a6c9a9b0ee6b54b2937a2d995548ad11c39966b07d4b9f58e907ffbe1a4b454f2d277f3 + checksum: 10c0/650bcb4f664308972588a8f789f806d63c4069e2e008cfc3b5c80bf9df992c62972dce279b8f434c7f78823e97095942ee4f0e37bc549258887213e72acb7ef8 languageName: node linkType: hard @@ -1897,18 +1907,18 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-relative-color-syntax@npm:^3.0.2": - version: 3.0.2 - resolution: "@csstools/postcss-relative-color-syntax@npm:3.0.2" +"@csstools/postcss-relative-color-syntax@npm:^3.0.3": + version: 3.0.3 + resolution: "@csstools/postcss-relative-color-syntax@npm:3.0.3" dependencies: - "@csstools/css-color-parser": "npm:^3.0.2" - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/css-color-parser": "npm:^3.0.3" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/34a8c999e08c6e7833484ee2fb91e7fcc25235d6c361712fed581e44a5a29f1ceb95415b6f4260de53809ac13f5da5415d1905c2971477cf5d45e5196081c663 + checksum: 10c0/c241fe6b725d775f6d2085be1dff3868d189b176fa91ab1eb1133e30e30c8151bded4e50d17a845edd0bdd0a7adf9e8883cb2634fea3394872591fe9ad2a7e86 languageName: node linkType: hard @@ -1923,16 +1933,16 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-stepped-value-functions@npm:^4.0.1": - version: 4.0.1 - resolution: "@csstools/postcss-stepped-value-functions@npm:4.0.1" +"@csstools/postcss-stepped-value-functions@npm:^4.0.2": + version: 4.0.2 + resolution: "@csstools/postcss-stepped-value-functions@npm:4.0.2" dependencies: - "@csstools/css-calc": "npm:^2.0.1" - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/css-calc": "npm:^2.0.2" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" peerDependencies: postcss: ^8.4 - checksum: 10c0/7e65969b124fce603675ca17c2ffa2bb456677866e54bc9fbdc4da0945be1593fde2abb0730d3d03190776ad2022b394a1f9d4834c5b1f4c7ec497929fd35f8f + checksum: 10c0/444a27d725bc7a8e1554469e8ac69e248ff525b728fbe058523b0f1aefcff80ca707f543d21fead0a22d51603b1669190fb01f0f2dcd599a01768a37e0d62bc3 languageName: node linkType: hard @@ -1948,16 +1958,16 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-trigonometric-functions@npm:^4.0.1": - version: 4.0.1 - resolution: "@csstools/postcss-trigonometric-functions@npm:4.0.1" +"@csstools/postcss-trigonometric-functions@npm:^4.0.2": + version: 4.0.2 + resolution: "@csstools/postcss-trigonometric-functions@npm:4.0.2" dependencies: - "@csstools/css-calc": "npm:^2.0.1" - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/css-calc": "npm:^2.0.2" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" peerDependencies: postcss: ^8.4 - checksum: 10c0/59e017ebb9f4f8f027e134024e3322b5e202cc96073e0bb0d45733a829c8eadc7f4f7ce57ce8360a748a677595af9ea95da1779684699b48b911b73b4017ac8b + checksum: 10c0/eaecb2ea891162e4fcbbccf4f660c99e9e59f21937b70fe6aec3b51441eff2a12c1a2dc13fff426722629a7929919fd866311eaa68d74ee9d1f5387a23502fe2 languageName: node linkType: hard @@ -13352,18 +13362,18 @@ __metadata: languageName: node linkType: hard -"postcss-color-functional-notation@npm:^7.0.2": - version: 7.0.2 - resolution: "postcss-color-functional-notation@npm:7.0.2" +"postcss-color-functional-notation@npm:^7.0.3": + version: 7.0.3 + resolution: "postcss-color-functional-notation@npm:7.0.3" dependencies: - "@csstools/css-color-parser": "npm:^3.0.2" - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/css-color-parser": "npm:^3.0.3" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/e89c0bff94558b0c978ac36f7e02f7f516291f90fd43169d39c63ad2bb0415e3b1c4b3c2469280d578727e850fdf15a557230cb28275f3f0676f0f73187f2867 + checksum: 10c0/5e04c81002512c960784043c096bc91ebc76b8fddb9259a2418b0e121eb65042944cc0f78946f6b7e5774ff1fee087849019655e4848af1f88879e3ab9ff7c17 languageName: node linkType: hard @@ -13417,46 +13427,46 @@ __metadata: languageName: node linkType: hard -"postcss-custom-media@npm:^11.0.2": - version: 11.0.2 - resolution: "postcss-custom-media@npm:11.0.2" +"postcss-custom-media@npm:^11.0.3": + version: 11.0.3 + resolution: "postcss-custom-media@npm:11.0.3" dependencies: - "@csstools/cascade-layer-name-parser": "npm:^2.0.1" - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" - "@csstools/media-query-list-parser": "npm:^3.0.1" + "@csstools/cascade-layer-name-parser": "npm:^2.0.2" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" + "@csstools/media-query-list-parser": "npm:^4.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/7bec2b1e0b5d786c33c5715b611ffc8b9737252ee6bf77ca59255ac16f91ce614406923f43250e5c88b04f1bb050f155dc5ed4d9350dbd704c45fbd72e5a9a04 + checksum: 10c0/bd3f0cf17d7422385d26afed510dc2acebb1d8c25fce13e2bbee1c49cdc7fe95ebe7f50b89ef0a88ebdd5f6826e89d99e26b905881ceff788df655670dba93d8 languageName: node linkType: hard -"postcss-custom-properties@npm:^14.0.1": - version: 14.0.1 - resolution: "postcss-custom-properties@npm:14.0.1" +"postcss-custom-properties@npm:^14.0.2": + version: 14.0.2 + resolution: "postcss-custom-properties@npm:14.0.2" dependencies: - "@csstools/cascade-layer-name-parser": "npm:^2.0.1" - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/cascade-layer-name-parser": "npm:^2.0.2" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" "@csstools/utilities": "npm:^2.0.0" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/12180a7f4a4fe2d528387346a1810b82ed870081756dcf6be226c839716ab3f6f4d6ca4c7208a07d7d84bf2c986beef6473e29964e7c2572066fca5d3b000ed5 + checksum: 10c0/ea2e0cb60c558bb1afb4e601dcc64a38e1b28e5df3e47b83b858fc12d909d0e3453013e6b368fc05a7db7098ffcdc702a30a92f1a3c0ef67dfb97bf089021f1a languageName: node linkType: hard -"postcss-custom-selectors@npm:^8.0.1": - version: 8.0.1 - resolution: "postcss-custom-selectors@npm:8.0.1" +"postcss-custom-selectors@npm:^8.0.2": + version: 8.0.2 + resolution: "postcss-custom-selectors@npm:8.0.2" dependencies: - "@csstools/cascade-layer-name-parser": "npm:^2.0.1" - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/cascade-layer-name-parser": "npm:^2.0.2" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" postcss-selector-parser: "npm:^6.1.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/b867233b3d68fbab90afca8a776eb74196ebc3fac8988175d95118a47993c793138fec6cc580272bb35d9bd31086acbdd33ff86da0cab83ef2f08bfc1c23ecd6 + checksum: 10c0/81673ffb0874f63c0f5e14315a5808259ec80ae8452aaf10d28112d30a9aaabbf61d13edb02f8be2965f44b943968c7eda051a1693da436ef157e77fcff0d752 languageName: node linkType: hard @@ -13574,18 +13584,18 @@ __metadata: languageName: node linkType: hard -"postcss-lab-function@npm:^7.0.2": - version: 7.0.2 - resolution: "postcss-lab-function@npm:7.0.2" +"postcss-lab-function@npm:^7.0.3": + version: 7.0.3 + resolution: "postcss-lab-function@npm:7.0.3" dependencies: - "@csstools/css-color-parser": "npm:^3.0.2" - "@csstools/css-parser-algorithms": "npm:^3.0.1" - "@csstools/css-tokenizer": "npm:^3.0.1" + "@csstools/css-color-parser": "npm:^3.0.3" + "@csstools/css-parser-algorithms": "npm:^3.0.2" + "@csstools/css-tokenizer": "npm:^3.0.2" "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/6b2be7e762b4ccb58ea9051723d390f6732ad78bb30bfef9499139cf5e2ac160c3de31b2b005fcc30e9fced4abe1685df6cb76c99d548896bae6746105ac8520 + checksum: 10c0/c50a73a9ed54b4194998c4627599d1f42074235f572edbbcdb0e00717f3ae2121dc8378d917792b281860c5650a617d923823da6f395515f610b5760d115354d languageName: node linkType: hard @@ -13906,38 +13916,38 @@ __metadata: linkType: hard "postcss-preset-env@npm:^10.0.0": - version: 10.0.6 - resolution: "postcss-preset-env@npm:10.0.6" + version: 10.0.7 + resolution: "postcss-preset-env@npm:10.0.7" dependencies: "@csstools/postcss-cascade-layers": "npm:^5.0.0" - "@csstools/postcss-color-function": "npm:^4.0.2" - "@csstools/postcss-color-mix-function": "npm:^3.0.2" - "@csstools/postcss-content-alt-text": "npm:^2.0.1" - "@csstools/postcss-exponential-functions": "npm:^2.0.1" + "@csstools/postcss-color-function": "npm:^4.0.3" + "@csstools/postcss-color-mix-function": "npm:^3.0.3" + "@csstools/postcss-content-alt-text": "npm:^2.0.2" + "@csstools/postcss-exponential-functions": "npm:^2.0.2" "@csstools/postcss-font-format-keywords": "npm:^4.0.0" - "@csstools/postcss-gamut-mapping": "npm:^2.0.2" - "@csstools/postcss-gradients-interpolation-method": "npm:^5.0.2" - "@csstools/postcss-hwb-function": "npm:^4.0.2" + "@csstools/postcss-gamut-mapping": "npm:^2.0.3" + "@csstools/postcss-gradients-interpolation-method": "npm:^5.0.3" + "@csstools/postcss-hwb-function": "npm:^4.0.3" "@csstools/postcss-ic-unit": "npm:^4.0.0" "@csstools/postcss-initial": "npm:^2.0.0" "@csstools/postcss-is-pseudo-class": "npm:^5.0.0" - "@csstools/postcss-light-dark-function": "npm:^2.0.4" + "@csstools/postcss-light-dark-function": "npm:^2.0.5" "@csstools/postcss-logical-float-and-clear": "npm:^3.0.0" "@csstools/postcss-logical-overflow": "npm:^2.0.0" "@csstools/postcss-logical-overscroll-behavior": "npm:^2.0.0" "@csstools/postcss-logical-resize": "npm:^3.0.0" - "@csstools/postcss-logical-viewport-units": "npm:^3.0.1" - "@csstools/postcss-media-minmax": "npm:^2.0.1" - "@csstools/postcss-media-queries-aspect-ratio-number-values": "npm:^3.0.1" + "@csstools/postcss-logical-viewport-units": "npm:^3.0.2" + "@csstools/postcss-media-minmax": "npm:^2.0.2" + "@csstools/postcss-media-queries-aspect-ratio-number-values": "npm:^3.0.2" "@csstools/postcss-nested-calc": "npm:^4.0.0" "@csstools/postcss-normalize-display-values": "npm:^4.0.0" - "@csstools/postcss-oklab-function": "npm:^4.0.2" + "@csstools/postcss-oklab-function": "npm:^4.0.3" "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" - "@csstools/postcss-relative-color-syntax": "npm:^3.0.2" + "@csstools/postcss-relative-color-syntax": "npm:^3.0.3" "@csstools/postcss-scope-pseudo-class": "npm:^4.0.0" - "@csstools/postcss-stepped-value-functions": "npm:^4.0.1" + "@csstools/postcss-stepped-value-functions": "npm:^4.0.2" "@csstools/postcss-text-decoration-shorthand": "npm:^4.0.1" - "@csstools/postcss-trigonometric-functions": "npm:^4.0.1" + "@csstools/postcss-trigonometric-functions": "npm:^4.0.2" "@csstools/postcss-unset-value": "npm:^4.0.0" autoprefixer: "npm:^10.4.19" browserslist: "npm:^4.23.1" @@ -13947,12 +13957,12 @@ __metadata: cssdb: "npm:^8.1.1" postcss-attribute-case-insensitive: "npm:^7.0.0" postcss-clamp: "npm:^4.1.0" - postcss-color-functional-notation: "npm:^7.0.2" + postcss-color-functional-notation: "npm:^7.0.3" postcss-color-hex-alpha: "npm:^10.0.0" postcss-color-rebeccapurple: "npm:^10.0.0" - postcss-custom-media: "npm:^11.0.2" - postcss-custom-properties: "npm:^14.0.1" - postcss-custom-selectors: "npm:^8.0.1" + postcss-custom-media: "npm:^11.0.3" + postcss-custom-properties: "npm:^14.0.2" + postcss-custom-selectors: "npm:^8.0.2" postcss-dir-pseudo-class: "npm:^9.0.0" postcss-double-position-gradients: "npm:^6.0.0" postcss-focus-visible: "npm:^10.0.0" @@ -13960,7 +13970,7 @@ __metadata: postcss-font-variant: "npm:^5.0.0" postcss-gap-properties: "npm:^6.0.0" postcss-image-set-function: "npm:^7.0.0" - postcss-lab-function: "npm:^7.0.2" + postcss-lab-function: "npm:^7.0.3" postcss-logical: "npm:^8.0.0" postcss-nesting: "npm:^13.0.0" postcss-opacity-percentage: "npm:^3.0.0" @@ -13972,7 +13982,7 @@ __metadata: postcss-selector-not: "npm:^8.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/01660acf3b9ddf4d612a31819e9a5de9fe5383e9eddd2c130180f66ae90c5a881eb408e73454fd50e1839eae71678d738bf72073de08f9013c183b0bd9950fe5 + checksum: 10c0/f789000e0504fd827e854bb0feb8b4c218d381314e4d863c5a36df925df412d0844c912952fe27892a320433640aeaff03ee94a3057b42011bf5d32b3963f333 languageName: node linkType: hard From 3b07fe1bba713fb10f5c873dccb38f6875180c77 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 10 Oct 2024 15:42:08 +0200 Subject: [PATCH 124/150] =?UTF-8?q?Fix=20=E2=80=9CMark=20every=20notificat?= =?UTF-8?q?ion=20as=20read=E2=80=9D=20not=20updating=20the=20read=20marker?= =?UTF-8?q?=20if=20scrolled=20down=20(#32385)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/javascript/mastodon/reducers/notification_groups.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/javascript/mastodon/reducers/notification_groups.ts b/app/javascript/mastodon/reducers/notification_groups.ts index 8b033f0fc7..91e91d7549 100644 --- a/app/javascript/mastodon/reducers/notification_groups.ts +++ b/app/javascript/mastodon/reducers/notification_groups.ts @@ -559,7 +559,10 @@ export const notificationGroupsReducer = createReducer( compareId(state.lastReadId, mostRecentGroup.page_max_id) < 0 ) state.lastReadId = mostRecentGroup.page_max_id; - commitLastReadId(state); + + // We don't call `commitLastReadId`, because that is conditional + // and we want to unconditionally update the state instead. + state.readMarkerId = state.lastReadId; }) .addCase(fetchMarkers.fulfilled, (state, action) => { if ( From 22fd767425a02eb1b39d18a54053603772777b86 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 10 Oct 2024 16:53:12 +0200 Subject: [PATCH 125/150] Fix mute duration not being shown in list of muted accounts in web UI (#32388) --- app/javascript/mastodon/api_types/accounts.ts | 11 ++++++++++- app/javascript/mastodon/models/account.ts | 3 +++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/javascript/mastodon/api_types/accounts.ts b/app/javascript/mastodon/api_types/accounts.ts index 5bf3e64288..fdbd7523fc 100644 --- a/app/javascript/mastodon/api_types/accounts.ts +++ b/app/javascript/mastodon/api_types/accounts.ts @@ -13,7 +13,7 @@ export interface ApiAccountRoleJSON { } // See app/serializers/rest/account_serializer.rb -export interface ApiAccountJSON { +export interface BaseApiAccountJSON { acct: string; avatar: string; avatar_static: string; @@ -45,3 +45,12 @@ export interface ApiAccountJSON { memorial?: boolean; hide_collections: boolean; } + +// See app/serializers/rest/muted_account_serializer.rb +export interface ApiMutedAccountJSON extends BaseApiAccountJSON { + mute_expires_at?: string | null; +} + +// For now, we have the same type representing both `Account` and `MutedAccount` +// objects, but we should refactor this in the future. +export type ApiAccountJSON = ApiMutedAccountJSON; diff --git a/app/javascript/mastodon/models/account.ts b/app/javascript/mastodon/models/account.ts index a04ebe6291..8e8e3b0e8d 100644 --- a/app/javascript/mastodon/models/account.ts +++ b/app/javascript/mastodon/models/account.ts @@ -95,6 +95,9 @@ export const accountDefaultValues: AccountShape = { limited: false, moved: null, hide_collections: false, + // This comes from `ApiMutedAccountJSON`, but we should eventually + // store that in a different object. + mute_expires_at: null, }; const AccountFactory = ImmutableRecord(accountDefaultValues); From 6e96ec840d9fdf0ba83f48d8482b2bcdd573c08e Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 10 Oct 2024 19:31:51 +0200 Subject: [PATCH 126/150] Fix the favicon notification badge not using the correct notification count (#2880) Fixes #2879 --- app/javascript/flavours/glitch/features/ui/index.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/features/ui/index.jsx b/app/javascript/flavours/glitch/features/ui/index.jsx index d1165194ba..1ef29f8db2 100644 --- a/app/javascript/flavours/glitch/features/ui/index.jsx +++ b/app/javascript/flavours/glitch/features/ui/index.jsx @@ -21,6 +21,7 @@ import { Permalink } from 'flavours/glitch/components/permalink'; import { PictureInPicture } from 'flavours/glitch/features/picture_in_picture'; import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context'; import { layoutFromWindow } from 'flavours/glitch/is_mobile'; +import { selectUnreadNotificationGroupsCount } from 'flavours/glitch/selectors/notifications'; import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router'; import { uploadCompose, resetCompose, changeComposeSpoilerness } from '../../actions/compose'; @@ -90,7 +91,7 @@ const mapStateToProps = state => ({ hasMediaAttachments: state.getIn(['compose', 'media_attachments']).size > 0, canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < 4, isWide: state.getIn(['local_settings', 'stretch']), - unreadNotifications: state.getIn(['notifications', 'unread']), + unreadNotifications: selectUnreadNotificationGroupsCount(state), showFaviconBadge: state.getIn(['local_settings', 'notifications', 'favicon_badge']), hicolorPrivacyIcons: state.getIn(['local_settings', 'hicolor_privacy_icons']), moved: state.getIn(['accounts', me, 'moved']) && state.getIn(['accounts', state.getIn(['accounts', me, 'moved'])]), From bb0cf04d71783214aab0a65f410f76ba6989513c Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 11 Oct 2024 11:19:48 +0200 Subject: [PATCH 127/150] Add note about not changing ActiveRecord encryption secrets once they are set (#32413) --- lib/tasks/db.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tasks/db.rake b/lib/tasks/db.rake index d8bc927bc4..79599bd917 100644 --- a/lib/tasks/db.rake +++ b/lib/tasks/db.rake @@ -8,7 +8,7 @@ namespace :db do desc 'Generate a set of keys for configuring Active Record encryption in a given environment' task :init do # rubocop:disable Rails/RakeEnvironment puts <<~MSG - Add these secret environment variables to your Mastodon environment (e.g. .env.production):#{' '} + Add the following secret environment variables to your Mastodon environment (e.g. .env.production), ensure they are shared across all your nodes and do not change them after they are set:#{' '} ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=#{SecureRandom.alphanumeric(32)} ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=#{SecureRandom.alphanumeric(32)} From 10ea6da09ffc46a402800d22c81bad6dfa0beecb Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 11 Oct 2024 12:24:03 +0200 Subject: [PATCH 128/150] Fix language of push notifications (#32415) --- app/workers/web/push_notification_worker.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/workers/web/push_notification_worker.rb b/app/workers/web/push_notification_worker.rb index 104503f130..e771928ef3 100644 --- a/app/workers/web/push_notification_worker.rb +++ b/app/workers/web/push_notification_worker.rb @@ -55,12 +55,8 @@ class Web::PushNotificationWorker end def push_notification_json - Oj.dump(serialized_notification_in_subscription_locale.as_json) - end - - def serialized_notification_in_subscription_locale I18n.with_locale(@subscription.locale.presence || I18n.default_locale) do - serialized_notification + Oj.dump(serialized_notification.as_json) end end From e15befebbd288faeec55ef6ad323d106f4ec57e1 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 11 Oct 2024 16:16:37 +0200 Subject: [PATCH 129/150] Add tag with commit hash to PR image builds (#32418) --- .github/workflows/build-push-pr.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-push-pr.yml b/.github/workflows/build-push-pr.yml index 72baed5121..d3bc8e5df8 100644 --- a/.github/workflows/build-push-pr.yml +++ b/.github/workflows/build-push-pr.yml @@ -21,9 +21,11 @@ jobs: uses: actions/checkout@v4 - id: version_vars run: | - echo mastodon_version_metadata=pr-${{ github.event.pull_request.number }}-$(git rev-parse --short HEAD) >> $GITHUB_OUTPUT + echo mastodon_version_metadata=pr-${{ github.event.pull_request.number }}-$(git rev-parse --short ${{github.event.pull_request.head.sha}}) >> $GITHUB_OUTPUT + echo mastodon_short_sha=$(git rev-parse --short ${{github.event.pull_request.head.sha}}) >> $GITHUB_OUTPUT outputs: metadata: ${{ steps.version_vars.outputs.mastodon_version_metadata }} + short_sha: ${{ steps.version_vars.outputs.mastodon_short_sha }} build-image: needs: compute-suffix @@ -39,6 +41,7 @@ jobs: latest=auto tags: | type=ref,event=pr + type=ref,event=pr,suffix=-${{ needs.compute-suffix.outputs.short_sha }} secrets: inherit build-image-streaming: @@ -55,4 +58,5 @@ jobs: latest=auto tags: | type=ref,event=pr + type=ref,event=pr,suffix=-${{ needs.compute-suffix.outputs.short_sha }} secrets: inherit From 888e6a3439ed1324a53d1085a2b293809c9e1eb6 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 11 Oct 2024 17:45:07 +0200 Subject: [PATCH 130/150] Fix setting to hide the quick filter bar (#2882) Fixes #2881 --- .../glitch/features/notifications_v2/filter_bar.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/javascript/flavours/glitch/features/notifications_v2/filter_bar.tsx b/app/javascript/flavours/glitch/features/notifications_v2/filter_bar.tsx index 1299796662..d9a6b4d07f 100644 --- a/app/javascript/flavours/glitch/features/notifications_v2/filter_bar.tsx +++ b/app/javascript/flavours/glitch/features/notifications_v2/filter_bar.tsx @@ -14,6 +14,7 @@ import { Icon } from 'flavours/glitch/components/icon'; import { selectSettingsNotificationsQuickFilterActive, selectSettingsNotificationsQuickFilterAdvanced, + selectSettingsNotificationsQuickFilterShow, } from 'flavours/glitch/selectors/settings'; import { useAppDispatch, useAppSelector } from 'flavours/glitch/store'; @@ -65,6 +66,11 @@ export const FilterBar: React.FC = () => { const advancedMode = useAppSelector( selectSettingsNotificationsQuickFilterAdvanced, ); + const useFilterBar = useAppSelector( + selectSettingsNotificationsQuickFilterShow, + ); + + if (!useFilterBar) return null; if (advancedMode) return ( From b0dd38433beda1e72ed74e80b6523805fa0a9d56 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 14 Oct 2024 10:18:25 +0200 Subject: [PATCH 131/150] Fix follow recommendation suppressions not applying immediately (#32392) --- app/models/follow_recommendation.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/follow_recommendation.rb b/app/models/follow_recommendation.rb index 7ac9e6dfb9..0435437a81 100644 --- a/app/models/follow_recommendation.rb +++ b/app/models/follow_recommendation.rb @@ -18,5 +18,6 @@ class FollowRecommendation < ApplicationRecord belongs_to :account_summary, foreign_key: :account_id, inverse_of: false belongs_to :account - scope :localized, ->(locale) { joins(:account_summary).merge(AccountSummary.localized(locale)) } + scope :unsupressed, -> { where.not(FollowRecommendationSuppression.where(FollowRecommendationSuppression.arel_table[:account_id].eq(arel_table[:account_id])).select(1).arel.exists) } + scope :localized, ->(locale) { unsupressed.joins(:account_summary).merge(AccountSummary.localized(locale)) } end From de422a37e8092768a6e8bef45479c43da8681d5d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 10:22:46 +0200 Subject: [PATCH 132/150] Update dependency fuzzysort to v3.1.0 (#32460) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 548d94fc2e..cd4ac5ce96 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8934,9 +8934,9 @@ __metadata: linkType: hard "fuzzysort@npm:^3.0.0": - version: 3.0.2 - resolution: "fuzzysort@npm:3.0.2" - checksum: 10c0/c6cdbd092a8e91ed822aeac6d4fb95559759c10602cb29f27307c1cabd01fdd384fa399f7757722435b595244efb000cd63f144104c41b8551b2faff123279cb + version: 3.1.0 + resolution: "fuzzysort@npm:3.1.0" + checksum: 10c0/da9bb32de16f2a5c2c000b99031d9f4f8a01380c12d5d3b67296443a1152c55987ce3c4ddbfe97481b0e9b6f2fb77d61dceba29a93ad36ee23ef5bab6a31afb8 languageName: node linkType: hard From e9eac648964b1c3cdbbc49022bdf44483dba6b34 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 08:23:20 +0000 Subject: [PATCH 133/150] Update devDependencies (non-major) (#32457) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 98 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 41 deletions(-) diff --git a/yarn.lock b/yarn.lock index cd4ac5ce96..8c8c98bbc7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2267,8 +2267,8 @@ __metadata: linkType: hard "@formatjs/cli@npm:^6.1.1": - version: 6.2.12 - resolution: "@formatjs/cli@npm:6.2.12" + version: 6.2.15 + resolution: "@formatjs/cli@npm:6.2.15" peerDependencies: "@glimmer/env": ^0.1.7 "@glimmer/reference": ^0.91.1 || ^0.92.0 @@ -2297,7 +2297,7 @@ __metadata: optional: true bin: formatjs: bin/formatjs - checksum: 10c0/3bd05a9fad6c837e22988e6638f426c128efa46ab80ff88cf2ad81fb3bc10cf4f228907577fc01e24c2d7d505cfabfaa69f0496d2ec8f0ab2d6b5eaccb5e475c + checksum: 10c0/e947aa7f3994251392fe15673752a8d8e3c8a30733bb49de5e617d45a327a3e1d16419e2d6b01f7ef2cbe86e2946024342d5b3301e6a8f17de3de9e2e7aedb29 languageName: node linkType: hard @@ -6622,10 +6622,10 @@ __metadata: languageName: node linkType: hard -"css-functions-list@npm:^3.2.2": - version: 3.2.2 - resolution: "css-functions-list@npm:3.2.2" - checksum: 10c0/8638a63d0cf1bdc50d4a752ec1c94a57e9953c3b03eace4f5526db20bec3c061e95089f905dbb4999c44b9780ce777ba856967560f6d15119a303f6030901c10 +"css-functions-list@npm:^3.2.3": + version: 3.2.3 + resolution: "css-functions-list@npm:3.2.3" + checksum: 10c0/03f9ed34eeed310d2b1cf0e524eea02bc5f87854a4de85f8957ea432ab1036841a3fb00879590519f7bb8fda40d992ce7a72fa9b61696ca1dc53b90064858f96 languageName: node linkType: hard @@ -6733,6 +6733,16 @@ __metadata: languageName: node linkType: hard +"css-tree@npm:^3.0.0": + version: 3.0.0 + resolution: "css-tree@npm:3.0.0" + dependencies: + mdn-data: "npm:2.10.0" + source-map-js: "npm:^1.0.1" + checksum: 10c0/43d44fdf7004ae91d73d486f17894fef77efa33747a6752b9241cf0f5fb47fabc16ec34a96a993651d9014dfdeee803d7c5fcd3548214252ee19f4e5c98999b2 + languageName: node + linkType: hard + "css-tree@npm:~2.2.0": version: 2.2.1 resolution: "css-tree@npm:2.2.1" @@ -6982,15 +6992,15 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.3.6, debug@npm:~4.3.6": - version: 4.3.6 - resolution: "debug@npm:4.3.6" +"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.3.6, debug@npm:^4.3.7, debug@npm:~4.3.6": + version: 4.3.7 + resolution: "debug@npm:4.3.7" dependencies: - ms: "npm:2.1.2" + ms: "npm:^2.1.3" peerDependenciesMeta: supports-color: optional: true - checksum: 10c0/3293416bff072389c101697d4611c402a6bacd1900ac20c0492f61a9cdd6b3b29750fc7f5e299f8058469ef60ff8fb79b86395a30374fbd2490113c1c7112285 + checksum: 10c0/1471db19c3b06d485a622d62f65947a19a23fbd0dd73f7fd3eafb697eec5360cde447fb075919987899b1a2096e85d35d4eb5a4de09a57600ac9cf7e6c8e768b languageName: node linkType: hard @@ -8577,12 +8587,12 @@ __metadata: languageName: node linkType: hard -"file-entry-cache@npm:^9.0.0": - version: 9.0.0 - resolution: "file-entry-cache@npm:9.0.0" +"file-entry-cache@npm:^9.1.0": + version: 9.1.0 + resolution: "file-entry-cache@npm:9.1.0" dependencies: flat-cache: "npm:^5.0.0" - checksum: 10c0/07b0a4f062dc0aa258f3e1b06ac083ea25313f5e289943e146fafdaf3315dcc031635545eea7fe98fe5598b91d6c7f48dba7a251dd7ac20108a6ebf7d00b0b1c + checksum: 10c0/4b4dbc1e972f50202b1a4430d30fd99378ef6e2a64857176abdc65c5e4730a948fb37e274478520a7bacbc70f3abba455a4b9d2c1915c53f30d11dc85d3fef5e languageName: node linkType: hard @@ -9656,13 +9666,20 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.2.0, ignore@npm:^5.3.1, ignore@npm:^5.3.2": +"ignore@npm:^5.2.0, ignore@npm:^5.3.1": version: 5.3.2 resolution: "ignore@npm:5.3.2" checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 languageName: node linkType: hard +"ignore@npm:^6.0.2": + version: 6.0.2 + resolution: "ignore@npm:6.0.2" + checksum: 10c0/9a38feac1861906a78ba0f03e8ef3cd6b0526dce2a1a84e1009324b557763afeb9c3ebcc04666b21f7bbf71adda45e76781bb9e2eaa0903d45dcaded634454f5 + languageName: node + linkType: hard + "immer@npm:^10.0.3": version: 10.0.3 resolution: "immer@npm:10.0.3" @@ -11828,6 +11845,13 @@ __metadata: languageName: node linkType: hard +"mdn-data@npm:2.10.0": + version: 2.10.0 + resolution: "mdn-data@npm:2.10.0" + checksum: 10c0/f6f1a6a6eb092bab250d06f6f6c7cb1733a77a17e7119aac829ad67d4322bbf6a30df3c6d88686e71942e66bd49274b2ddfede22a1d3df0d6c49a56fbd09eb7c + languageName: node + linkType: hard + "media-typer@npm:0.3.0": version: 0.3.0 resolution: "media-typer@npm:0.3.0" @@ -12207,14 +12231,7 @@ __metadata: languageName: node linkType: hard -"ms@npm:2.1.2": - version: 2.1.2 - resolution: "ms@npm:2.1.2" - checksum: 10c0/a437714e2f90dbf881b5191d35a6db792efbca5badf112f87b9e1c712aace4b4b9b742dd6537f3edf90fd6f684de897cec230abde57e87883766712ddda297cc - languageName: node - linkType: hard - -"ms@npm:2.1.3, ms@npm:^2.1.1": +"ms@npm:2.1.3, ms@npm:^2.1.1, ms@npm:^2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 @@ -14036,12 +14053,12 @@ __metadata: languageName: node linkType: hard -"postcss-safe-parser@npm:^7.0.0": - version: 7.0.0 - resolution: "postcss-safe-parser@npm:7.0.0" +"postcss-safe-parser@npm:^7.0.1": + version: 7.0.1 + resolution: "postcss-safe-parser@npm:7.0.1" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/4217afd8ce2809e959dc365e4675f499303cc6b91f94db06c8164422822db2d3b3124df701ee2234db4127ad05619b016bfb9c2bccae9bf9cf898a396f1632c9 + checksum: 10c0/6957b10b818bd8d4664ec0e548af967f7549abedfb37f844d389571d36af681340f41f9477b9ccf34bcc7599bdef222d1d72e79c64373001fae77089fba6d965 languageName: node linkType: hard @@ -14105,7 +14122,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.2.15, postcss@npm:^8.4.24, postcss@npm:^8.4.41": +"postcss@npm:^8.2.15, postcss@npm:^8.4.24, postcss@npm:^8.4.47": version: 8.4.47 resolution: "postcss@npm:8.4.47" dependencies: @@ -16703,8 +16720,8 @@ __metadata: linkType: hard "stylelint@npm:^16.0.2": - version: 16.9.0 - resolution: "stylelint@npm:16.9.0" + version: 16.10.0 + resolution: "stylelint@npm:16.10.0" dependencies: "@csstools/css-parser-algorithms": "npm:^3.0.1" "@csstools/css-tokenizer": "npm:^3.0.1" @@ -16714,17 +16731,17 @@ __metadata: balanced-match: "npm:^2.0.0" colord: "npm:^2.9.3" cosmiconfig: "npm:^9.0.0" - css-functions-list: "npm:^3.2.2" - css-tree: "npm:^2.3.1" - debug: "npm:^4.3.6" + css-functions-list: "npm:^3.2.3" + css-tree: "npm:^3.0.0" + debug: "npm:^4.3.7" fast-glob: "npm:^3.3.2" fastest-levenshtein: "npm:^1.0.16" - file-entry-cache: "npm:^9.0.0" + file-entry-cache: "npm:^9.1.0" global-modules: "npm:^2.0.0" globby: "npm:^11.1.0" globjoin: "npm:^0.1.4" html-tags: "npm:^3.3.1" - ignore: "npm:^5.3.2" + ignore: "npm:^6.0.2" imurmurhash: "npm:^0.1.4" is-plain-object: "npm:^5.0.0" known-css-properties: "npm:^0.34.0" @@ -16733,21 +16750,20 @@ __metadata: micromatch: "npm:^4.0.8" normalize-path: "npm:^3.0.0" picocolors: "npm:^1.0.1" - postcss: "npm:^8.4.41" + postcss: "npm:^8.4.47" postcss-resolve-nested-selector: "npm:^0.1.6" - postcss-safe-parser: "npm:^7.0.0" + postcss-safe-parser: "npm:^7.0.1" postcss-selector-parser: "npm:^6.1.2" postcss-value-parser: "npm:^4.2.0" resolve-from: "npm:^5.0.0" string-width: "npm:^4.2.3" - strip-ansi: "npm:^7.1.0" supports-hyperlinks: "npm:^3.1.0" svg-tags: "npm:^1.0.0" table: "npm:^6.8.2" write-file-atomic: "npm:^5.0.1" bin: stylelint: bin/stylelint.mjs - checksum: 10c0/d3ff9c8945c56b04a2fa16ec33d163325496d5db94b6fcb5adf74c76f7f794ac992888273f9a3317652ba8b6195168b2ffff382ca2a667a241e2ace8c9505ae2 + checksum: 10c0/d07dd156c225d16c740995daacd78090f7fc317602e87bda2fca323a4ae427a8526d724f3089df3b2185df4520f987547668ceea9b30985988ccbc514034aa21 languageName: node linkType: hard From 05bc82e1ab7fab0beae7dc300d2dd369faf0504a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 08:24:10 +0000 Subject: [PATCH 134/150] Update dependency use-debounce to v10.0.4 (#32452) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8c8c98bbc7..30317f9a1f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17662,11 +17662,11 @@ __metadata: linkType: hard "use-debounce@npm:^10.0.0": - version: 10.0.3 - resolution: "use-debounce@npm:10.0.3" + version: 10.0.4 + resolution: "use-debounce@npm:10.0.4" peerDependencies: react: "*" - checksum: 10c0/351b62c565d6dce5a21ecc21fe3e1f8db74f70c81c8f7d9dbdfc2da1cb82d883578589f6146e684d91dac534bc3c8b145ab1a36fbf4d44cbb4113827508b39aa + checksum: 10c0/73494fc44b2bd58a7ec799a528fc20077c45fe2e94fedff6dcd88d136f7a39f417d77f584d5613aac615ed32aeb2ea393797ae1f7d5b2645eab57cb497a6d0cb languageName: node linkType: hard From 555fb98cbb1f6e951d8ee0401bd95215ed8dd58c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 10:28:15 +0200 Subject: [PATCH 135/150] Update dependency typescript to v5.6.3 (#32456) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index 30317f9a1f..fe975f3a75 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17408,22 +17408,22 @@ __metadata: linkType: hard "typescript@npm:5, typescript@npm:^5.0.4": - version: 5.6.2 - resolution: "typescript@npm:5.6.2" + version: 5.6.3 + resolution: "typescript@npm:5.6.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/3ed8297a8c7c56b7fec282532503d1ac795239d06e7c4966b42d4330c6cf433a170b53bcf93a130a7f14ccc5235de5560df4f1045eb7f3550b46ebed16d3c5e5 + checksum: 10c0/44f61d3fb15c35359bc60399cb8127c30bae554cd555b8e2b46d68fa79d680354b83320ad419ff1b81a0bdf324197b29affe6cc28988cd6a74d4ac60c94f9799 languageName: node linkType: hard "typescript@patch:typescript@npm%3A5#optional!builtin, typescript@patch:typescript@npm%3A^5.0.4#optional!builtin": - version: 5.6.2 - resolution: "typescript@patch:typescript@npm%3A5.6.2#optional!builtin::version=5.6.2&hash=8c6c40" + version: 5.6.3 + resolution: "typescript@patch:typescript@npm%3A5.6.3#optional!builtin::version=5.6.3&hash=8c6c40" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/94eb47e130d3edd964b76da85975601dcb3604b0c848a36f63ac448d0104e93819d94c8bdf6b07c00120f2ce9c05256b8b6092d23cf5cf1c6fa911159e4d572f + checksum: 10c0/7c9d2e07c81226d60435939618c91ec2ff0b75fbfa106eec3430f0fcf93a584bc6c73176676f532d78c3594fe28a54b36eb40b3d75593071a7ec91301533ace7 languageName: node linkType: hard From 2343ce4441c2304da1e20adcb7d9262d71890abd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 08:28:47 +0000 Subject: [PATCH 136/150] Update dependency rack to v2.2.10 (#32455) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1c2bb8df08..4c9cfe828e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -615,7 +615,7 @@ GEM activesupport (>= 3.0.0) raabro (1.4.0) racc (1.8.1) - rack (2.2.9) + rack (2.2.10) rack-attack (6.7.0) rack (>= 1.0, < 4) rack-cors (2.0.2) From 06d6b35e884dbfa10ba7cb0069b5dd8c25c76399 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 14 Oct 2024 04:31:12 -0400 Subject: [PATCH 137/150] Convert `admin/tags` controller specs to system specs (#32447) --- .../controllers/admin/tags_controller_spec.rb | 82 ------------------- spec/system/admin/tags_spec.rb | 38 +++++++++ 2 files changed, 38 insertions(+), 82 deletions(-) delete mode 100644 spec/controllers/admin/tags_controller_spec.rb create mode 100644 spec/system/admin/tags_spec.rb diff --git a/spec/controllers/admin/tags_controller_spec.rb b/spec/controllers/admin/tags_controller_spec.rb deleted file mode 100644 index 1df2bc4003..0000000000 --- a/spec/controllers/admin/tags_controller_spec.rb +++ /dev/null @@ -1,82 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Admin::TagsController do - render_views - - before do - sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')) - end - - describe 'GET #index' do - before do - Fabricate(:tag) - - tag_filter = instance_double(Admin::TagFilter, results: Tag.all) - allow(Admin::TagFilter).to receive(:new).and_return(tag_filter) - end - - let(:params) { { order: 'newest' } } - - it 'returns http success' do - get :index - - expect(response).to have_http_status(200) - expect(response).to render_template(:index) - - expect(Admin::TagFilter) - .to have_received(:new) - .with(hash_including(params)) - end - - describe 'with filters' do - let(:params) { { order: 'newest', name: 'test' } } - - it 'returns http success' do - get :index, params: { name: 'test' } - - expect(response).to have_http_status(200) - expect(response).to render_template(:index) - - expect(Admin::TagFilter) - .to have_received(:new) - .with(hash_including(params)) - end - end - end - - describe 'GET #show' do - let!(:tag) { Fabricate(:tag) } - - before do - get :show, params: { id: tag.id } - end - - it 'returns status 200' do - expect(response).to have_http_status(200) - end - end - - describe 'PUT #update' do - let!(:tag) { Fabricate(:tag, listable: false) } - - context 'with valid params' do - it 'updates the tag' do - put :update, params: { id: tag.id, tag: { listable: '1' } } - - expect(response).to redirect_to(admin_tag_path(tag.id)) - expect(tag.reload).to be_listable - end - end - - context 'with invalid params' do - it 'does not update the tag' do - put :update, params: { id: tag.id, tag: { name: 'cant-change-name' } } - - expect(response).to have_http_status(200) - expect(response).to render_template(:show) - end - end - end -end diff --git a/spec/system/admin/tags_spec.rb b/spec/system/admin/tags_spec.rb new file mode 100644 index 0000000000..a3eca80d13 --- /dev/null +++ b/spec/system/admin/tags_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Admin Tags' do + describe 'Tag interaction' do + let!(:tag) { Fabricate(:tag, name: 'test') } + + before { sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + it 'allows tags listing and editing' do + visit admin_tags_path + + expect(page) + .to have_title(I18n.t('admin.tags.title')) + + click_on '#test' + + fill_in display_name_field, with: 'NewTagName' + expect { click_on submit_button } + .to_not(change { tag.reload.display_name }) + expect(page) + .to have_content(match_error_text) + + fill_in display_name_field, with: 'TEST' + expect { click_on submit_button } + .to(change { tag.reload.display_name }.to('TEST')) + end + + def display_name_field + I18n.t('simple_form.labels.defaults.display_name') + end + + def match_error_text + I18n.t('tags.does_not_match_previous_name') + end + end +end From 2404d6d1a13d1e59f026c14403b89a328decabe3 Mon Sep 17 00:00:00 2001 From: Florian Kohler <13822756+FlohEinstein@users.noreply.github.com> Date: Mon, 14 Oct 2024 10:57:34 +0200 Subject: [PATCH 138/150] Added Swiss German to languages dropdown (#29281) Co-authored-by: David Roetzel --- app/helpers/languages_helper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/helpers/languages_helper.rb b/app/helpers/languages_helper.rb index b6c09b7314..394202e39a 100644 --- a/app/helpers/languages_helper.rb +++ b/app/helpers/languages_helper.rb @@ -193,6 +193,7 @@ module LanguagesHelper ckb: ['Sorani (Kurdish)', 'سۆرانی'].freeze, cnr: ['Montenegrin', 'crnogorski'].freeze, csb: ['Kashubian', 'Kaszëbsczi'].freeze, + gsw: ['Swiss German', 'Schwiizertütsch'].freeze, jbo: ['Lojban', 'la .lojban.'].freeze, kab: ['Kabyle', 'Taqbaylit'].freeze, ldn: ['Láadan', 'Láadan'].freeze, From d8eab3d81f1ab46026801d4698380110e25f7b44 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 14 Oct 2024 08:51:01 -0400 Subject: [PATCH 139/150] Reinforce coverage for `DomainBlock` model (#32473) --- app/models/domain_block.rb | 4 +++- spec/models/domain_block_spec.rb | 33 ++++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/app/models/domain_block.rb b/app/models/domain_block.rb index b5d1f2e079..2853f6457a 100644 --- a/app/models/domain_block.rb +++ b/app/models/domain_block.rb @@ -40,7 +40,9 @@ class DomainBlock < ApplicationRecord if suspend? [:suspend] else - [severity.to_sym, reject_media? ? :reject_media : nil, reject_reports? ? :reject_reports : nil].reject { |policy| policy == :noop || policy.nil? } + [severity.to_sym, reject_media? ? :reject_media : nil, reject_reports? ? :reject_reports : nil] + .reject { |policy| policy == :noop } + .compact end end diff --git a/spec/models/domain_block_spec.rb b/spec/models/domain_block_spec.rb index 8278454cd7..14f904ea7f 100644 --- a/spec/models/domain_block_spec.rb +++ b/spec/models/domain_block_spec.rb @@ -3,14 +3,13 @@ require 'rails_helper' RSpec.describe DomainBlock do - describe 'validations' do + describe 'Validations' do it { is_expected.to validate_presence_of(:domain) } - it 'is invalid if the same normalized domain already exists' do - _domain_block = Fabricate(:domain_block, domain: 'にゃん') - domain_block_with_normalized_value = Fabricate.build(:domain_block, domain: 'xn--r9j5b5b') - domain_block_with_normalized_value.valid? - expect(domain_block_with_normalized_value).to model_have_error_on_field(:domain) + context 'when a normalized domain exists' do + before { Fabricate(:domain_block, domain: 'にゃん') } + + it { is_expected.to_not allow_value('xn--r9j5b5b').for(:domain) } end end @@ -105,4 +104,26 @@ RSpec.describe DomainBlock do end end end + + describe '#policies' do + subject { domain_block.policies } + + context 'when severity is suspend' do + let(:domain_block) { Fabricate.build :domain_block, severity: :suspend } + + it { is_expected.to eq(%i(suspend)) } + end + + context 'when severity is noop' do + let(:domain_block) { Fabricate.build :domain_block, severity: :noop, reject_media: true } + + it { is_expected.to eq(%i(reject_media)) } + end + + context 'when severity is silence' do + let(:domain_block) { Fabricate.build :domain_block, severity: :silence, reject_reports: true } + + it { is_expected.to eq(%i(silence reject_reports)) } + end + end end From cc70acc11cf488660ebd4a207633380e56cbf417 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 14 Oct 2024 08:52:47 -0400 Subject: [PATCH 140/150] Augment coverage for `Status` model (#32468) --- spec/models/status_spec.rb | 52 ++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/spec/models/status_spec.rb b/spec/models/status_spec.rb index df67c365eb..90f5968438 100644 --- a/spec/models/status_spec.rb +++ b/spec/models/status_spec.rb @@ -472,11 +472,53 @@ RSpec.describe Status do end end - describe 'validation' do - it 'disallow empty uri for remote status' do - alice.update(domain: 'example.com') - status = Fabricate.build(:status, uri: '', account: alice) - expect(status).to model_have_error_on_field(:uri) + describe 'Validations' do + context 'with a remote account' do + subject { Fabricate.build :status, account: remote_account } + + let(:remote_account) { Fabricate :account, domain: 'example.com' } + + it { is_expected.to_not allow_value('').for(:uri) } + end + end + + describe 'Callbacks' do + describe 'Stripping content when required' do + context 'with a remote account' do + subject { Fabricate.build :status, local: false, account:, text: ' text ', spoiler_text: ' spoiler ' } + + let(:account) { Fabricate.build :account, domain: 'host.example' } + + it 'preserves content' do + expect { subject.valid? } + .to not_change(subject, :text) + .and not_change(subject, :spoiler_text) + end + end + + context 'with a local account' do + let(:account) { Fabricate.build :account, domain: nil } + + context 'with populated fields' do + subject { Fabricate.build :status, local: true, account:, text: ' text ', spoiler_text: ' spoiler ' } + + it 'strips content' do + expect { subject.valid? } + .to change(subject, :text).to('text') + .and change(subject, :spoiler_text).to('spoiler') + end + end + + context 'with empty fields' do + subject { Fabricate.build :status, local: true, account:, text: nil, spoiler_text: nil } + + it 'preserves content' do + expect { subject.valid? } + .to not_change(subject, :text) + .and not_change(subject, :spoiler_text) + end + end + end end end From ffa10323814b3ea0f15ac9cd2238164e42a873ad Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 14 Oct 2024 15:00:20 +0200 Subject: [PATCH 141/150] Add further warnings about encryption secrets (#32476) --- config/initializers/active_record_encryption.rb | 1 + lib/tasks/db.rake | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/config/initializers/active_record_encryption.rb b/config/initializers/active_record_encryption.rb index b7a874e404..c53f16d4d1 100644 --- a/config/initializers/active_record_encryption.rb +++ b/config/initializers/active_record_encryption.rb @@ -20,6 +20,7 @@ - ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY Run `bin/rails db:encryption:init` to generate new secrets and then assign the environment variables. + Do not change the secrets once they are set, as doing so may cause data loss and other issues that will be difficult or impossible to recover from. MESSAGE end diff --git a/lib/tasks/db.rake b/lib/tasks/db.rake index 79599bd917..73de0c120f 100644 --- a/lib/tasks/db.rake +++ b/lib/tasks/db.rake @@ -7,6 +7,17 @@ namespace :db do namespace :encryption do desc 'Generate a set of keys for configuring Active Record encryption in a given environment' task :init do # rubocop:disable Rails/RakeEnvironment + if %w( + ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY + ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT + ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY + ).any? { |key| ENV.key?(key) } + pastel = Pastel.new + puts pastel.red(<<~MSG) + WARNING: It looks like encryption secrets have already been set. Please ensure you are not changing secrets for a Mastodon installation that already uses them, as this will cause data loss and other issues that are difficult to recover from. + MSG + end + puts <<~MSG Add the following secret environment variables to your Mastodon environment (e.g. .env.production), ensure they are shared across all your nodes and do not change them after they are set:#{' '} From 7c10b0fb7a078661558fef86399d86831423260c Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 14 Oct 2024 17:25:32 +0200 Subject: [PATCH 142/150] Fix follow recommendation carrousel scrolling on RTL layouts (#32462) --- .../components/inline_follow_suggestions.jsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.jsx b/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.jsx index 1b8040e55b..14ea6bd996 100644 --- a/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.jsx +++ b/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.jsx @@ -129,8 +129,13 @@ export const InlineFollowSuggestions = ({ hidden }) => { return; } - setCanScrollLeft(bodyRef.current.scrollLeft > 0); - setCanScrollRight((bodyRef.current.scrollLeft + bodyRef.current.clientWidth) < bodyRef.current.scrollWidth); + if (getComputedStyle(bodyRef.current).direction === 'rtl') { + setCanScrollLeft((bodyRef.current.clientWidth - bodyRef.current.scrollLeft) < bodyRef.current.scrollWidth); + setCanScrollRight(bodyRef.current.scrollLeft < 0); + } else { + setCanScrollLeft(bodyRef.current.scrollLeft > 0); + setCanScrollRight((bodyRef.current.scrollLeft + bodyRef.current.clientWidth) < bodyRef.current.scrollWidth); + } }, [setCanScrollRight, setCanScrollLeft, bodyRef, suggestions]); const handleLeftNav = useCallback(() => { From 6cedbb4c5056818a2c1b6b618d987f46cebf50c8 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 8 Oct 2024 09:21:36 -0400 Subject: [PATCH 143/150] [Glitch] Bring icon vertical middle to applications list style Port fa4a82326d4e33c63a76c6725c36e85fe3ae9310 to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/styles/admin.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss index 9bc3c7758e..fadc678de3 100644 --- a/app/javascript/flavours/glitch/styles/admin.scss +++ b/app/javascript/flavours/glitch/styles/admin.scss @@ -1050,6 +1050,12 @@ a.name-tag, color: var(--user-role-accent); } +.applications-list { + .icon { + vertical-align: middle; + } +} + .announcements-list, .filters-list { border: 1px solid var(--background-border-color); From 39723a4d9cdb321617b25290f09be99d6026641b Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 9 Oct 2024 19:24:22 +0200 Subject: [PATCH 144/150] [Glitch] Fix list edition modal styling Port 45a520603b10792e24a2190215c0305c739108d0 to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/styles/components.scss | 111 ++++++++---------- 1 file changed, 50 insertions(+), 61 deletions(-) diff --git a/app/javascript/flavours/glitch/styles/components.scss b/app/javascript/flavours/glitch/styles/components.scss index 261aaae495..39ee2da242 100644 --- a/app/javascript/flavours/glitch/styles/components.scss +++ b/app/javascript/flavours/glitch/styles/components.scss @@ -8498,7 +8498,6 @@ noscript { justify-content: flex-start; gap: 15px; align-items: center; - border: 1px solid var(--background-border-color); border-top: 0; label { @@ -8525,79 +8524,23 @@ noscript { background: rgba($base-overlay-background, 0.5); } +.list-adder, .list-editor { - background: $ui-base-color; + backdrop-filter: var(--background-filter); + background: var(--modal-background-color); + border: 1px solid var(--modal-border-color); flex-direction: column; border-radius: 8px; - box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4); width: 380px; overflow: hidden; @media screen and (width <= 420px) { width: 90%; } - - h4 { - padding: 15px 0; - background: lighten($ui-base-color, 13%); - font-weight: 500; - font-size: 16px; - text-align: center; - border-radius: 8px 8px 0 0; - } - - .drawer__pager { - height: 50vh; - border-radius: 4px; - } - - .drawer__inner { - border-radius: 0 0 8px 8px; - - &.backdrop { - width: calc(100% - 60px); - box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4); - border-radius: 0 0 0 8px; - } - } - - &__accounts { - overflow-y: auto; - } - - .account__display-name { - &:hover strong { - text-decoration: none; - } - } - - .account__avatar { - cursor: default; - } - - .search { - margin-bottom: 0; - } } .list-adder { - background: $ui-base-color; - flex-direction: column; - border-radius: 8px; - box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4); - width: 380px; - overflow: hidden; - - @media screen and (width <= 420px) { - width: 90%; - } - - &__account { - background: lighten($ui-base-color, 13%); - } - &__lists { - background: lighten($ui-base-color, 13%); height: 50vh; border-radius: 0 0 8px 8px; overflow-y: auto; @@ -8618,6 +8561,52 @@ noscript { text-decoration: none; font-size: 16px; padding: 10px; + display: flex; + align-items: center; + gap: 4px; + } +} + +.list-editor { + h4 { + padding: 15px 0; + background: lighten($ui-base-color, 13%); + font-weight: 500; + font-size: 16px; + text-align: center; + border-radius: 8px 8px 0 0; + } + + .drawer__pager { + height: 50vh; + border: 0; + } + + .drawer__inner { + &.backdrop { + width: calc(100% - 60px); + box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4); + border-radius: 0 0 0 8px; + } + } + + &__accounts { + background: unset; + overflow-y: auto; + } + + .account__display-name { + &:hover strong { + text-decoration: none; + } + } + + .account__avatar { + cursor: default; + } + + .search { + margin-bottom: 0; } } From 1a9be3e0eb045352ce93ff6e7e11cc60202fc867 Mon Sep 17 00:00:00 2001 From: Michael Stanclift Date: Wed, 9 Oct 2024 14:33:28 -0500 Subject: [PATCH 145/150] [Glitch] Restore list column border Port de4f7859b4cf5fc5254173368cf35f0d711331b6 to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/styles/components.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/flavours/glitch/styles/components.scss b/app/javascript/flavours/glitch/styles/components.scss index 39ee2da242..7c2f19bde1 100644 --- a/app/javascript/flavours/glitch/styles/components.scss +++ b/app/javascript/flavours/glitch/styles/components.scss @@ -8498,6 +8498,7 @@ noscript { justify-content: flex-start; gap: 15px; align-items: center; + border: 1px solid var(--background-border-color); border-top: 0; label { From 9b3aaa96095c0f71ea93947c732917ce986c4592 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 10 Oct 2024 13:04:38 +0200 Subject: [PATCH 146/150] =?UTF-8?q?[Glitch]=20Fix=20=E2=80=9CMention?= =?UTF-8?q?=E2=80=9D=20appearing=20for=20otherwise=20filtered=20posts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port f75eb1a8b0386d2ca5c1c05ee3b10364b3e11211 to glitch-soc Signed-off-by: Claire --- .../components/notification_with_status.tsx | 9 +++- .../flavours/glitch/selectors/filters.ts | 50 +++++++++++++++++++ .../flavours/glitch/selectors/index.js | 15 +----- 3 files changed, 60 insertions(+), 14 deletions(-) create mode 100644 app/javascript/flavours/glitch/selectors/filters.ts diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/notification_with_status.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_with_status.tsx index 941b1254f7..4f45189e59 100644 --- a/app/javascript/flavours/glitch/features/notifications_v2/components/notification_with_status.tsx +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_with_status.tsx @@ -16,6 +16,7 @@ import { import type { IconProp } from 'flavours/glitch/components/icon'; import { Icon } from 'flavours/glitch/components/icon'; import Status from 'flavours/glitch/containers/status_container'; +import { getStatusHidden } from 'flavours/glitch/selectors/filters'; import { useAppSelector, useAppDispatch } from 'flavours/glitch/store'; import { DisplayedName } from './displayed_name'; @@ -51,6 +52,12 @@ export const NotificationWithStatus: React.FC<{ (state) => state.statuses.getIn([statusId, 'visibility']) === 'direct', ); + const isFiltered = useAppSelector( + (state) => + statusId && + getStatusHidden(state, { id: statusId, contextType: 'notifications' }), + ); + const handlers = useMemo( () => ({ open: () => { @@ -77,7 +84,7 @@ export const NotificationWithStatus: React.FC<{ [dispatch, statusId], ); - if (!statusId) return null; + if (!statusId || isFiltered) return null; return ( diff --git a/app/javascript/flavours/glitch/selectors/filters.ts b/app/javascript/flavours/glitch/selectors/filters.ts new file mode 100644 index 0000000000..5d7bfcbdc7 --- /dev/null +++ b/app/javascript/flavours/glitch/selectors/filters.ts @@ -0,0 +1,50 @@ +import { createSelector } from '@reduxjs/toolkit'; + +import type { RootState } from 'flavours/glitch/store'; +import { toServerSideType } from 'flavours/glitch/utils/filters'; + +// TODO: move to `app/javascript/flavours/glitch/models` and use more globally +type Filter = Immutable.Map; + +// TODO: move to `app/javascript/flavours/glitch/models` and use more globally +type FilterResult = Immutable.Map; + +export const getFilters = createSelector( + [ + (state: RootState) => state.filters as Immutable.Map, + (_, { contextType }: { contextType: string }) => contextType, + ], + (filters, contextType) => { + if (!contextType) { + return null; + } + + const now = new Date(); + const serverSideType = toServerSideType(contextType); + + return filters.filter((filter) => { + const context = filter.get('context') as Immutable.List; + const expiration = filter.get('expires_at') as Date | null; + return ( + context.includes(serverSideType) && + (expiration === null || expiration > now) + ); + }); + }, +); + +export const getStatusHidden = ( + state: RootState, + { id, contextType }: { id: string; contextType: string }, +) => { + const filters = getFilters(state, { contextType }); + if (filters === null) return false; + + const filtered = state.statuses.getIn([id, 'filtered']) as + | Immutable.List + | undefined; + return filtered?.some( + (result) => + filters.getIn([result.get('filter'), 'filter_action']) === 'hide', + ); +}; diff --git a/app/javascript/flavours/glitch/selectors/index.js b/app/javascript/flavours/glitch/selectors/index.js index 1b2d63ae36..7c9a68cba4 100644 --- a/app/javascript/flavours/glitch/selectors/index.js +++ b/app/javascript/flavours/glitch/selectors/index.js @@ -1,23 +1,12 @@ import { createSelector } from '@reduxjs/toolkit'; import { List as ImmutableList, Map as ImmutableMap } from 'immutable'; -import { toServerSideType } from 'flavours/glitch/utils/filters'; - import { me } from '../initial_state'; +import { getFilters } from './filters'; + export { makeGetAccount } from "./accounts"; -const getFilters = createSelector([state => state.get('filters'), (_, { contextType }) => contextType], (filters, contextType) => { - if (!contextType) { - return null; - } - - const now = new Date(); - const serverSideType = toServerSideType(contextType); - - return filters.filter(filter => filter.get('context').includes(serverSideType) && (filter.get('expires_at') === null || filter.get('expires_at') > now)); -}); - export const makeGetStatus = () => { return createSelector( [ From 71a6ced55cc13f7e23e53623b0fbf2c1871a2245 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 10 Oct 2024 15:42:08 +0200 Subject: [PATCH 147/150] =?UTF-8?q?[Glitch]=20Fix=20=E2=80=9CMark=20every?= =?UTF-8?q?=20notification=20as=20read=E2=80=9D=20not=20updating=20the=20r?= =?UTF-8?q?ead=20marker=20if=20scrolled=20down?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port e018e6321feb97609b18ac61d3349beb6de170b5 to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/reducers/notification_groups.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/reducers/notification_groups.ts b/app/javascript/flavours/glitch/reducers/notification_groups.ts index 3eece4b1d0..d1dacc7964 100644 --- a/app/javascript/flavours/glitch/reducers/notification_groups.ts +++ b/app/javascript/flavours/glitch/reducers/notification_groups.ts @@ -559,7 +559,10 @@ export const notificationGroupsReducer = createReducer( compareId(state.lastReadId, mostRecentGroup.page_max_id) < 0 ) state.lastReadId = mostRecentGroup.page_max_id; - commitLastReadId(state); + + // We don't call `commitLastReadId`, because that is conditional + // and we want to unconditionally update the state instead. + state.readMarkerId = state.lastReadId; }) .addCase(fetchMarkers.fulfilled, (state, action) => { if ( From 075eb3ed389e46241811be79c8399485291acc4a Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 10 Oct 2024 16:53:12 +0200 Subject: [PATCH 148/150] [Glitch] Fix mute duration not being shown in list of muted accounts in web UI Port a295832960f3a782b928145279af335f956fff1f to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/api_types/accounts.ts | 11 ++++++++++- app/javascript/flavours/glitch/models/account.ts | 3 +++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/api_types/accounts.ts b/app/javascript/flavours/glitch/api_types/accounts.ts index 5bf3e64288..fdbd7523fc 100644 --- a/app/javascript/flavours/glitch/api_types/accounts.ts +++ b/app/javascript/flavours/glitch/api_types/accounts.ts @@ -13,7 +13,7 @@ export interface ApiAccountRoleJSON { } // See app/serializers/rest/account_serializer.rb -export interface ApiAccountJSON { +export interface BaseApiAccountJSON { acct: string; avatar: string; avatar_static: string; @@ -45,3 +45,12 @@ export interface ApiAccountJSON { memorial?: boolean; hide_collections: boolean; } + +// See app/serializers/rest/muted_account_serializer.rb +export interface ApiMutedAccountJSON extends BaseApiAccountJSON { + mute_expires_at?: string | null; +} + +// For now, we have the same type representing both `Account` and `MutedAccount` +// objects, but we should refactor this in the future. +export type ApiAccountJSON = ApiMutedAccountJSON; diff --git a/app/javascript/flavours/glitch/models/account.ts b/app/javascript/flavours/glitch/models/account.ts index 0b698ead3d..799265831e 100644 --- a/app/javascript/flavours/glitch/models/account.ts +++ b/app/javascript/flavours/glitch/models/account.ts @@ -95,6 +95,9 @@ export const accountDefaultValues: AccountShape = { limited: false, moved: null, hide_collections: false, + // This comes from `ApiMutedAccountJSON`, but we should eventually + // store that in a different object. + mute_expires_at: null, }; const AccountFactory = ImmutableRecord(accountDefaultValues); From ab50b2613e0faf19a3b68def947eb557db267102 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 14 Oct 2024 17:25:32 +0200 Subject: [PATCH 149/150] [Glitch] Fix follow recommendation carrousel scrolling on RTL layouts Port 7c10b0fb7a078661558fef86399d86831423260c to glitch-soc Signed-off-by: Claire --- .../components/inline_follow_suggestions.jsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/javascript/flavours/glitch/features/home_timeline/components/inline_follow_suggestions.jsx b/app/javascript/flavours/glitch/features/home_timeline/components/inline_follow_suggestions.jsx index 4e727a63ed..4dc47f7515 100644 --- a/app/javascript/flavours/glitch/features/home_timeline/components/inline_follow_suggestions.jsx +++ b/app/javascript/flavours/glitch/features/home_timeline/components/inline_follow_suggestions.jsx @@ -129,8 +129,13 @@ export const InlineFollowSuggestions = ({ hidden }) => { return; } - setCanScrollLeft(bodyRef.current.scrollLeft > 0); - setCanScrollRight((bodyRef.current.scrollLeft + bodyRef.current.clientWidth) < bodyRef.current.scrollWidth); + if (getComputedStyle(bodyRef.current).direction === 'rtl') { + setCanScrollLeft((bodyRef.current.clientWidth - bodyRef.current.scrollLeft) < bodyRef.current.scrollWidth); + setCanScrollRight(bodyRef.current.scrollLeft < 0); + } else { + setCanScrollLeft(bodyRef.current.scrollLeft > 0); + setCanScrollRight((bodyRef.current.scrollLeft + bodyRef.current.clientWidth) < bodyRef.current.scrollWidth); + } }, [setCanScrollRight, setCanScrollLeft, bodyRef, suggestions]); const handleLeftNav = useCallback(() => { From a7f9a34d89d206812ebc2cc995b6993d7e43bb39 Mon Sep 17 00:00:00 2001 From: Noa Himesaka Date: Thu, 17 Oct 2024 00:31:57 +0900 Subject: [PATCH 150/150] use YuruToot theme color --- app/helpers/theme_helper.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/helpers/theme_helper.rb b/app/helpers/theme_helper.rb index c5d226f70e..1a6362792e 100644 --- a/app/helpers/theme_helper.rb +++ b/app/helpers/theme_helper.rb @@ -19,11 +19,11 @@ module ThemeHelper if theme == 'system' ''.html_safe.tap do |tags| - tags << tag.meta(name: 'theme-color', content: Themes::THEME_COLORS[:dark], media: '(prefers-color-scheme: dark)') - tags << tag.meta(name: 'theme-color', content: Themes::THEME_COLORS[:light], media: '(prefers-color-scheme: light)') + tags << tag.meta(name: 'theme-color', content: '#787878', media: '(prefers-color-scheme: dark)') + tags << tag.meta(name: 'theme-color', content: '#787878', media: '(prefers-color-scheme: light)') end else - tag.meta name: 'theme-color', content: theme_color_for(theme) + tag.meta name: 'theme-color', content: '#787878' end end