From 357ca69dc037a0543118604bc6dae270319ec827 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Mar 2022 09:34:57 +0900 Subject: Bump rubocop-rails from 2.13.2 to 2.14.0 (#17790) Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.13.2 to 2.14.0. - [Release notes](https://github.com/rubocop/rubocop-rails/releases) - [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.13.2...v2.14.0) --- updated-dependencies: - dependency-name: rubocop-rails dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index 44f11c84f..39fa3f3e8 100644 --- a/Gemfile +++ b/Gemfile @@ -133,7 +133,7 @@ group :development do gem 'letter_opener_web', '~> 2.0' gem 'memory_profiler' gem 'rubocop', '~> 1.25', require: false - gem 'rubocop-rails', '~> 2.13', require: false + gem 'rubocop-rails', '~> 2.14', require: false gem 'brakeman', '~> 5.2', require: false gem 'bundler-audit', '~> 0.9', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 610503749..1e42cb48e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -432,7 +432,7 @@ GEM orm_adapter (0.5.0) ox (2.14.10) parallel (1.21.0) - parser (3.1.0.0) + parser (3.1.1.0) ast (~> 2.4.1) parslet (2.0.0) pastel (0.8.0) @@ -524,7 +524,7 @@ GEM redis (4.5.1) redis-namespace (1.8.2) redis (>= 3.0.4) - regexp_parser (2.2.0) + regexp_parser (2.2.1) request_store (1.5.0) rack (>= 1.4) responders (3.0.1) @@ -568,9 +568,9 @@ GEM rubocop-ast (>= 1.15.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.15.1) - parser (>= 3.0.1.1) - rubocop-rails (2.13.2) + rubocop-ast (1.16.0) + parser (>= 3.1.1.0) + rubocop-rails (2.14.0) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.7.0, < 2.0) @@ -815,7 +815,7 @@ DEPENDENCIES rspec-sidekiq (~> 3.1) rspec_junit_formatter (~> 0.5) rubocop (~> 1.25) - rubocop-rails (~> 2.13) + rubocop-rails (~> 2.14) ruby-progressbar (~> 1.11) sanitize (~> 6.0) scenic (~> 1.6) -- cgit From bf846543452f341dd0d96bd3f263ebf0707a8458 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Mar 2022 09:51:58 +0900 Subject: Bump rubocop from 1.25.1 to 1.26.0 (#17789) Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.25.1 to 1.26.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.25.1...v1.26.0) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 39fa3f3e8..536470c7d 100644 --- a/Gemfile +++ b/Gemfile @@ -132,7 +132,7 @@ group :development do gem 'letter_opener', '~> 1.7' gem 'letter_opener_web', '~> 2.0' gem 'memory_profiler' - gem 'rubocop', '~> 1.25', require: false + gem 'rubocop', '~> 1.26', require: false gem 'rubocop-rails', '~> 2.14', require: false gem 'brakeman', '~> 5.2', require: false gem 'bundler-audit', '~> 0.9', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 1e42cb48e..da4070dee 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -559,13 +559,13 @@ GEM rspec-support (3.11.0) rspec_junit_formatter (0.5.1) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (1.25.1) + rubocop (1.26.0) parallel (~> 1.10) parser (>= 3.1.0.0) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml - rubocop-ast (>= 1.15.1, < 2.0) + rubocop-ast (>= 1.16.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 3.0) rubocop-ast (1.16.0) @@ -814,7 +814,7 @@ DEPENDENCIES rspec-rails (~> 5.1) rspec-sidekiq (~> 3.1) rspec_junit_formatter (~> 0.5) - rubocop (~> 1.25) + rubocop (~> 1.26) rubocop-rails (~> 2.14) ruby-progressbar (~> 1.11) sanitize (~> 6.0) -- cgit From 3349cbeb3ed0edc118b5c66270367b3ca03b93b2 Mon Sep 17 00:00:00 2001 From: Jeong Arm Date: Sat, 19 Mar 2022 17:24:08 +0900 Subject: Fix clean_discarded_statuses (#17822) --- app/workers/scheduler/user_cleanup_scheduler.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/workers/scheduler/user_cleanup_scheduler.rb b/app/workers/scheduler/user_cleanup_scheduler.rb index 750d2127b..d1f00c47f 100644 --- a/app/workers/scheduler/user_cleanup_scheduler.rb +++ b/app/workers/scheduler/user_cleanup_scheduler.rb @@ -27,7 +27,7 @@ class Scheduler::UserCleanupScheduler end def clean_discarded_statuses! - Status.discarded.where('deleted_at <= ?', 30.days.ago).find_in_batches do |statuses| + Status.unscoped.discarded.where('deleted_at <= ?', 30.days.ago).find_in_batches do |statuses| RemovalWorker.push_bulk(statuses) do |status| [status.id, { 'immediate' => true }] end -- cgit From 8ee4fde19b1a9bd55d9ff9c8c0d0e6a3546c6782 Mon Sep 17 00:00:00 2001 From: Daniel Jakots Date: Sat, 19 Mar 2022 04:24:26 -0400 Subject: Bump NODE_VER to 16.14.2 (#17825) See the announcement https://nodejs.org/en/blog/vulnerability/mar-2022-security-releases/ --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 1b3661561..2073cbebf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ SHELL ["/bin/bash", "-c"] RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections # Install Node v16 (LTS) -ENV NODE_VER="16.13.2" +ENV NODE_VER="16.14.2" RUN ARCH= && \ dpkgArch="$(dpkg --print-architecture)" && \ case "${dpkgArch##*-}" in \ -- cgit From c0e3b20c58cefd3625bb3c96544ddc2d53a7439c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Mar 2022 16:23:01 +0100 Subject: New Crowdin updates (#17817) * New translations devise.en.yml (Danish) * New translations devise.en.yml (Danish) * New translations devise.en.yml (Danish) * New translations devise.en.yml (Danish) * New translations devise.en.yml (Danish) * New translations devise.en.yml (Danish) * New translations en.json (Vietnamese) * New translations en.yml (Vietnamese) * New translations doorkeeper.en.yml (Vietnamese) * New translations en.yml (Vietnamese) * New translations en.json (Vietnamese) * New translations en.yml (Vietnamese) * New translations en.yml (Vietnamese) * New translations en.json (Russian) * New translations en.yml (Japanese) * New translations en.yml (Japanese) * New translations en.json (Japanese) * New translations en.yml (Japanese) * New translations en.json (Catalan) * New translations en.json (Slovak) * New translations en.yml (Slovak) * New translations en.json (Catalan) * New translations en.json (Slovak) * New translations en.json (Catalan) * New translations simple_form.en.yml (Slovak) * New translations doorkeeper.en.yml (Slovak) * New translations devise.en.yml (Catalan) * New translations devise.en.yml (Catalan) * New translations doorkeeper.en.yml (Catalan) * New translations devise.en.yml (Catalan) * New translations doorkeeper.en.yml (Catalan) * New translations en.yml (Catalan) * New translations en.yml (Catalan) * New translations simple_form.en.yml (Thai) * New translations en.yml (Thai) * New translations en.json (Ukrainian) * New translations devise.en.yml (Danish) * New translations doorkeeper.en.yml (Danish) * New translations devise.en.yml (Danish) * New translations en.yml (Kurmanji (Kurdish)) * New translations en.yml (Kurmanji (Kurdish)) * New translations en.yml (Kurmanji (Kurdish)) * New translations en.yml (Ukrainian) * New translations doorkeeper.en.yml (Ukrainian) * New translations en.yml (Vietnamese) * New translations doorkeeper.en.yml (Danish) * New translations en.yml (Vietnamese) * New translations doorkeeper.en.yml (Danish) * New translations doorkeeper.en.yml (Danish) * New translations doorkeeper.en.yml (Danish) * New translations doorkeeper.en.yml (Danish) * New translations doorkeeper.en.yml (Danish) * New translations en.json (Persian) * New translations en.json (Persian) * New translations en.yml (Japanese) * New translations en.yml (Vietnamese) * New translations en.json (Vietnamese) * New translations en.json (Japanese) * New translations en.json (Japanese) * New translations simple_form.en.yml (Japanese) * New translations simple_form.en.yml (Japanese) * New translations en.json (Russian) * New translations en.json (Russian) * New translations en.json (Russian) * New translations en.yml (Thai) * New translations en.yml (Thai) * New translations simple_form.en.yml (Thai) * New translations en.yml (Thai) * Run `bundle exec i18n-tasks normalize` * Run `yarn manage:translations` Co-authored-by: Yamagishi Kazutoshi --- app/javascript/mastodon/locales/ca.json | 24 ++++++------ app/javascript/mastodon/locales/fa.json | 46 +++++++++++----------- app/javascript/mastodon/locales/ja.json | 22 +++++------ app/javascript/mastodon/locales/ru.json | 32 ++++++++-------- app/javascript/mastodon/locales/sk.json | 8 ++-- app/javascript/mastodon/locales/uk.json | 10 ++--- app/javascript/mastodon/locales/vi.json | 20 +++++----- config/locales/ca.yml | 22 +++++------ config/locales/devise.ca.yml | 32 ++++++++-------- config/locales/devise.da.yml | 34 ++++++++--------- config/locales/doorkeeper.ca.yml | 22 +++++------ config/locales/doorkeeper.da.yml | 68 ++++++++++++++++----------------- config/locales/doorkeeper.sk.yml | 1 + config/locales/doorkeeper.uk.yml | 4 ++ config/locales/doorkeeper.vi.yml | 8 ++-- config/locales/ja.yml | 10 +++-- config/locales/ku.yml | 12 +++--- config/locales/simple_form.ja.yml | 7 ++++ config/locales/simple_form.sk.yml | 3 ++ config/locales/simple_form.th.yml | 2 + config/locales/sk.yml | 2 + config/locales/th.yml | 8 ++++ config/locales/uk.yml | 18 ++++++++- config/locales/vi.yml | 48 +++++++++++------------ 24 files changed, 255 insertions(+), 208 deletions(-) diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index 287fd0771..055732cfd 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -328,7 +328,7 @@ "notifications.column_settings.filter_bar.category": "Barra ràpida de filtres", "notifications.column_settings.filter_bar.show_bar": "Mostra la barra de filtres", "notifications.column_settings.follow": "Nous seguidors:", - "notifications.column_settings.follow_request": "Nova sol·licitud de seguiment:", + "notifications.column_settings.follow_request": "Noves sol·licituts de seguiment:", "notifications.column_settings.mention": "Mencions:", "notifications.column_settings.poll": "Resultats de l’enquesta:", "notifications.column_settings.push": "Notificacions push", @@ -353,7 +353,7 @@ "notifications.permission_denied_alert": "No es poden activar les notificacions del escriptori perquè el permís del navegador ha estat denegat abans", "notifications.permission_required": "Les notificacions d'escriptori no estan disponibles perquè el permís requerit no ha estat concedit.", "notifications_permission_banner.enable": "Activar les notificacions d’escriptori", - "notifications_permission_banner.how_to_control": "Per a rebre notificacions quan Mastodon no està obert cal activar les notificacions d’escriptori. Pots controlar amb precisió quins tipus d’interaccions generen notificacions d’escriptori després d’activar el botó {icon} de dalt.", + "notifications_permission_banner.how_to_control": "Per a rebre notificacions quan Mastodon no és obert cal activar les notificacions d’escriptori. Pots controlar amb precisió quins tipus d’interaccions generen notificacions d’escriptori després d’activar el botó {icon} de dalt.", "notifications_permission_banner.title": "Mai et perdis res", "picture_in_picture.restore": "Retorna’l", "poll.closed": "Finalitzada", @@ -376,7 +376,7 @@ "privacy.unlisted.short": "No llistat", "refresh": "Actualitza", "regeneration_indicator.label": "Carregant…", - "regeneration_indicator.sublabel": "S'està preparant la línia de temps Inici!", + "regeneration_indicator.sublabel": "S'està preparant la teva línia de temps Inici!", "relative_time.days": "fa {number} dies", "relative_time.full.days": "fa {number, plural, one {# dia} other {# dies}}", "relative_time.full.hours": "fa {number, plural, one {# hora} other {# hores}}", @@ -394,7 +394,7 @@ "report.categories.other": "Altres", "report.categories.spam": "Contingut brossa", "report.categories.violation": "El contingut viola una o més regles del servidor", - "report.category.subtitle": "Tria la millor combinació", + "report.category.subtitle": "Tria la millor coincidència", "report.category.title": "Digue'ns què està passant amb aquest {type}", "report.category.title_account": "perfil", "report.category.title_status": "publicació", @@ -410,7 +410,7 @@ "report.reasons.dislike_description": "Això no és quelcom que vulguis veure", "report.reasons.other": "Això és una altre cosa", "report.reasons.other_description": "El problema no encaixa en altres categories", - "report.reasons.spam": "Això és brossa", + "report.reasons.spam": "Això és contingut brossa", "report.reasons.spam_description": "Enllaços maliciosos, compromís falç o respostes repetitives", "report.reasons.violation": "Viola les regles del servidor", "report.reasons.violation_description": "Ets conscient que trenca regles especifiques", @@ -447,7 +447,7 @@ "status.cancel_reblog_private": "Desfer l'impuls", "status.cannot_reblog": "Aquesta publicació no pot ser impulsada", "status.copy": "Copia l'enllaç a l'estat", - "status.delete": "Esborrar", + "status.delete": "Esborra", "status.detailed_status": "Visualització detallada de la conversa", "status.direct": "Missatge directe @{name}", "status.edit": "Edita", @@ -465,17 +465,17 @@ "status.mute": "Silenciar @{name}", "status.mute_conversation": "Silenciar conversació", "status.open": "Ampliar aquest estat", - "status.pin": "Fixat en el perfil", + "status.pin": "Fixa en el perfil", "status.pinned": "Publicació fixada", "status.read_more": "Llegir més", "status.reblog": "Impuls", - "status.reblog_private": "Impulsar a l'audiència original", + "status.reblog_private": "Impulsar amb la visibilitat original", "status.reblogged_by": "{name} ha impulsat", "status.reblogs.empty": "Encara ningú no ha impulsat aquesta publicació. Quan algú ho faci, apareixeran aquí.", "status.redraft": "Esborrar i reescriure", "status.remove_bookmark": "Suprimeix el marcador", "status.reply": "Respondre", - "status.replyAll": "Respondre al tema", + "status.replyAll": "Respondre al fil", "status.report": "Informar sobre @{name}", "status.sensitive_warning": "Contingut sensible", "status.share": "Compartir", @@ -510,11 +510,11 @@ "units.short.million": "{count}M", "units.short.thousand": "{count}K", "upload_area.title": "Arrossega i deixa anar per a carregar", - "upload_button.label": "Afegir multimèdia (JPEG, PNG, GIF, WebM, MP4, MOV)", + "upload_button.label": "Afegir mèdia, un vídeo o un fitxer d'audio", "upload_error.limit": "S'ha superat el límit de càrrega d'arxius.", "upload_error.poll": "No es permet l'enviament de fitxers en les enquestes.", "upload_form.audio_description": "Descriviu per a les persones amb pèrdua auditiva", - "upload_form.description": "Descriure els problemes visuals", + "upload_form.description": "Descriure per els que tenen problemes visuals", "upload_form.edit": "Edita", "upload_form.thumbnail": "Canvia la miniatura", "upload_form.undo": "Esborra", @@ -523,7 +523,7 @@ "upload_modal.apply": "Aplica", "upload_modal.applying": "Aplicant…", "upload_modal.choose_image": "Tria imatge", - "upload_modal.description_placeholder": "Jove xef, porti whisky amb quinze glaçons d’hidrogen, coi!", + "upload_modal.description_placeholder": "Una ràpida guineu marró salta sobre el gos mandrós", "upload_modal.detect_text": "Detecta el text de l'imatge", "upload_modal.edit_media": "Editar multimèdia", "upload_modal.hint": "Fes clic o arrossega el cercle en la previsualització per escollir el punt focal que sempre serà visible de totes les miniatures.", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index 659336393..820b90640 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -18,7 +18,7 @@ "account.followers": "پی‌گیرندگان", "account.followers.empty": "هنوز کسی این کاربر را پی‌گیری نمی‌کند.", "account.followers_counter": "{count, plural, one {{counter} پی‌گیرنده} other {{counter} پی‌گیرنده}}", - "account.following": "Following", + "account.following": "پی می‌گیرید", "account.following_counter": "{count, plural, one {{counter} پی‌گرفته} other {{counter} پی‌گرفته}}", "account.follows.empty": "این کاربر هنوز پی‌گیر کسی نیست.", "account.follows_you": "پی می‌گیردتان", @@ -41,12 +41,12 @@ "account.statuses_counter": "{count, plural, one {{counter} فرسته} other {{counter} فرسته}}", "account.unblock": "رفع مسدودیت @{name}", "account.unblock_domain": "رفع مسدودیت دامنهٔ {domain}", - "account.unblock_short": "Unblock", + "account.unblock_short": "رفع مسدودیت", "account.unendorse": "معرّفی نکردن در نمایه", "account.unfollow": "ناپی‌گیری", "account.unmute": "ناخموشی @{name}", "account.unmute_notifications": "ناخموشی آگاهی‌ها از @{name}", - "account.unmute_short": "Unmute", + "account.unmute_short": "ناخموشی", "account_note.placeholder": "برای افزودن یادداشت کلیک کنید", "admin.dashboard.daily_retention": "User retention rate by day after sign-up", "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", @@ -106,7 +106,7 @@ "compose_form.poll.switch_to_single": "تبدیل به نظرسنجی تک‌گزینه‌ای", "compose_form.publish": "بوق", "compose_form.publish_loud": "{publish}!", - "compose_form.save_changes": "Save changes", + "compose_form.save_changes": "ذخیرهٔ تغییرات", "compose_form.sensitive.hide": "{count, plural, one {علامت‌گذاری رسانه به عنوان حساس} other {علامت‌گذاری رسانه‌ها به عنوان حساس}}", "compose_form.sensitive.marked": "{count, plural, one {رسانه به عنوان حساس علامت‌گذاری شد} other {رسانه‌ها به عنوان حساس علامت‌گذاری شدند}}", "compose_form.sensitive.unmarked": "{count, plural, one {رسانه به عنوان حساس علامت‌گذاری نشد} other {رسانه‌ها به عنوان حساس علامت‌گذاری نشدند}}", @@ -187,12 +187,12 @@ "error.unexpected_crash.next_steps_addons": "لطفاً از کارشان انداخته و صفحه را نوسازی کنید. اگر کمکی نکرد، شاید همچنان بتوانید با مرورگری دیگر یا با کاره‌ای بومی از ماستودون استفاده کنید.", "errors.unexpected_crash.copy_stacktrace": "رونوشت از جزئیات اشکال", "errors.unexpected_crash.report_issue": "گزارش مشکل", - "explore.search_results": "Search results", - "explore.suggested_follows": "For you", - "explore.title": "Explore", - "explore.trending_links": "News", - "explore.trending_statuses": "Posts", - "explore.trending_tags": "Hashtags", + "explore.search_results": "نتایج جست‌وجو", + "explore.suggested_follows": "برای شما", + "explore.title": "کاوش", + "explore.trending_links": "اخبار", + "explore.trending_statuses": "فرسته‌ها", + "explore.trending_tags": "هشتگ‌ها", "follow_recommendations.done": "انجام شد", "follow_recommendations.heading": "افرادی را که می‌خواهید فرسته‌هایشان را ببینید پی‌گیری کنید! این‌ها تعدادی پیشنهاد هستند.", "follow_recommendations.lead": "فرسته‌های افرادی که دنبال می‌کنید به ترتیب زمانی در خوراک خانه‌تان نشان داده خواهد شد. از اشتباه کردن نترسید. می‌توانید به همین سادگی در هر زمانی از دنبال کردن افراد دست بکشید!", @@ -294,7 +294,7 @@ "navigation_bar.discover": "گشت و گذار", "navigation_bar.domain_blocks": "دامنه‌های مسدود شده", "navigation_bar.edit_profile": "ویرایش نمایه", - "navigation_bar.explore": "Explore", + "navigation_bar.explore": "کاوش", "navigation_bar.favourites": "پسندیده‌ها", "navigation_bar.filters": "واژه‌های خموش", "navigation_bar.follow_requests": "درخواست‌های پی‌گیری", @@ -309,7 +309,7 @@ "navigation_bar.preferences": "ترجیحات", "navigation_bar.public_timeline": "خط زمانی همگانی", "navigation_bar.security": "امنیت", - "notification.admin.sign_up": "{name} signed up", + "notification.admin.sign_up": "{name} ثبت نام کرد", "notification.favourite": "‫{name}‬ فرسته‌تان را پسندید", "notification.follow": "‫{name}‬ پی‌گیرتان شد", "notification.follow_request": "{name} می‌خواهد پی‌گیر شما باشد", @@ -318,10 +318,10 @@ "notification.poll": "نظرسنجی‌ای که در آن رأی دادید به پایان رسیده است", "notification.reblog": "‫{name}‬ فرسته‌تان را تقویت کرد", "notification.status": "{name} چیزی فرستاد", - "notification.update": "{name} edited a post", + "notification.update": "{name} فرسته‌ای را ویرایش کرد", "notifications.clear": "پاک‌سازی آگاهی‌ها", "notifications.clear_confirmation": "مطمئنید می‌خواهید همهٔ آگاهی‌هایتان را برای همیشه پاک کنید؟", - "notifications.column_settings.admin.sign_up": "New sign-ups:", + "notifications.column_settings.admin.sign_up": "ثبت نام‌های جدید:", "notifications.column_settings.alert": "آگاهی‌های میزکار", "notifications.column_settings.favourite": "پسندیده‌ها:", "notifications.column_settings.filter_bar.advanced": "نمایش همۀ دسته‌ها", @@ -338,7 +338,7 @@ "notifications.column_settings.status": "فرسته‌های جدید:", "notifications.column_settings.unread_notifications.category": "آگاهی‌های خوانده نشده", "notifications.column_settings.unread_notifications.highlight": "پررنگ کردن آگاهی‌های خوانده نشده", - "notifications.column_settings.update": "Edits:", + "notifications.column_settings.update": "ویرایش‌ها:", "notifications.filter.all": "همه", "notifications.filter.boosts": "تقویت‌ها", "notifications.filter.favourites": "پسندها", @@ -378,20 +378,20 @@ "regeneration_indicator.label": "در حال بار شدن…", "regeneration_indicator.sublabel": "خوراک خانگیان دارد آماده می‌شود!", "relative_time.days": "{number} روز", - "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", - "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", - "relative_time.full.just_now": "just now", - "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", - "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", + "relative_time.full.days": "{number, plural, one {# روز} other {# روز}} پیش", + "relative_time.full.hours": "{number, plural, one {# ساعت} other {# ساعت}} پیش", + "relative_time.full.just_now": "همين آلان", + "relative_time.full.minutes": "{number, plural, one {# دقیقه} other {# دقیقه}} پیش", + "relative_time.full.seconds": "{number, plural, one {# ثانیه} other {# ثانیه}} پیش", "relative_time.hours": "{number} ساعت", "relative_time.just_now": "حالا", "relative_time.minutes": "{number} دقیقه", "relative_time.seconds": "{number} ثانیه", "relative_time.today": "امروز", "reply_indicator.cancel": "لغو", - "report.block": "Block", - "report.block_explanation": "You will not see their posts. They will not be able to see your posts or follow you. They will be able to tell that they are blocked.", - "report.categories.other": "Other", + "report.block": "مسدود کردن", + "report.block_explanation": "شما فرسته‌هایشان را نخواهید دید. آن‌ها نمی‌توانند فرسته‌هایتان را ببینند یا شما را پی‌بگیرند. آنها می‌توانند بگویند که مسدود شده‌اند.", + "report.categories.other": "غیره", "report.categories.spam": "Spam", "report.categories.violation": "Content violates one or more server rules", "report.category.subtitle": "Choose the best match", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index d8e62b621..8c7878a84 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -18,7 +18,7 @@ "account.followers": "フォロワー", "account.followers.empty": "まだ誰もフォローしていません。", "account.followers_counter": "{counter} フォロワー", - "account.following": "Following", + "account.following": "フォロー中", "account.following_counter": "{counter} フォロー", "account.follows.empty": "まだ誰もフォローしていません。", "account.follows_you": "フォローされています", @@ -41,12 +41,12 @@ "account.statuses_counter": "{counter} 投稿", "account.unblock": "@{name}さんのブロックを解除", "account.unblock_domain": "{domain}のブロックを解除", - "account.unblock_short": "Unblock", + "account.unblock_short": "ブロック解除", "account.unendorse": "プロフィールから外す", "account.unfollow": "フォロー解除", "account.unmute": "@{name}さんのミュートを解除", "account.unmute_notifications": "@{name}さんからの通知を受け取るようにする", - "account.unmute_short": "Unmute", + "account.unmute_short": "ミュート解除", "account_note.placeholder": "クリックしてメモを追加", "admin.dashboard.daily_retention": "サインアップ後の日ごとのユーザー継続率", "admin.dashboard.monthly_retention": "サインアップ後の月ごとのユーザー継続率", @@ -188,7 +188,7 @@ "errors.unexpected_crash.copy_stacktrace": "スタックトレースをクリップボードにコピー", "errors.unexpected_crash.report_issue": "問題を報告", "explore.search_results": "検索結果", - "explore.suggested_follows": "For you", + "explore.suggested_follows": "あなたに", "explore.title": "エクスプローラー", "explore.trending_links": "ニュース", "explore.trending_statuses": "投稿", @@ -321,7 +321,7 @@ "notification.update": "{name} が投稿を編集しました", "notifications.clear": "通知を消去", "notifications.clear_confirmation": "本当に通知を消去しますか?", - "notifications.column_settings.admin.sign_up": "New sign-ups:", + "notifications.column_settings.admin.sign_up": "新規登録:", "notifications.column_settings.alert": "デスクトップ通知", "notifications.column_settings.favourite": "お気に入り:", "notifications.column_settings.filter_bar.advanced": "すべてのカテゴリを表示", @@ -390,7 +390,7 @@ "relative_time.today": "今日", "reply_indicator.cancel": "キャンセル", "report.block": "ブロック", - "report.block_explanation": "You will not see their posts. They will not be able to see your posts or follow you. They will be able to tell that they are blocked.", + "report.block_explanation": "相手の投稿が表示されなくなります。相手はあなたの投稿を見ることやフォローすることができません。相手はブロックされていることがわかります。", "report.categories.other": "その他", "report.categories.spam": "スパム", "report.categories.violation": "サーバーのルールに違反", @@ -399,11 +399,11 @@ "report.category.title_account": "プロフィール", "report.category.title_status": "投稿", "report.close": "完了", - "report.comment.title": "Is there anything else you think we should know?", + "report.comment.title": "その他に私たちに伝えておくべき事はありますか?", "report.forward": "{target} に転送する", "report.forward_hint": "このアカウントは別のサーバーに所属しています。通報内容を匿名で転送しますか?", "report.mute": "ミュート", - "report.mute_explanation": "You will not see their posts. They can still follow you and see your posts and will not know that they are muted.", + "report.mute_explanation": "相手の投稿は表示されなくなります。相手は引き続きあなたをフォローして、あなたの投稿を表示することができますが、ミュートされていることはわかりません。", "report.next": "次へ", "report.placeholder": "追加コメント", "report.reasons.dislike": "興味がありません", @@ -421,9 +421,9 @@ "report.submit": "通報する", "report.target": "{target}さんを通報する", "report.thanks.take_action": "次のような方法はいかがでしょうか?", - "report.thanks.take_action_actionable": "While we review this, you can take action against @{name}:", + "report.thanks.take_action_actionable": "私達が確認している間でも、あなたは @{name} さんに対して対応することが出来ます:", "report.thanks.title": "見えないようにしたいですか?", - "report.thanks.title_actionable": "Thanks for reporting, we'll look into this.", + "report.thanks.title_actionable": "ご報告ありがとうございます、追って確認します。", "report.unfollow": "@{name}のフォローを解除", "report.unfollow_explanation": "このアカウントをフォローしています。ホームフィードに彼らの投稿を表示しないようにするには、彼らのフォローを外してください。", "search.placeholder": "検索", @@ -436,7 +436,7 @@ "search_results.accounts": "人々", "search_results.all": "すべて", "search_results.hashtags": "ハッシュタグ", - "search_results.nothing_found": "Could not find anything for these search terms", + "search_results.nothing_found": "この検索条件では何も見つかりませんでした", "search_results.statuses": "投稿", "search_results.statuses_fts_disabled": "このサーバーでは投稿本文の検索は利用できません。", "search_results.total": "{count, number}件の結果", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index 1bbc2918c..79fac6eb5 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -18,7 +18,7 @@ "account.followers": "Подписчики", "account.followers.empty": "На этого пользователя пока никто не подписан.", "account.followers_counter": "{count, plural, one {{counter} подписчик} many {{counter} подписчиков} other {{counter} подписчика}}", - "account.following": "Following", + "account.following": "Подписки", "account.following_counter": "{count, plural, one {{counter} подписка} many {{counter} подписок} other {{counter} подписки}}", "account.follows.empty": "Этот пользователь пока ни на кого не подписался.", "account.follows_you": "Подписан(а) на вас", @@ -95,7 +95,7 @@ "compose_form.direct_message_warning": "Адресованные посты отправляются и видны только упомянутым в них пользователям.", "compose_form.direct_message_warning_learn_more": "Подробнее", "compose_form.hashtag_warning": "Так как этот пост не публичный, он не отобразится в поиске по хэштегам.", - "compose_form.lock_disclaimer": "Ваша учётная запись не {locked}. Любой пользователь сможет подписаться на вас и просматривать посты для подписчиков.", + "compose_form.lock_disclaimer": "Ваша учётная запись {locked}. Любой пользователь сможет подписаться на вас и просматривать посты для подписчиков.", "compose_form.lock_disclaimer.lock": "не закрыта", "compose_form.placeholder": "О чём думаете?", "compose_form.poll.add_option": "Добавить вариант", @@ -390,42 +390,42 @@ "relative_time.today": "сегодня", "reply_indicator.cancel": "Отмена", "report.block": "Заблокировать", - "report.block_explanation": "You will not see their posts. They will not be able to see your posts or follow you. They will be able to tell that they are blocked.", + "report.block_explanation": "В перестаните видеть посты этого пользователя, а он(а) больше не сможет подписаться на вас и читать ваши посты. Он(а) сможет понять что вы заблокировали его/её.", "report.categories.other": "Другое", "report.categories.spam": "Спам", "report.categories.violation": "Содержимое нарушает одно или несколько правил узла", "report.category.subtitle": "Выберите наиболее подходящее", - "report.category.title": "Расскажите нам, что происходит с {type}", - "report.category.title_account": "профиль", - "report.category.title_status": "пост", + "report.category.title": "Расскажите нам, что не так с {type}", + "report.category.title_account": "этим профилем", + "report.category.title_status": "этим постом", "report.close": "Готово", - "report.comment.title": "Есть что-нибудь еще, что мы должны знать?", - "report.forward": "Переслать в {target}", + "report.comment.title": "Есть ли что-нибудь ещё, что нам стоит знать?", + "report.forward": "Переслать на {target}", "report.forward_hint": "Эта учётная запись расположена на другом узле. Отправить туда анонимную копию вашей жалобы?", - "report.mute": "Mute", + "report.mute": "Игнорировать", "report.mute_explanation": "Вы не будете видеть их посты. Они по-прежнему могут подписываться на вас и видеть ваши посты, но не будут знать, что они в списке игнорируемых.", "report.next": "Далее", - "report.placeholder": "Комментарий", + "report.placeholder": "Дополнительные комментарии", "report.reasons.dislike": "Мне не нравится", "report.reasons.dislike_description": "Не хотел(а) бы видеть такой контент", "report.reasons.other": "Другое", - "report.reasons.other_description": "Проблема не подпадает под другие категории", + "report.reasons.other_description": "Проблема не попадает ни под одну из категорий", "report.reasons.spam": "Это спам", - "report.reasons.spam_description": "Вредоносные ссылки, поддельные действия или повторяющиеся ответы", + "report.reasons.spam_description": "Вредоносные ссылки, фальшивое взаимодействие или повторяющиеся ответы", "report.reasons.violation": "Нарушаются правила сервера", "report.reasons.violation_description": "Вы знаете, что подобное нарушает определенные правила", "report.rules.subtitle": "Выберите все подходящие варианты", "report.rules.title": "Какие правила нарушены?", "report.statuses.subtitle": "Выберите все подходящие варианты", - "report.statuses.title": "Есть ли сообщения, подтверждающие основания этой жалобы?", + "report.statuses.title": "Выберите посты, которые относятся к вашей жалобе.", "report.submit": "Отправить", "report.target": "Жалоба на {target}", - "report.thanks.take_action": "Here are your options for controlling what you see on Mastodon:", - "report.thanks.take_action_actionable": "While we review this, you can take action against @{name}:", + "report.thanks.take_action": "Вот несколько опций управления тем, что вы видите в Mastodon:", + "report.thanks.take_action_actionable": "Пока мы рассматриваем его, вот действия, которые вы можете предпринять лично против @{name}:", "report.thanks.title": "Не хотите видеть это?", "report.thanks.title_actionable": "Спасибо за обращение, мы его рассмотрим.", "report.unfollow": "Отписаться от @{name}", - "report.unfollow_explanation": "You are following this account. To not see their posts in your home feed anymore, unfollow them.", + "report.unfollow_explanation": "Вы подписаны на этого пользователя. Чтобы не видеть его/её посты в своей домашней ленте, отпишитесь от него/неё.", "search.placeholder": "Поиск", "search_popout.search_format": "Продвинутый формат поиска", "search_popout.tips.full_text": "Поиск по простому тексту отобразит посты, которые вы написали, добавили в избранное, продвинули или в которых были упомянуты, а также подходящие имена пользователей и хэштеги.", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index 60b513aa1..860e65413 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -389,7 +389,7 @@ "relative_time.seconds": "{number}sek", "relative_time.today": "dnes", "reply_indicator.cancel": "Zrušiť", - "report.block": "Block", + "report.block": "Blokuj", "report.block_explanation": "You will not see their posts. They will not be able to see your posts or follow you. They will be able to tell that they are blocked.", "report.categories.other": "Other", "report.categories.spam": "Spam", @@ -424,7 +424,7 @@ "report.thanks.take_action_actionable": "While we review this, you can take action against @{name}:", "report.thanks.title": "Nechceš to vidieť?", "report.thanks.title_actionable": "Thanks for reporting, we'll look into this.", - "report.unfollow": "Unfollow @{name}", + "report.unfollow": "Nesleduj @{name}", "report.unfollow_explanation": "You are following this account. To not see their posts in your home feed anymore, unfollow them.", "search.placeholder": "Hľadaj", "search_popout.search_format": "Pokročilé vyhľadávanie", @@ -434,7 +434,7 @@ "search_popout.tips.text": "Vráti jednoduchý textový výpis zhodujúcich sa mien, prezývok a haštagov", "search_popout.tips.user": "užívateľ", "search_results.accounts": "Ľudia", - "search_results.all": "All", + "search_results.all": "Všetky", "search_results.hashtags": "Haštagy", "search_results.nothing_found": "Could not find anything for these search terms", "search_results.statuses": "Príspevky", @@ -451,7 +451,7 @@ "status.detailed_status": "Podrobný náhľad celej konverzácie", "status.direct": "Priama správa pre @{name}", "status.edit": "Uprav", - "status.edited": "Edited {date}", + "status.edited": "Upravené {date}", "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Vložiť", "status.favourite": "Páči sa mi", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index 06bb94307..876f8aa8a 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -41,7 +41,7 @@ "account.statuses_counter": "{count, plural, one {{counter} Пост} few {{counter} Пости} many {{counter} Постів} other {{counter} Пости}}", "account.unblock": "Розблокувати @{name}", "account.unblock_domain": "Розблокувати {domain}", - "account.unblock_short": "Unblock", + "account.unblock_short": "Розблокувати", "account.unendorse": "Не публікувати у профілі", "account.unfollow": "Відписатися", "account.unmute": "Зняти глушення з @{name}", @@ -187,7 +187,7 @@ "error.unexpected_crash.next_steps_addons": "Спробуйте їх вимкнути та оновити сторінку. Якщо це не допомагає, ви можете використовувати Mastodon через інший браузер або окремий застосунок.", "errors.unexpected_crash.copy_stacktrace": "Скопіювати трасування стека у буфер обміну", "errors.unexpected_crash.report_issue": "Повідомити про проблему", - "explore.search_results": "Search results", + "explore.search_results": "Результати пошуку", "explore.suggested_follows": "Для вас", "explore.title": "Огляд", "explore.trending_links": "Новини", @@ -309,7 +309,7 @@ "navigation_bar.preferences": "Налаштування", "navigation_bar.public_timeline": "Глобальна стрічка", "navigation_bar.security": "Безпека", - "notification.admin.sign_up": "{name} signed up", + "notification.admin.sign_up": "{name} приєднується", "notification.favourite": "{name} вподобав(-ла) ваш допис", "notification.follow": "{name} підписався(-лась) на вас", "notification.follow_request": "{name} відправив(-ла) запит на підписку", @@ -321,7 +321,7 @@ "notification.update": "{name} змінює допис", "notifications.clear": "Очистити сповіщення", "notifications.clear_confirmation": "Ви впевнені, що хочете назавжди видалити всі сповіщеня?", - "notifications.column_settings.admin.sign_up": "New sign-ups:", + "notifications.column_settings.admin.sign_up": "Нові реєстрації:", "notifications.column_settings.alert": "Сповіщення на комп'ютері", "notifications.column_settings.favourite": "Вподобане:", "notifications.column_settings.filter_bar.advanced": "Показати всі категорії", @@ -389,7 +389,7 @@ "relative_time.seconds": "{number}с", "relative_time.today": "сьогодні", "reply_indicator.cancel": "Відмінити", - "report.block": "Block", + "report.block": "Заблокувати", "report.block_explanation": "You will not see their posts. They will not be able to see your posts or follow you. They will be able to tell that they are blocked.", "report.categories.other": "Інше", "report.categories.spam": "Спам", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index b6db3c14b..d47033881 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -8,7 +8,7 @@ "account.blocked": "Đã chặn", "account.browse_more_on_origin_server": "Truy cập trang của người này", "account.cancel_follow_request": "Hủy yêu cầu theo dõi", - "account.direct": "Nhắn tin @{name}", + "account.direct": "Nhắn riêng @{name}", "account.disable_notifications": "Không thông báo khi @{name} đăng tút", "account.domain_blocked": "Người đã chặn", "account.edit_profile": "Chỉnh sửa trang cá nhân", @@ -49,9 +49,9 @@ "account.unmute_short": "Bỏ ẩn", "account_note.placeholder": "Nhấn để thêm", "admin.dashboard.daily_retention": "Tỉ lệ người dùng sau đăng ký ở lại theo ngày", - "admin.dashboard.monthly_retention": "Tỉ lệ người dùng sau đăng ký ở lại theo tháng", + "admin.dashboard.monthly_retention": "Tỉ lệ người dùng ở lại sau khi đăng ký", "admin.dashboard.retention.average": "Trung bình", - "admin.dashboard.retention.cohort": "Đăng ký tháng", + "admin.dashboard.retention.cohort": "Tháng đăng ký", "admin.dashboard.retention.cohort_size": "Người dùng mới", "alert.rate_limited.message": "Vui lòng thử lại sau {retry_time, time, medium}.", "alert.rate_limited.title": "Vượt giới hạn", @@ -179,7 +179,7 @@ "empty_column.list": "Chưa có tút. Khi những người trong danh sách này đăng tút mới, chúng sẽ xuất hiện ở đây.", "empty_column.lists": "Bạn chưa tạo danh sách nào.", "empty_column.mutes": "Bạn chưa ẩn bất kỳ ai.", - "empty_column.notifications": "Bạn chưa có thông báo nào. Hãy thử theo dõi hoặc nhắn tin cho một ai đó.", + "empty_column.notifications": "Bạn chưa có thông báo nào. Hãy thử theo dõi hoặc nhắn riêng cho một ai đó.", "empty_column.public": "Trống trơn! Bạn hãy viết gì đó hoặc bắt đầu theo dõi những người khác", "error.unexpected_crash.explanation": "Trang này có thể không hiển thị chính xác do lỗi lập trình Mastodon hoặc vấn đề tương thích trình duyệt.", "error.unexpected_crash.explanation_addons": "Trang này không thể hiển thị do xung khắc với add-on của trình duyệt hoặc công cụ tự động dịch ngôn ngữ.", @@ -188,7 +188,7 @@ "errors.unexpected_crash.copy_stacktrace": "Sao chép stacktrace vào clipboard", "errors.unexpected_crash.report_issue": "Báo cáo lỗi", "explore.search_results": "Kết quả tìm kiếm", - "explore.suggested_follows": "Đề xuất cho bạn", + "explore.suggested_follows": "Dành cho bạn", "explore.title": "Khám phá", "explore.trending_links": "Tin tức", "explore.trending_statuses": "Tút", @@ -294,7 +294,7 @@ "navigation_bar.discover": "Khám phá", "navigation_bar.domain_blocks": "Máy chủ đã ẩn", "navigation_bar.edit_profile": "Trang cá nhân", - "navigation_bar.explore": "Khám phá", + "navigation_bar.explore": "Xu hướng", "navigation_bar.favourites": "Thích", "navigation_bar.filters": "Bộ lọc từ ngữ", "navigation_bar.follow_requests": "Yêu cầu theo dõi", @@ -309,7 +309,7 @@ "navigation_bar.preferences": "Cài đặt", "navigation_bar.public_timeline": "Thế giới", "navigation_bar.security": "Bảo mật", - "notification.admin.sign_up": "{name} vừa đăng ký", + "notification.admin.sign_up": "{name} đăng ký máy chủ của bạn", "notification.favourite": "{name} thích tút của bạn", "notification.follow": "{name} theo dõi bạn", "notification.follow_request": "{name} yêu cầu theo dõi bạn", @@ -367,7 +367,7 @@ "poll_button.remove_poll": "Hủy cuộc bình chọn", "privacy.change": "Thay đổi quyền riêng tư", "privacy.direct.long": "Chỉ người được nhắc đến mới thấy", - "privacy.direct.short": "Tin nhắn", + "privacy.direct.short": "Nhắn riêng", "privacy.private.long": "Dành riêng cho người theo dõi", "privacy.private.short": "Riêng tư", "privacy.public.long": "Hiện trên bảng tin máy chủ", @@ -449,7 +449,7 @@ "status.copy": "Sao chép URL", "status.delete": "Xóa", "status.detailed_status": "Xem chi tiết thêm", - "status.direct": "Nhắn tin @{name}", + "status.direct": "Nhắn riêng @{name}", "status.edit": "Sửa", "status.edited": "Đã sửa {date}", "status.edited_x_times": "Đã sửa {count, plural, other {{count} lần}}", @@ -483,7 +483,7 @@ "status.show_less_all": "Thu gọn toàn bộ", "status.show_more": "Xem thêm", "status.show_more_all": "Hiển thị tất cả", - "status.show_thread": "Toàn chủ đề", + "status.show_thread": "Xem chuỗi tút này", "status.uncached_media_warning": "Uncached", "status.unmute_conversation": "Quan tâm", "status.unpin": "Bỏ ghim trên trang cá nhân", diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 460feb037..054db2e5b 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -1,7 +1,7 @@ --- ca: about: - about_hashtag_html: Aquests són tuts públics etiquetats amb #%{hashtag}. Pots interactuar amb elles si tens un compte a qualsevol lloc del fedivers. + about_hashtag_html: Aquests són publicacions públiques etiquetades amb #%{hashtag}. Pots interactuar amb elles si tens un compte a qualsevol lloc del fedivers. about_mastodon_html: 'La xarxa social del futur: sense anuncis, sense vigilància corporativa, disseny ètic i descentralització. Posseeix les teves dades amb Mastodon!' about_this: Quant a active_count_after: actiu @@ -25,7 +25,7 @@ ca: instance_actor_flash: | Aquest compte és un actor virtual utilitzat per a representar al propi servidor i no cap usuari individual. S'utilitza per a propòsits de federació i no ha de ser bloquejat si no voleu bloquejar tota la instància, en aquest cas hauríeu d'utilitzar un bloqueig de domini. - learn_more: Més informació + learn_more: Aprèn més logged_in_as_html: Actualment has iniciat sessió com a %{username}. logout_before_registering: Ja has iniciat sessió. privacy_policy: Política de privadesa @@ -35,12 +35,12 @@ ca: server_stats: 'Estadístiques del servidor:' source_code: Codi font status_count_after: - one: estat - other: tuts - status_count_before: Que han escrit + one: publicació + other: publicacions + status_count_before: Que han publicat tagline: Segueix els teus amics i descobreix-ne de nous terms: Termes del servei - unavailable_content: Contingut no disponible + unavailable_content: Servidors moderats unavailable_content_description: domain: Servidor reason: Raó @@ -78,10 +78,10 @@ ca: pin_errors: following: Has d'estar seguint la persona que vulguis avalar posts: - one: Tut - other: Tuts - posts_tab_heading: Tuts - posts_with_replies: Tuts i respostes + one: Publicació + other: Publicacions + posts_tab_heading: Publicacions + posts_with_replies: Publicacions i respostes roles: admin: Administrador bot: Bot @@ -98,7 +98,7 @@ ca: created_msg: La nota de moderació s'ha creat correctament! destroyed_msg: Nota de moderació destruïda amb èxit! accounts: - add_email_domain_block: Afegir el domini de correu a la llista negra + add_email_domain_block: Bloquejar el domini de l'adreça de correu electrònic approve: Aprova approved_msg: L’aplicació del registre de %{username} s’ha aprovat amb èxit are_you_sure: N'estàs segur? diff --git a/config/locales/devise.ca.yml b/config/locales/devise.ca.yml index ff7836711..4c58c432f 100644 --- a/config/locales/devise.ca.yml +++ b/config/locales/devise.ca.yml @@ -25,7 +25,7 @@ ca: explanation: Has creat un compte a %{host} amb aquesta adreça de correu electrònic. Estàs a un sol clic de l'activació. Si no fos així, ignora aquest correu electrònic. explanation_when_pending: Has sol·licitat una invitació a %{host} amb aquesta adreça de correu electrònic. Un cop confirmis la teva adreça de correu electrònic revisarem la teva sol·licitud. No es pot iniciar la sessió fins llavors. Si la teva sol·licitud és rebutjada les teves dades s’eliminaran, de manera que no s’exigirà cap altra acció. Si no has estat tu qui ha fet aquest sol·licitud si us plau ignora aquest correu electrònic. extra_html: Si us plau consulta també les regles del servidor i les nostres condicions de servei. - subject: 'Mastodon: Instruccions de confirmació de %{instance}' + subject: 'Mastodon: Instruccions de confirmació per a %{instance}' title: Verifica l'adreça de correu email_changed: explanation: 'L''adreça de correu del teu compte s''està canviant a:' @@ -34,7 +34,7 @@ ca: title: Adreça de correu electrònic nova password_change: explanation: S'ha canviat la contrasenya del teu compte. - extra: Si no has canviat el teu correu electrònic, és probable que algú hagi accedit al teu compte. Si us plau, canvia la contrasenya immediatament o posa't en contacte amb l'administrador del servidor si no pots accedir al teu compte. + extra: Si no has canviat la teva contrasenya, és probable que algú hagi accedit al teu compte. Si us plau, canvia la contrasenya immediatament o posa't en contacte amb l'administrador del servidor si no pots accedir al teu compte. subject: 'Mastodon: Contrasenya canviada' title: Contrasenya canviada reconfirmation_instructions: @@ -61,7 +61,7 @@ ca: subject: 'Mastodon: codis de recuperació de Dos factors regenerats' title: 2FA codis de recuperació canviats unlock_instructions: - subject: 'Mastodon: Instruccions per a desbloquejar' + subject: 'Mastodon: Instruccions de desbloqueig' webauthn_credential: added: explanation: La següent clau de seguretat s'ha afegit al teu compte @@ -84,34 +84,34 @@ ca: success: Autenticat amb èxit des del compte %{kind}. passwords: no_token: No pots accedir a aquesta pàgina sense provenir des del correu de restabliment de la contrasenya. Si vens des del correu de restabliment de contrasenya, assegura't que estàs emprant l'adreça completa proporcionada. - send_instructions: Si el teu correu electrònic existeix en la nostra base de dades, rebràs en pocs minuts un enllaç de restabliment de contrasenya en l'adreça de correu. Si us plau verifica la teva carpeta de correu brossa if no rebut aquest correu. - send_paranoid_instructions: Si el seu correu electrònic existeix en la nostra base de dades, rebràs un enllaç de restabliment de contrasenya en l'adreça de correu en pocs minuts. + send_instructions: Si el teu correu electrònic existeix en la nostra base de dades, rebràs en pocs minuts un enllaç de restabliment de contrasenya en l'adreça de correu. Si us plau verifica la teva carpeta de correu brossa si no has rebut aquest correu. + send_paranoid_instructions: Si el teu correu electrònic existeix en la nostra base de dades, rebràs un enllaç de restabliment de contrasenya en l'adreça de correu en pocs minuts. Si us plau verifica la carpeta de correu brossa si no reps aquest correu. updated: La contrasenya s'ha canviat correctament. Ara ja estàs registrat. updated_not_active: La contrasenya s'ha canviat correctament. registrations: - destroyed: Adéu! el compte s'ha cancel·lat amb èxit. Desitgem veure't de nou aviat. + destroyed: Adéu! el compte s'ha cancel·lat amb èxit. Desitgem veure't de nou ben aviat. signed_up: Benvingut! T'has registrat amb èxit. - signed_up_but_inactive: T´has registrat amb èxit. No obstant, no podem identificar-te perquè el compte encara no s'ha activat. - signed_up_but_locked: T´has registrat amb èxit. No obstant, no podem identificar-te perquè el compte està blocat. + signed_up_but_inactive: T´has registrat amb èxit. No obstant, no podem iniciar la teva sessió perquè el teu compte encara no s'ha activat. + signed_up_but_locked: T´has registrat amb èxit. No obstant, no podem iniciar la teva sessió perquè el teu compte està bloquejat. signed_up_but_pending: S'ha enviat un missatge amb un enllaç de confirmació a la teva adreça de correu electrònic. Després que hagis fet clic a l'enllaç, revisarem la sol·licitud. Se't notificarà si s'aprova. - signed_up_but_unconfirmed: S'ha enviat per correu electrònic un missatge amb un enllaç de confirmació. Fes clic a l'enllaç per a activar el compte. - update_needs_confirmation: Ha actualitzat el seu compte amb èxit, però necessitem verificar la nova adreça de correu. Si us plau comprovi el correu i segueixi l'enllaç per confirmar la nova adreça de correu. - updated: El seu compte ha estat actualitzat amb èxit. + signed_up_but_unconfirmed: S'ha enviat per correu electrònic un missatge amb un enllaç de confirmació. Fes clic a l'enllaç per a activar el compte. Si us plau verifica la teva carpeta de correu brossa si no reps aquest correu. + update_needs_confirmation: Has actualitzat el teu compte amb èxit, però necessitem verificar la teva nova adreça de correu. Si us plau comprova el correu i segueixi l'enllaç per confirmar la nova adreça de correu. Si us plau verifica la teva carpeta de correu brossa si no reps aquest correu. + updated: El teu compte ha estat actualitzat amb èxit. sessions: already_signed_out: Has tancat la sessió amb èxit. signed_in: T'has registrat amb èxit. signed_out: Has tancat la sessió amb èxit. unlocks: send_instructions: En pocs minuts rebràs un correu electrònic amb instruccions sobre com desbloquejar el teu compte. Si us plau verifica la teva carpeta de correu brossa si no has rebut aquest correu. - send_paranoid_instructions: Si el compte existeix, rebràs en pocs minuts un correu electrònic amb instruccions sobre com desbloquejar-lo. Verifica la carpeta de correu brossa si no has rebut aquest correu. - unlocked: El compte s'ha desblocat correctament. Inicia sessió per a continuar. + send_paranoid_instructions: Si el teu compte existeix, rebràs en pocs minuts un correu electrònic amb instruccions sobre com desbloquejar-lo. Verifica la carpeta de correu brossa si no has rebut aquest correu. + unlocked: El compte s'ha desbloquejat correctament. Inicia sessió per a continuar. errors: messages: already_confirmed: ja està confirmat. Intenta d'iniciar sessió - confirmation_period_expired: calia fer la confirmació dins de %{period}, torna a sol·licitar-la - expired: ha expirat, demana'n una altra + confirmation_period_expired: cal fer la confirmació dins de %{period}, si us plau sol·licita-ho de nou + expired: ha expirat, si us plau demana'n una altra not_found: no s'ha trobat not_locked: no està bloquejada not_saved: one: '1 error ha impedit desar aquest %{resource}:' - other: "%{count} errors hab impedit desar aquest %{resource}:" + other: "%{count} errors han impedit desar aquest %{resource}:" diff --git a/config/locales/devise.da.yml b/config/locales/devise.da.yml index 6e4d5ad62..18aa43162 100644 --- a/config/locales/devise.da.yml +++ b/config/locales/devise.da.yml @@ -37,21 +37,21 @@ da: title: Adgangskode skiftet reconfirmation_instructions: explanation: Bekræft den nye adresse for at skifte din e-mail. - extra: Er denne ændring ikke foranlediget af dig, så ignorér denne e-mail. Mastodon-kontoens e-mailadresse skiftes ikke, før linket ovenfor benyttes. + extra: Er denne ændring ikke foranlediget af dig, så ignorér denne e-mail. Mastodon-kontoens e-mailadresse kan kun skiftes vha. linket ovenfor. subject: 'Mastodon: Bekræft e-mail for %{instance}' title: Bekræft e-mailadresse reset_password_instructions: action: Skift adgangskode explanation: Du har anmodet om en ny kontoadgangskode. - extra: Har du ikke anmodet om dette, så ignorér denne e-mail. Din adgangskode skiftes først, når linket ovenfor er benyttet til at oprette en ny. - subject: 'Mastodon: Nulstil adgangskode-instruktioner' + extra: Har du ikke anmodet om dette, så ignorér denne e-mail. Din adgangskode skiftes først, når en ny er oprettet vha. linket ovenfor. + subject: 'Mastodon: Instruktioner til adgangskodenulstilling' title: Adgangskodenulstilling two_factor_disabled: - explanation: Tofaktorgodkendelse for din konto er blevet deaktiveret. Indlogning er nu kun mulig via email og adgangskode. + explanation: Tofaktorgodkendelse for kontoen er blevet deaktiveret. Indlogning er nu kun mulig via email og adgangskode. subject: 'Mastodon: Tofaktorgodkendelse deaktiveret' title: 2FA deaktiveret two_factor_enabled: - explanation: Tofaktorgodkendelse er blevet aktiveret for din konto. Et login-token genereret af den parrede TOTP-app vil være nødvendig. + explanation: Tofaktorgodkendelse er blevet aktiveret for kontoen. Indlogning vil kærve et token genereret af den parrede TOTP-app. subject: 'Mastodon: Tofaktorgodkendelse aktiveret' title: 2FA aktiveret two_factor_recovery_codes_changed: @@ -70,38 +70,38 @@ da: subject: 'Mastodon: Sikkerhedsnøgle slettet' title: En af dine sikkerhedsnøgler er blevet slettet webauthn_disabled: - explanation: Godkendelse med sikkerhedsnøgler er blevet deaktiveret for din konto. Indlogning er nu kun mulig via token genereret af den parrede TOTP-app. + explanation: Godkendelse med sikkerhedsnøgler er blevet deaktiveret for kontoen. Indlogning er nu kun mulig via token genereret af den parrede TOTP-app. subject: 'Mastodon: Godkendelse med sikkerhedsnøgler deaktiveret' title: Sikkerhedsnøgler deaktiveret webauthn_enabled: - explanation: Sikkerhedsnøglegodkendelse er aktiveret for din konto. Din sikkerhedsnøgle kan nu bruges til indlogning. + explanation: Sikkerhedsnøglegodkendelse er aktiveret for kontoen. Din sikkerhedsnøgle kan nu bruges til indlogning. subject: 'Mastodon: Sikkerhedsnøglegodkendelse aktiveret' title: Sikkerhedsnøgler aktiveret omniauth_callbacks: failure: Kunne ikke godkende dig fra %{kind} fordi "%{reason}". success: Godkendt fra %{kind}-konto. passwords: - no_token: Denne side er kun tilgængelig via linket fra en adgangskodenulstillings e-mail. Husk i den forbindelse at benytte den fuldstændige URL fra e-mailen. + no_token: Denne side er kun tilgængelig via linket fra en e-mail til adgangskodenulstillings. Husk i den forbindelse at benytte den fuldstændige URL fra e-mailen. send_instructions: Er din e-mailadresse allerede registreret, e-mailes du et link til adgangskodenulstilling. Tjek spammappen, hvis e-mailen ikke ses i indbakken indenfor få minutter. - send_paranoid_instructions: Er din e-mail-adresse allerede registreret, e-mailes du et link til adgangskodegendannelse. Tjek spammappen, hvis e-mailen ikke ses i indbakken indenfor få minutter. + send_paranoid_instructions: Er din e-mailadresse allerede registreret, e-mailes du et link til adgangskodenulstilling. Tjek spammappen, hvis e-mailen ikke ses i indbakken indenfor få minutter. updated: Din adgangskode er skiftet, og du er nu logget ind. updated_not_active: Din adgangskode er skiftet. registrations: destroyed: Farvel! Din konto er nu annulleret. Vi håber snart at se dig igen. - signed_up: Velkommen! Du har nu tilmeldt dig. - signed_up_but_inactive: Du har nu oprettet dig. Da din konto endnu ikke er aktiveret, kan du dog pt. ikke logge ind. - signed_up_but_locked: Du har nu oprettet dig. Da din konto er låst, kan du pt. ikke logge ind. - signed_up_but_pending: En besked med et bekræftelseslink er e-mailet til dig. Når du har klikket på linket, gennemgår vi din ansøgning, og du får besked, hvis den godkendes. - signed_up_but_unconfirmed: En besked med et bekræftelseslink er e-mailet til dig. Følg linket for at aktivere din konto. Tjek din spammappe, hvis du ikke ser denne e-mail i din indbakke. - update_needs_confirmation: Du har opdateret din konto. Din nye e-mailadresse skal dog bekræftes. For at gøre dette, tjek din e-mail og følg bekræftelseslinket. Tjek din spammappe, hvis du ikke ser denne e-mail i din indbakke indenfor få minutter. + signed_up: Velkommen! Du er nu tilmeldt. + signed_up_but_inactive: Du har nu oprettet dig. Da din konto endnu ikke er aktiveret, kan du dog ikke logge ind med det samme. + signed_up_but_locked: Du har nu oprettet dig. Da din konto er låst, kan du ikke logge ind med det samme. + signed_up_but_pending: Et bekræftelseslink er e-mailet til dig. Når du har klikket på linket, gennemgår vi din ansøgning, og du får besked, hvis den godkendes. + signed_up_but_unconfirmed: Et bekræftelseslink er e-mailet til dig. Følg linket for at aktivere din konto. Tjek spammappen, hvis e-mailen ikke dukker op i indbakken. + update_needs_confirmation: Du har opdateret din konto. Din nye e-mailadresse skal nu bekræftes. Til dette formål er du blevet e-mailet et bekræftelseslink, så følg dette for at bekræfte den nye e-mailadresse. Ser du ikke e-mailen i din indbakke snarest, så tjek Spam-mappen. updated: Din konto er nu opdateret. sessions: already_signed_out: Du er nu logget ud. signed_in: Du er nu logget ind. signed_out: Du er nu logget ud. unlocks: - send_instructions: Instruktioner mailes til dig om, hvordan du oplåser din konto. Er denne e-mail ikke er i din indbakke inden for få minutter, så tjek spammappe. - send_paranoid_instructions: Findes din konto, mailes du instrukser om, hvordan du oplåser den. Ser du ikke denne e-mail i din indbakke undenfor få minutter, så tjek spammappen. + send_instructions: Instruktioner e-mailes til dig om, hvordan du oplåser din konto. Er e-mailen ikke er i din indbakke inden for få minutter, så tjek i Spam. + send_paranoid_instructions: Findes din konto, e-mailes du instrukser om, hvordan du oplåser den. Er e-mailen i din indbakke indenfor få minutter, så tjek i Spam. unlocked: Din konto er nu oplåst. Log ind for at fortsætte. errors: messages: diff --git a/config/locales/doorkeeper.ca.yml b/config/locales/doorkeeper.ca.yml index a4d37f417..9725efe6c 100644 --- a/config/locales/doorkeeper.ca.yml +++ b/config/locales/doorkeeper.ca.yml @@ -13,9 +13,9 @@ ca: attributes: redirect_uri: fragment_present: no pot contenir un fragment. - invalid_uri: ha de ser un URI válid. - relative_uri: ha de ser un URI absoluta. - secured_uri: ha de ser un URI HTTPS/SSL. + invalid_uri: ha de ser una URI vàlida. + relative_uri: ha de ser una URI absoluta. + secured_uri: ha de ser una URI HTTPS/SSL. doorkeeper: applications: buttons: @@ -82,9 +82,9 @@ ca: messages: access_denied: El propietari del recurs o servidor d'autorizació ha denegat la petició. credential_flow_not_configured: Les credencials de contrasenya del propietari del recurs han fallat degut a que Doorkeeper.configure.resource_owner_from_credentials està sense configurar. - invalid_client: La autentificació del client ha fallat perquè és un client desconegut o no està inclòs l'autentificació del client o el mètode d'autenticació no està confirmat. - invalid_grant: La concessió d'autorizació oferida és invàlida, ha vençut, s'ha revocat, no coincideix amb l'URI de redirecció utilizada en la petició d'autorizació, o fou emesa per a un altre client. - invalid_redirect_uri: L'URI de redirecció inclòs no és vàlid. + invalid_client: La autentificació del client ha fallat perquè és un client desconegut o no està inclòsa l'autentificació del client o el mètode d'autenticació no està confirmat. + invalid_grant: La concessió d'autorizació oferta és invàlida, ha vençut, s'ha revocat, no coincideix amb l'URI de redirecció utilizada en la petició d'autorizació, o fou emesa per a un altre client. + invalid_redirect_uri: L'uri de redirecció inclòsa no és vàlida. invalid_request: missing_param: 'Falta paràmetre requerit: %{value}.' request_not_authorized: La petició ha de ser autoritzada. Falta o és invàlid un paràmetre requerit per l'autorització de la petició. @@ -154,7 +154,7 @@ ca: admin:write:accounts: fer l'acció de moderació en els comptes admin:write:reports: fer l'acció de moderació en els informes crypto: usa xifrat d'extrem a extrem - follow: seguir, blocar, desblocar i deixar de seguir comptes + follow: modificar relacions dels comptes push: rebre notificacions push del teu compte read: llegir les dades del teu compte read:accounts: veure informació dels comptes @@ -168,13 +168,13 @@ ca: read:notifications: veure les teves notificacions read:reports: veure els teus informes read:search: cerca en nom teu - read:statuses: veure tots els tuts - write: publicar en el teu nom + read:statuses: veure tots les publicacions + write: modificar totes les dades del teu compte write:accounts: modifica el teu perfil write:blocks: bloqueja comptes i dominis write:bookmarks: publicacions a marcadors write:conversations: silencia i esborra converses - write:favourites: afavoreix tuts + write:favourites: afavoreix publicacions write:filters: crear filtres write:follows: seguir usuaris write:lists: crear llistes @@ -182,4 +182,4 @@ ca: write:mutes: silencia usuaris i converses write:notifications: esborra les teves notificacions write:reports: informe d’altres persones - write:statuses: publicar tuts + write:statuses: publicar publicacions diff --git a/config/locales/doorkeeper.da.yml b/config/locales/doorkeeper.da.yml index 19f4307f6..094faedba 100644 --- a/config/locales/doorkeeper.da.yml +++ b/config/locales/doorkeeper.da.yml @@ -4,7 +4,7 @@ da: attributes: doorkeeper/application: name: Applikationsnavn - redirect_uri: Link + redirect_uri: Omdirigerings-URI scopes: Områder website: Applikationswebsted errors: @@ -13,7 +13,7 @@ da: attributes: redirect_uri: fragment_present: kan ikke indeholde et fragment. - invalid_uri: skal være en gyldigt URI. + invalid_uri: skal være en gyldig URI. relative_uri: skal være en absolut URI. secured_uri: skal være en HTTPS-/SSL-URI. doorkeeper: @@ -33,7 +33,7 @@ da: help: native_redirect_uri: Brug %{native_redirect_uri} til lokale tests redirect_uri: Brug én linje pr. URI - scopes: Adskil omfang med mellemrum. Lad være tomt for standardomfang. + scopes: Adskil omfang med mellemrum. Lad stå tomt for standardomfang. index: application: Applikation callback_url: Callback-URL @@ -60,9 +60,9 @@ da: error: title: En fejl opstod new: - prompt_html: "%{client_name} ønsker tilladelse til at tilgå din konto. Den er en tredjepartsapplikation. Er der ikke tillid til den, bør den ikke godkendes." + prompt_html: "%{client_name} ønsker tilladelse til at tilgå din konto. Den er en tredjepartsapplikation. Har du ikke tillid til den, bør den ikke godkendes." review_permissions: Gennemgå tilladelser - title: Godkendelse krævet + title: Godkendelse kræves show: title: Kopiér og indsæt denne godkendelseskode i applikationen. authorized_applications: @@ -72,7 +72,7 @@ da: revoke: Sikker? index: authorized_at: Godkendt pr. %{date} - description_html: Disse er applikationer, som kan tilgå din konto vha. API'en. Er der applikationer her, som ikke genkendes eller udviser mærkelig adfærd, kan deres adgang tilbagekaldes. + description_html: Disse er applikationer, som kan tilgå din konto vha. API'en. Er her applikationer, som ikke genkendes eller udviser mærkværdig adfærd, kan deres adgangstilladelse ophæves. last_used_at: Senest brugt pr. %{date} never_used: Aldrig brugt scopes: Tilladelser @@ -81,25 +81,25 @@ da: errors: messages: access_denied: Ressourceejeren eller godkendelsesserveren afviste anmodningen. - credential_flow_not_configured: Ressourceejeradgangskodeakkreditiv flow mislykkedes grundet ikke-opsat Doorkeeper.configure.resource_owner_from_credentials. - invalid_client: Klientbekræftelse mislykkedes grundet en ukendt klient, ingen klientbekræftelse inkluderet, eller uunderstøttet bekræftelsesmetode. - invalid_grant: Den leverede godkendelse er ugyldig, udløbet, tilbagekaldt, matcher ikke omdirigerings-URI brugt i godkendelsesanmodningen, eller er udstedt til en anden klient. + credential_flow_not_configured: Ressourceejeradgangskodeakkreditiver-flow mislykkedes grundet ikke-opsat Doorkeeper.configure.resource_owner_from_credentials. + invalid_client: Klientgodkendelse mislykkedes grundet en ukendt klient, ingen inkluderet klientgodkendelse eller uunderstøttet godkendelsesmetode. + invalid_grant: Den leverede godkendelse er ugyldig, udløbet, ophævet, matcher ikke omdirigerings-URI'en brugt i godkendelsesanmodningen eller er udstedt til en anden klient. invalid_redirect_uri: Inkluderede ormdirigerings-URI er ugyldig. invalid_request: - missing_param: 'Mangler krævet parameter: %{value}.' - request_not_authorized: Anmodning skal godkendes. Krævet parameter til godkendelse af anmodning mangler eller er ugyldig. - unknown: Anmodningen mangler en krævet parametre, inkluderer en uunderstøttet parametre værdi eller er på anden vis fejlbehæftet. - invalid_resource_owner: De angivne ressourceejerakkreditiver er ugyldige, eller ressourceejer kunne ikke findes - invalid_scope: Det anmodede omfang er ugyldigt, ukendt eller fejlbehæftet. + missing_param: 'Mangler obligatoriske parameter: %{value}.' + request_not_authorized: Anmodning kræver godkendelse. Obligatorisk parameter til godkendelse af anmodning mangler eller er ugyldig. + unknown: Anmodningen mangler en obligatorisk parameter, indeholder en uunderstøttet parameterværdi eller er på anden vis fejlbehæftet. + invalid_resource_owner: De angivne ressourceejerakkreditiver er ugyldige, eller ressourceejer kan ikke findes + invalid_scope: Det anmodede omfang er ugyldigt, ukendt eller forkert udformet. invalid_token: expired: Adgangstoken er udløbet - revoked: Adgangstoken er tilbagekaldt - unknown: Adgangstoken er ugyldig + revoked: Adgangstoken er ophævet + unknown: Adgangstoken er ugyldigt resource_owner_authenticator_not_configured: Ressourceejer kunne ikke findes grundet ikke-opsat Doorkeeper.configure.resource_owner_authenticator. server_error: Godkejdelsesserveren stødte på en uventet betingelse, der forhindrede den i at imødekomme anmodningen. temporarily_unavailable: Godkendelsesserveren kan pt. ikke håndtere anmodningen grundet midlertidig overbelastning eller servervedligehold. - unauthorized_client: Klienten er ikke godkendt til at udføre denne anmodning via denne metode. - unsupported_grant_type: Godkendelsestypen understøttes ikke af godkendelsesserveren. + unauthorized_client: Klienten er ikke godkendt til at udføre denne anmodning vha. denne metode. + unsupported_grant_type: Godkendelsestildelingstypen understøttes ikke af godkendelsesserveren. unsupported_response_type: Godkendelsesserveren understøtter ikke denne svartype. flash: applications: @@ -111,7 +111,7 @@ da: notice: Applikation opdateret. authorized_applications: destroy: - notice: Applikation tilbagekaldt. + notice: Applikation ophævet. grouped_scopes: access: read: Skrivebeskyttet adgang @@ -133,7 +133,7 @@ da: follows: Følger lists: Lister media: Medievedhæftninger - mutes: Tavsgjorte + mutes: Tavsgørelser notifications: Notifikationer push: Push-notifikationer reports: Anmeldelser @@ -143,43 +143,43 @@ da: admin: nav: applications: Applikationer - oauth2_provider: OAuth-udbyder + oauth2_provider: OAuth2-leverandør application: - title: OAuth-godkendelse krævet + title: OAuth-godkendelse obligatorisk scopes: - admin:read: læs al data på serveren + admin:read: læs alle data på serveren admin:read:accounts: læs sensitiv information fra alle konti admin:read:reports: læs sensitiv information fra alle anmeldelser og anmeldte konti - admin:write: redigér al data på serveren + admin:write: redigér alle data på serveren admin:write:accounts: udfør modereringshandlinger på konti admin:write:reports: udfør modereringshandlinger på anmeldelser crypto: benyt ende-til-ende kryptering follow: ændre kontorelationer - push: modtage dine push-notifikationer - read: læse alle dine kontodata + push: modtag dine push-notifikationer + read: læs alle dine kontodata read:accounts: se kontooplysninger read:blocks: se dine blokeringer read:bookmarks: se dine bogmærker read:favourites: se dine favoritter read:filters: se dine filtre - read:follows: se, hvem du følger + read:follows: se dine følger read:lists: se dine lister read:mutes: se dine tavsgørelser read:notifications: se dine notifikationer read:reports: se dine anmeldelser - read:search: søge på dine vegne - read:statuses: se alle statusser + read:search: søg på dine vegne + read:statuses: se alle indlæg write: ændre alle dine kontodata write:accounts: ændre din profil write:blocks: blokere konti og domæner - write:bookmarks: bogmærke statusser - write:conversations: tavsgør og slet konversationer - write:favourites: favoritmarkerede indlæg + write:bookmarks: bogmærke indlæg + write:conversations: tavsgøre og slette konversationer + write:favourites: favoritmarkere indlæg write:filters: oprette filtre write:follows: følge personer write:lists: oprette lister - write:media: uploade multimediefiler + write:media: uploade mediefiler write:mutes: tavsgøre personer og konversationer write:notifications: rydde dine notifikationer write:reports: anmelde personer - write:statuses: udgive statusser + write:statuses: udgive indlæg diff --git a/config/locales/doorkeeper.sk.yml b/config/locales/doorkeeper.sk.yml index 3f92a67ae..3e29a3332 100644 --- a/config/locales/doorkeeper.sk.yml +++ b/config/locales/doorkeeper.sk.yml @@ -101,6 +101,7 @@ sk: notice: Oprávnenia aplikácie zrušené. grouped_scopes: title: + blocks: Blokovania mutes: Nevšímané layouts: admin: diff --git a/config/locales/doorkeeper.uk.yml b/config/locales/doorkeeper.uk.yml index 44562f4b8..7d522497d 100644 --- a/config/locales/doorkeeper.uk.yml +++ b/config/locales/doorkeeper.uk.yml @@ -109,7 +109,11 @@ uk: grouped_scopes: title: accounts: Облікові записи + admin/reports: Адміністрація звітів all: Усе + blocks: Блокування + bookmarks: Закладки + conversations: Бесіди crypto: Наскрізне шифрування filters: Фільтри lists: Списки diff --git a/config/locales/doorkeeper.vi.yml b/config/locales/doorkeeper.vi.yml index 4acfd9977..ecd5cfc4c 100644 --- a/config/locales/doorkeeper.vi.yml +++ b/config/locales/doorkeeper.vi.yml @@ -71,13 +71,13 @@ vi: confirmations: revoke: Bạn có chắc không? index: - authorized_at: Cấp quyền vào %{date} + authorized_at: Cho phép vào %{date} description_html: Đây là những ứng dụng có thể truy cập tài khoản của bạn bằng API. Nếu có ứng dụng bạn không nhận ra ở đây hoặc ứng dụng hoạt động sai, bạn có thể thu hồi quyền truy cập của ứng dụng đó. - last_used_at: Dùng gần nhất vào %{date} - never_used: Chưa dùng bao giờ + last_used_at: Dùng lần cuối %{date} + never_used: Chưa dùng scopes: Quyền cho phép superapp: Đang dùng - title: Các ứng dụng đang cho phép + title: Các ứng dụng đang dùng errors: messages: access_denied: Chủ sở hữu tài nguyên hoặc máy chủ đã từ chối yêu cầu. diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 32b101147..58c4694c0 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -716,7 +716,7 @@ ja: trends: allow: 許可 approved: 承認 - disallow: 不許可 + disallow: 拒否 links: allow: リンクの許可 allow_provider: 発行者の承認 @@ -731,8 +731,11 @@ ja: title: 発行者 rejected: 拒否 statuses: - allow: 投稿を許可する - disallow: 投稿を許可しない + allow: 掲載を許可 + allow_account: 投稿者を許可 + disallow: 掲載を拒否 + disallow_account: 投稿者を拒否 + title: トレンド投稿 tags: current_score: 現在のスコア %{score} dashboard: @@ -1309,6 +1312,7 @@ ja: default_language: UIの表示言語 disallowed_hashtags: other: '許可されていないハッシュタグが含まれています: %{tags}' + edited_at_html: "%{date} 編集済み" errors: in_reply_not_found: あなたが返信しようとしている投稿は存在しないようです。 open_in_web: Webで開く diff --git a/config/locales/ku.yml b/config/locales/ku.yml index a457b4b07..5245f85ec 100644 --- a/config/locales/ku.yml +++ b/config/locales/ku.yml @@ -21,7 +21,7 @@ ku: documentation: Pelbend federation_hint_html: Bi ajimêrê xwe %{instance} re tu dikarî kesên rajekar û li derveyî mastodonê bişopînî. get_apps: Sepaneke mobîl bicerbîne - hosted_on: Mastodon li ser%{domain} tê hildanê + hosted_on: Mastodon li ser %{domain} tê pêşkêşkirin instance_actor_flash: 'Ev ajimêr aktorekî aşopî ye ji bo rajekar were temsîl kirin tê bikaranîn ne ajimêra kesî ye. Ji bo armanca federasyonê dixebite û divê ney asteng kirin heta ku te xwest hemû nimûneyan asteng bikî, di vir de ger tu blogek navper bikarbînî. ' @@ -904,9 +904,9 @@ ku: sensitive_content: Naveroka hestiyarî toot_layout: Xêzkirina şandîya application_mailer: - notification_preferences: Hevyazên e-name yê biguherîne + notification_preferences: Sazkariyên e-nameyê biguherîne salutation: "%{name}," - settings: 'Hevyazên e-name yê biguherîne: %{link}' + settings: 'Sazkariyên e-nameyê biguherîne: %{link}' view: 'Nîşan bide:' view_profile: Profîlê nîşan bide view_status: Şandiyê nîşan bide @@ -1596,7 +1596,7 @@ ku:

Originally adapted from the Discourse privacy policy.

title: "%{instance} mercên bikaranîn û politîkayên nehêniyê" themes: - contrast: Mastodon (dijberiya bilind) + contrast: Mastodon (Dijberiya bilind) default: Mastodon (Tarî) mastodon-light: Mastodon (Ronahî) time: @@ -1635,8 +1635,8 @@ ku: title: Pakêtkirina arşîvan sign_in_token: details: 'Li vir hûrgiliyên hewldanê hene:' - explanation: 'Me hewildanek têketina ajimêra te ji navnîşana IPya nenas nas kir. Ger ev tu bî, ji kerema xwe koda ewlehiyê ya jêr têkeve rûpela jêpirsînê:' - further_actions: 'Ger ev ne tu bî, ji kerema xwe re şîfreya xwe biguherîne û li ser hesaba xwe rastkirina du-gavî çalak bike. Tu dikarî wê ji vê derê çêkî:' + explanation: 'Me hewildanek têketina ajimêra te ji navnîşana IP ya nenas destnîşan kir. Ger ev tu bî, ji kerema xwe koda ewlehiyê ya jêr binivîsîne di rûpela jêpirsînê de:' + further_actions: 'Ger ev ne tu bî, ji kerema xwe re pêborîna xwe biguherîne û li ser ajimêra xwe rastkirina du-gavî çalak bike. Tu dikarî wê ji vê derê çê bikî:' subject: Ji kerema xwe re hewldanên têketinê piştrast bike title: Hewldanên têketinê warning: diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index c6a52ce78..eac5c351c 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -27,6 +27,8 @@ ja: scheduled_at: お知らせを今すぐ掲載する場合は空欄にしてください starts_at: オプションです。お知らせしたい事柄の期間が決まっている場合に使用します text: 投稿と同じ構文を使用できます。アナウンスが占める画面のスペースに注意してください + appeal: + text: 一度だけ異議を申し立てることができます defaults: autofollow: 招待から登録した人が自動的にあなたをフォローするようになります avatar: "%{size}までのPNG、GIF、JPGが利用可能です。%{dimensions}pxまで縮小されます" @@ -116,6 +118,8 @@ ja: scheduled_at: 掲載予約日時 starts_at: 予定開始日時 text: お知らせ + appeal: + text: この決定を覆すべき理由を説明してください defaults: autofollow: 招待から参加後、あなたをフォロー avatar: アイコン @@ -194,6 +198,7 @@ ja: sign_up_requires_approval: 登録を制限 severity: ルール notification_emails: + appeal: モデレーターの判断に異議申し立てが行われました digest: タイムラインからピックアップしてメールで通知する favourite: お気に入り登録された時 follow: フォローされた時 @@ -201,6 +206,8 @@ ja: mention: 返信が来た時 pending_account: 新しいアカウントの承認が必要な時 reblog: 投稿がブーストされた時 + report: 新しいレポートが送信されました + trending_tag: 新しいトレンドタグにはレビューが必要です rule: text: ルール tag: diff --git a/config/locales/simple_form.sk.yml b/config/locales/simple_form.sk.yml index 847a68e0f..5ae4b2e04 100644 --- a/config/locales/simple_form.sk.yml +++ b/config/locales/simple_form.sk.yml @@ -153,6 +153,9 @@ sk: comment: Okomentuj invite_request: text: Prečo sa k nám chceš pridať? + ip_block: + comment: Komentár + severity: Pravidlo notification_emails: digest: Zasielať súhrnné emaily favourite: Zaslať email, ak si niekto obľúbi tvoj príspevok diff --git a/config/locales/simple_form.th.yml b/config/locales/simple_form.th.yml index a1dbe66f9..6127cb9d5 100644 --- a/config/locales/simple_form.th.yml +++ b/config/locales/simple_form.th.yml @@ -133,6 +133,7 @@ th: expires_in: หมดอายุหลังจาก fields: ข้อมูลเมตาโปรไฟล์ header: ส่วนหัว + honeypot: "%{label} (ไม่ต้องกรอก)" inbox_url: URL กล่องขาเข้าแบบรีเลย์ irreversible: ลบแทนที่จะซ่อน locale: ภาษาส่วนติดต่อ @@ -194,6 +195,7 @@ th: sign_up_requires_approval: จำกัดการลงทะเบียน severity: กฎ notification_emails: + appeal: ใครสักคนอุทธรณ์การตัดสินใจของผู้ควบคุม digest: ส่งอีเมลสรุป favourite: ใครสักคนได้ชื่นชอบโพสต์ของคุณ follow: ใครสักคนได้ติดตามคุณ diff --git a/config/locales/sk.yml b/config/locales/sk.yml index 2405c5872..687f4d40d 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -15,6 +15,7 @@ sk: contact: Kontakt contact_missing: Nezadaný contact_unavailable: Neuvedený/á + continue_to_web: Pokračovať na webovú aplikáciu discover_users: Objavuj užívateľov documentation: Dokumentácia federation_hint_html: S účtom na %{instance} budeš môcť následovať ľúdí na hociakom Mastodon serveri, ale aj na iných serveroch. @@ -24,6 +25,7 @@ sk: Tento účet je virtuálnym aktérom, ktorý predstavuje samotný server a nie žiadného jedného užívateľa. Je využívaný pre potreby federovania a nemal by byť blokovaný, pokiaľ nechceš zablokovať celý server, čo ide lepšie dosiahnúť cez blokovanie domény. learn_more: Zisti viac + logged_in_as_html: Práve si prihlásený/á ako %{username}. logout_before_registering: Už si prihlásený/á. privacy_policy: Zásady súkromia rules: Serverové pravidlá diff --git a/config/locales/th.yml b/config/locales/th.yml index c4294be7f..beafc4da4 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -52,6 +52,7 @@ th: what_is_mastodon: Mastodon คืออะไร? accounts: choices_html: 'ตัวเลือกของ %{name}:' + endorsements_hint: คุณสามารถแนะนำผู้คนที่คุณติดตามจากส่วนติดต่อเว็บ และเขาจะปรากฏที่นี่ featured_tags_hint: คุณสามารถแนะนำแฮชแท็กที่เฉพาะเจาะจงที่จะแสดงที่นี่ follow: ติดตาม followers: @@ -66,6 +67,8 @@ th: nothing_here: ไม่มีสิ่งใดที่นี่! people_followed_by: ผู้คนที่ %{name} ติดตาม people_who_follow: ผู้คนที่ติดตาม %{name} + pin_errors: + following: คุณต้องกำลังติดตามคนที่คุณต้องการแนะนำอยู่แล้ว posts: other: โพสต์ posts_tab_heading: โพสต์ @@ -269,6 +272,7 @@ th: update_domain_block: อัปเดตการปิดกั้นโดเมน update_status: อัปเดตโพสต์ actions: + approve_appeal_html: "%{name} ได้อนุมัติการอุทธรณ์การตัดสินใจในการควบคุมจาก %{target}" approve_user_html: "%{name} ได้อนุมัติการลงทะเบียนจาก %{target}" assigned_to_self_report_html: "%{name} ได้มอบหมายรายงาน %{target} ให้กับตนเอง" change_email_user_html: "%{name} ได้เปลี่ยนที่อยู่อีเมลของผู้ใช้ %{target}" @@ -299,6 +303,7 @@ th: enable_user_html: "%{name} ได้เปิดใช้งานการเข้าสู่ระบบสำหรับผู้ใช้ %{target}" memorialize_account_html: "%{name} ได้เปลี่ยนบัญชีของ %{target} เป็นหน้าอนุสรณ์" promote_user_html: "%{name} ได้เลื่อนขั้นผู้ใช้ %{target}" + reject_appeal_html: "%{name} ได้ปฏิเสธการอุทธรณ์การตัดสินใจในการควบคุมจาก %{target}" reject_user_html: "%{name} ได้ปฏิเสธการลงทะเบียนจาก %{target}" remove_avatar_user_html: "%{name} ได้เอาภาพประจำตัวของ %{target} ออก" reopen_report_html: "%{name} ได้เปิดรายงาน %{target} ใหม่" @@ -786,6 +791,9 @@ th: sensitive: เพื่อทำเครื่องหมายบัญชีของเขาว่าละเอียดอ่อน silence: เพื่อจำกัดบัญชีของเขา suspend: เพื่อระงับบัญชีของเขา + body: "%{target} กำลังอุทธรณ์การตัดสินใจในการควบคุมโดย %{action_taken_by} จาก %{date} ซึ่งเป็น %{type} เขาเขียนว่า:" + next_steps: คุณสามารถอนุมัติการอุทธรณ์เพื่อเลิกทำการตัดสินใจในการควบคุม หรือเพิกเฉยการอุทธรณ์ + subject: "%{username} กำลังอุทธรณ์การตัดสินใจในการควบคุมใน %{instance}" new_pending_account: body: รายละเอียดของบัญชีใหม่อยู่ด้านล่าง คุณสามารถอนุมัติหรือปฏิเสธใบสมัครนี้ new_report: diff --git a/config/locales/uk.yml b/config/locales/uk.yml index a4d29d3e4..ec0036226 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -459,6 +459,17 @@ uk: back_to_warning: Попередження by_domain: Домен confirm_purge: Ви впевнені, що хочете видалити ці дані з цього домену? + content_policies: + policies: + reject_media: Відхилити медіа + reject_reports: Відхилити скарги + silence: Обмеження + suspend: Призупинити + policy: Правила + reason: Суспільна причина + title: Політика вмісту + dashboard: + instance_languages_dimension: Найуживаніші мови delivery: all: Усі clear: Очистити помилки доставляння @@ -731,6 +742,10 @@ uk: rejected: Посилання цього публікатора можуть не будуть популярними title: Публікатори rejected: Відхилено + statuses: + allow: Дозволити оприлюднення + allow_account: Дозволити автора + disallow_account: Заборонити автора tags: current_score: Поточний результат %{score} dashboard: @@ -1334,6 +1349,7 @@ uk: many: 'заборонених хештеґів: %{tags}' one: 'заборонений хештеґ: %{tags}' other: 'заборонених хештеґів: %{tags}' + edited_at_html: Відредаговано %{date} errors: in_reply_not_found: Статуса, на який ви намагаєтеся відповісти, не існує. open_in_web: Відкрити у вебі @@ -1396,7 +1412,7 @@ uk: '2629746': 1 місяць '31556952': 1 рік '5259492': 2 місяці - '604800': 1 week + '604800': 1 тиждень '63113904': 2 роки '7889238': 3 місяці min_age_label: Поріг давності diff --git a/config/locales/vi.yml b/config/locales/vi.yml index 459b950a6..ea196a5cd 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -51,7 +51,7 @@ vi: user_count_after: other: người dùng user_count_before: Nhà của - what_is_mastodon: Tham gia Mastodon + what_is_mastodon: Mastodon accounts: choices_html: "%{name} tôn vinh:" endorsements_hint: Bạn có thể tôn vinh những người bạn theo dõi và họ sẽ hiển thị ở giao diện web. @@ -186,7 +186,7 @@ vi: roles: admin: Quản trị viên moderator: Kiểm duyệt viên - staff: Nhân viên + staff: Đội ngũ user: Người dùng search: Tìm kiếm search_same_email_domain: Tra cứu email @@ -227,7 +227,7 @@ vi: whitelisted: Danh sách trắng action_logs: action_types: - approve_appeal: Đồng ý kháng cáo + approve_appeal: Phê duyệt kháng cáo approve_user: Phê duyệt người dùng assigned_to_self_report: Tự xử lý báo cáo change_email_user: Đổi email @@ -295,7 +295,7 @@ vi: destroy_announcement_html: "%{name} xóa thông báo %{target}" destroy_custom_emoji_html: "%{name} đã xóa emoji %{target}" destroy_domain_allow_html: "%{name} đã ngừng liên hợp với %{target}" - destroy_domain_block_html: "%{name} bỏ chặn tên miền email %{target}" + destroy_domain_block_html: "%{name} bỏ chặn máy chủ %{target}" destroy_email_domain_block_html: "%{name} bỏ chặn tên miền email %{target}" destroy_instance_html: "%{name} thanh trừng máy chủ %{target}" destroy_ip_block_html: "%{name} bỏ chặn IP %{target}" @@ -388,7 +388,7 @@ vi: interactions: tương tác media_storage: Dung lượng lưu trữ new_users: người dùng mới - opened_reports: báo cáo chưa xử lí + opened_reports: tổng báo cáo pending_appeals_html: other: "%{count} kháng cáo đang chờ" pending_reports_html: @@ -584,20 +584,20 @@ vi: action_log: Nhật ký kiểm duyệt action_taken_by: Hành động được thực hiện bởi actions: - delete_description_html: Những tút bị báo cáo sẽ được xóa và 1 thẹo sẽ được ghi lại để giúp bạn lưu ý về tài khoản này trong tương lai. - mark_as_sensitive_description_html: Media trong báo cáo sẽ bị đánh dấu nhạy cảm và bạn nhận 1 lần cảnh cáo. + delete_description_html: Những tút bị báo cáo sẽ được xóa và 1 lần cảnh cáo sẽ được ghi lại để giúp bạn lưu ý về tài khoản này trong tương lai. + mark_as_sensitive_description_html: Media trong báo cáo sẽ bị đánh dấu nhạy cảm và họ nhận 1 lần cảnh cáo. other_description_html: Những tùy chọn để kiểm soát tài khoản và giao tiếp với tài khoản bị báo cáo. - resolve_description_html: Không có hành động nào áp dụng đối với tài khoản bị báo cáo, không có thẹo, và báo cáo sẽ được đóng. + resolve_description_html: Không có hành động nào áp dụng đối với tài khoản bị báo cáo, không có cảnh cáo, và báo cáo sẽ được đóng. silence_description_html: Trang cá nhân sẽ chỉ hiển thị với những người đã theo dõi hoặc tìm kiếm thủ công, hạn chế tối đa tầm ảnh hưởng của nó. Có thể đổi lại bình thường sau. suspend_description_html: Trang cá nhân và tất cả các nội dung sẽ không thể truy cập cho đến khi nó bị xóa hoàn toàn. Không thể tương tác với tài khoản. Đảo ngược trong vòng 30 ngày. - actions_description_html: Quyết định hướng xử lý báo cáo này. Nếu áp đặt trừng phạt, một email thông báo sẽ được gửi cho họ, ngoại trừ nếu đó là Spam. + actions_description_html: Hướng xử lý báo cáo này. Nếu áp đặt trừng phạt, một email thông báo sẽ được gửi cho họ, ngoại trừ Spam. add_to_report: Bổ sung báo cáo are_you_sure: Bạn có chắc không? assign_to_self: Giao cho tôi assigned: Người xử lý by_target_domain: Tên tài khoản bị báo cáo category: Phân loại - category_description_html: Lý do tài khoản hoặc nội dung này bị báo cáo sẽ được trích dẫn trong giao tiếp với tài khoản báo cáo + category_description_html: Lý do tài khoản hoặc nội dung này bị báo cáo sẽ được trích dẫn khi giao tiếp với họ comment: none: Không có mô tả comment_description_html: 'Để cung cấp thêm thông tin, %{name} cho biết:' @@ -628,7 +628,7 @@ vi: skip_to_actions: Kiểm duyệt ngay status: Trạng thái statuses: Nội dung bị báo cáo - statuses_description_html: Lý do tài khoản hoặc nội dung này bị báo cáo sẽ được trích dẫn trong giao tiếp với tài khoản báo cáo + statuses_description_html: Lý do tài khoản hoặc nội dung này bị báo cáo sẽ được trích dẫn khi giao tiếp với họ target_origin: Nguồn báo cáo title: Báo cáo unassign: Bỏ qua @@ -703,8 +703,8 @@ vi: desc_html: Nếu tắt, bảng tin sẽ chỉ hiển thị nội dung do người dùng của máy chủ này tạo ra title: Bao gồm nội dung từ mạng liên hợp trên bảng tin không được xác thực show_staff_badge: - desc_html: Hiển thị huy hiệu nhân viên trên trang người dùng - title: Hiển thị huy hiệu nhân viên + desc_html: Hiện huy hiệu đội ngũ trên trang người dùng + title: Hiện huy hiệu đội ngũ site_description: desc_html: Nội dung giới thiệu về máy chủ. Mô tả những gì làm cho máy chủ Mastodon này đặc biệt và bất cứ điều gì quan trọng khác. Bạn có thể dùng các thẻ HTML, đặc biệt là <a><em>. title: Mô tả máy chủ @@ -774,11 +774,11 @@ vi: approved: Đã cho phép disallow: Cấm links: - allow: Liên kết cho phép - allow_provider: Nguồn đăng cho phép - description_html: Đây là những liên kết được chia sẻ nhiều trên máy chủ của bạn. Nó có thể giúp người dùng tìm hiểu những gì đang xảy ra trên thế giới. Không có liên kết nào được hiển thị công khai cho đến khi bạn duyệt nguồn. Bạn cũng có thể cho phép hoặc từ chối từng liên kết riêng. - disallow: Liên kết cấm - disallow_provider: Nguồn đăng bị cấm + allow: Cho phép liên kết + allow_provider: Cho phép nguồn đăng + description_html: Đây là những liên kết được chia sẻ nhiều trên máy chủ của bạn. Nó có thể giúp người dùng tìm hiểu những gì đang xảy ra trên thế giới. Không có liên kết nào được hiển thị công khai cho đến khi bạn duyệt nguồn đăng. Bạn cũng có thể cho phép hoặc từ chối từng liên kết riêng. + disallow: Cấm liên kết + disallow_provider: Cấm nguồn đăng shared_by_over_week: one: một người chia sẻ trong tuần qua other: "%{count} người chia sẻ trong tuần qua" @@ -796,8 +796,8 @@ vi: allow: Cho phép tút allow_account: Cho phép người đăng description_html: Đây là những tút đang được đăng lại và yêu thích rất nhiều trên máy chủ của bạn. Nó có thể giúp người dùng mới và người dùng cũ tìm thấy nhiều người hơn để theo dõi. Không có tút nào được hiển thị công khai cho đến khi bạn cho phép người đăng và người cho phép đề xuất tài khoản của họ cho người khác. Bạn cũng có thể cho phép hoặc từ chối từng tút riêng. - disallow: Không cho phép tút - disallow_account: Không cho phép người đăng + disallow: Cấm tút + disallow_account: Cấm người đăng not_discoverable: Tác giả đã chọn không tham gia mục khám phá shared_by: other: Được thích và đăng lại %{friendly_count} lần @@ -817,7 +817,7 @@ vi: not_usable: Không được phép dùng peaked_on_and_decaying: Đỉnh điểm %{date}, giờ đang giảm title: Hashtag xu hướng - trendable: Có thể xuất hiện thành xu hướng + trendable: Có thể trở thành xu hướng trending_rank: 'Xu hướng #%{rank}' usable: Có thể dùng usage_comparison: Dùng %{today} lần hôm nay, so với %{yesterday} hôm qua @@ -1094,7 +1094,7 @@ vi: new: title: Thêm bộ lọc mới footer: - developers: Nhà phát triển + developers: Phát triển more: Nhiều hơn resources: Quy tắc trending_now: Xu hướng @@ -1433,7 +1433,7 @@ vi: show_more: Đọc thêm show_newer: Mới hơn show_older: Cũ hơn - show_thread: Toàn chủ đề + show_thread: Xem chuỗi tút này sign_in_to_participate: Đăng nhập để trả lời tút này title: '%{name}: "%{quote}"' visibilities: @@ -1609,7 +1609,7 @@ vi: none: Cảnh báo sensitive: Tài khoản đã bị đánh dấu nhạy cảm silence: Tài khoản bị hạn chế - suspend: Toài khoản bị vô hiệu hóa + suspend: Tài khoản bị vô hiệu hóa welcome: edit_profile_action: Cài đặt trang cá nhân edit_profile_step: Bạn có thể tùy chỉnh trang cá nhân của mình bằng cách tải lên ảnh đại diện, ảnh bìa, thay đổi tên hiển thị và hơn thế nữa. Nếu bạn muốn những người theo dõi mới phải được phê duyệt, hãy chuyển tài khoản sang trạng thái khóa. -- cgit From cf5435bb27b38f317d7d02de4df49c517614b4be Mon Sep 17 00:00:00 2001 From: Gomasy Date: Mon, 21 Mar 2022 12:45:58 +0900 Subject: Fix being unable to search by domain (#17832) --- app/views/admin/accounts/index.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/accounts/index.html.haml b/app/views/admin/accounts/index.html.haml index 7c0045145..60e4894d0 100644 --- a/app/views/admin/accounts/index.html.haml +++ b/app/views/admin/accounts/index.html.haml @@ -36,7 +36,7 @@ = hidden_field_tag key, params[key] - %i(username by_domain display_name email ip).each do |key| - - unless key == :by_domain && params[:remote].blank? + - unless key == :by_domain && params[:origin] != 'remote' .input.string.optional = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.accounts.#{key}") -- cgit From 584d8b977b3b8276da3c9035a3d16e61840fc0dc Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Mon, 21 Mar 2022 12:46:11 +0900 Subject: Format JSON and YAML using Prettier (#17823) * Format JSON and YAML using Prettier * Add prettier to devDep --- .codeclimate.yml | 10 ++--- .devcontainer/devcontainer.json | 20 ++++----- .devcontainer/docker-compose.yml | 5 +-- .github/dependabot.yml | 4 +- .github/workflows/build-image.yml | 4 +- .github/workflows/check-i18n.yml | 40 +++++++++--------- .prettierignore | 78 ++++++++++++++++++++++++++++++++++ .prettierrc.js | 3 ++ .rubocop.yml | 22 +++++----- app.json | 5 +-- boxfile.yml | 32 ++++++-------- config/database.yml | 1 - config/i18n-tasks.yml | 4 +- docker-compose.yml | 89 ++++++++++++++++++++------------------- package.json | 5 ++- scalingo.json | 5 +-- yarn.lock | 5 +++ 17 files changed, 203 insertions(+), 129 deletions(-) create mode 100644 .prettierignore create mode 100644 .prettierrc.js diff --git a/.codeclimate.yml b/.codeclimate.yml index c253bd95a..ee9022cda 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -1,4 +1,4 @@ -version: "2" +version: '2' checks: argument-count: enabled: false @@ -34,8 +34,8 @@ plugins: sass-lint: enabled: true exclude_patterns: -- spec/ -- vendor/asset/ + - spec/ + - vendor/asset/ -- app/javascript/mastodon/locales/**/*.json -- config/locales/**/*.yml + - app/javascript/mastodon/locales/**/*.json + - config/locales/**/*.yml diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 78e940763..628efc8ec 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -5,22 +5,22 @@ "workspaceFolder": "/workspaces/mastodon", // Set *default* container specific settings.json values on container create. - "settings": {}, + "settings": {}, // Add the IDs of extensions you want installed when the container is created. - "extensions": [ + "extensions": [ "EditorConfig.EditorConfig", "dbaeumer.vscode-eslint", - "rebornix.Ruby" - ], + "rebornix.Ruby" + ], // Use 'forwardPorts' to make a list of ports inside the container available locally. - // This can be used to network with other containers or the host. - "forwardPorts": [3000, 4000], + // This can be used to network with other containers or the host. + "forwardPorts": [3000, 4000], - // Use 'postCreateCommand' to run commands after the container is created. - "postCreateCommand": "bundle install --path vendor/bundle && yarn install && ./bin/rails db:setup", + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "bundle install --path vendor/bundle && yarn install && ./bin/rails db:setup", - // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. - "remoteUser": "vscode" + // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "vscode" } diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 906fce430..538f6cccd 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -9,9 +9,9 @@ services: # Update 'VARIANT' to pick a version of Ruby: 3, 3.1, 3.0, 2, 2.7, 2.6 # Append -bullseye or -buster to pin to an OS version. # Use -bullseye variants on local arm64/Apple Silicon. - VARIANT: "3.0-bullseye" + VARIANT: '3.0-bullseye' # Optional Node.js version to install - NODE_VERSION: "14" + NODE_VERSION: '14' volumes: - ..:/workspaces/mastodon:cached environment: @@ -34,7 +34,6 @@ services: - internal_network user: vscode - db: image: postgres:14-alpine restart: unless-stopped diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c4cd48878..bb1fccf7c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,7 +6,7 @@ version: 2 updates: - package-ecosystem: npm - directory: "/" + directory: '/' schedule: interval: weekly open-pull-requests-limit: 99 @@ -14,7 +14,7 @@ updates: - dependency-type: direct - package-ecosystem: bundler - directory: "/" + directory: '/' schedule: interval: weekly open-pull-requests-limit: 99 diff --git a/.github/workflows/build-image.yml b/.github/workflows/build-image.yml index bae185484..75c7b54a6 100644 --- a/.github/workflows/build-image.yml +++ b/.github/workflows/build-image.yml @@ -3,9 +3,9 @@ on: workflow_dispatch: push: branches: - - "main" + - 'main' tags: - - "*" + - '*' pull_request: paths: - .github/workflows/build-image.yml diff --git a/.github/workflows/check-i18n.yml b/.github/workflows/check-i18n.yml index 9cb98dd12..be38a096d 100644 --- a/.github/workflows/check-i18n.yml +++ b/.github/workflows/check-i18n.yml @@ -2,9 +2,9 @@ name: Check i18n on: push: - branches: [ main ] + branches: [main] pull_request: - branches: [ main ] + branches: [main] env: RAILS_ENV: test @@ -14,21 +14,21 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Install system dependencies - run: | - sudo apt-get update - sudo apt-get install -y libicu-dev libidn11-dev - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.0' - bundler-cache: true - - name: Check locale file normalization - run: bundle exec i18n-tasks check-normalized - - name: Check for unused strings - run: bundle exec i18n-tasks unused -l en - - name: Check for wrong string interpolations - run: bundle exec i18n-tasks check-consistent-interpolations - - name: Check that all required locale files exist - run: bundle exec rake repo:check_locales_files + - uses: actions/checkout@v2 + - name: Install system dependencies + run: | + sudo apt-get update + sudo apt-get install -y libicu-dev libidn11-dev + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.0' + bundler-cache: true + - name: Check locale file normalization + run: bundle exec i18n-tasks check-normalized + - name: Check for unused strings + run: bundle exec i18n-tasks unused -l en + - name: Check for wrong string interpolations + run: bundle exec i18n-tasks check-consistent-interpolations + - name: Check that all required locale files exist + run: bundle exec rake repo:check_locales_files diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..de7673eb6 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,78 @@ +# See https://help.github.com/articles/ignoring-files for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile '~/.gitignore_global' + +# Ignore bundler config and downloaded libraries. +/.bundle +/vendor/bundle + +# Ignore the default SQLite database. +/db/*.sqlite3 +/db/*.sqlite3-journal + +# Ignore all logfiles and tempfiles. +.eslintcache +/log/* +!/log/.keep +/tmp +/coverage +/public/system +/public/assets +/public/packs +/public/packs-test +.env +.env.production +.env.development +/node_modules/ +/build/ + +# Ignore Vagrant files +.vagrant/ + +# Ignore Capistrano customizations +/config/deploy/* + +# Ignore IDE files +.vscode/ +.idea/ + +# Ignore postgres + redis + elasticsearch volume optionally created by docker-compose +/postgres +/postgres14 +/redis +/elasticsearch + +# ignore Helm dependency charts +/chart/charts/*.tgz + +# Ignore Apple files +.DS_Store + +# Ignore vim files +*~ +*.swp + +# Ignore npm debug log +npm-debug.log + +# Ignore yarn log files +yarn-error.log +yarn-debug.log + +# Ignore vagrant log files +*-cloudimg-console.log + +# Ignore Docker option files +docker-compose.override.yml + +# Ignore Helm files +/chart + +# Ignore emoji map file +/app/javascript/mastodon/features/emoji/emoji_map.json + +# Ignore locale files +/app/javascript/mastodon/locales +/config/locales diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 000000000..1d70813d5 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,3 @@ +module.exports = { + singleQuote: true +} diff --git a/.rubocop.yml b/.rubocop.yml index 4948aea5a..a76937426 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -5,17 +5,17 @@ AllCops: TargetRubyVersion: 2.5 NewCops: disable Exclude: - - 'spec/**/*' - - 'db/**/*' - - 'app/views/**/*' - - 'config/**/*' - - 'bin/*' - - 'Rakefile' - - 'node_modules/**/*' - - 'Vagrantfile' - - 'vendor/**/*' - - 'lib/json_ld/*' - - 'lib/templates/**/*' + - 'spec/**/*' + - 'db/**/*' + - 'app/views/**/*' + - 'config/**/*' + - 'bin/*' + - 'Rakefile' + - 'node_modules/**/*' + - 'Vagrantfile' + - 'vendor/**/*' + - 'lib/json_ld/*' + - 'lib/templates/**/*' Bundler/OrderedGems: Enabled: false diff --git a/app.json b/app.json index 6b4365383..c694908c5 100644 --- a/app.json +++ b/app.json @@ -95,8 +95,5 @@ "scripts": { "postdeploy": "bundle exec rails db:migrate && bundle exec rails db:seed" }, - "addons": [ - "heroku-postgresql", - "heroku-redis" - ] + "addons": ["heroku-postgresql", "heroku-redis"] } diff --git a/boxfile.yml b/boxfile.yml index c1d89bb15..27166cec9 100644 --- a/boxfile.yml +++ b/boxfile.yml @@ -43,20 +43,19 @@ run.config: fs_watch: true - deploy.config: extra_steps: - NODE_ENV=production bundle exec rake assets:precompile transform: - - "envsubst < /app/.env.nanobox > /app/.env.production" + - 'envsubst < /app/.env.nanobox > /app/.env.production' - |- - if [ -z "$LOCAL_DOMAIN" ] - then - . /app/.env.production - export LOCAL_DOMAIN - fi - erb /app/nanobox/nginx-web.conf.erb > /app/nanobox/nginx-web.conf - erb /app/nanobox/nginx-stream.conf.erb > /app/nanobox/nginx-stream.conf + if [ -z "$LOCAL_DOMAIN" ] + then + . /app/.env.production + export LOCAL_DOMAIN + fi + erb /app/nanobox/nginx-web.conf.erb > /app/nanobox/nginx-web.conf + erb /app/nanobox/nginx-stream.conf.erb > /app/nanobox/nginx-stream.conf - touch /app/log/production.log before_live: web.web: @@ -65,11 +64,10 @@ deploy.config: after_live: worker.sidekiq: - |- - if [[ "${ES_ENABLED}" != "false" ]] - then - bin/tootctl search deploy - fi - + if [[ "${ES_ENABLED}" != "false" ]] + then + bin/tootctl search deploy + fi web.web: start: @@ -89,7 +87,6 @@ web.web: data.storage: - public/system - web.stream: start: nginx: nginx -c /app/nanobox/nginx-stream.conf @@ -103,7 +100,6 @@ web.stream: writable_dirs: - tmp - worker.sidekiq: start: default: bundle exec sidekiq -c 5 -q default -L /app/log/sidekiq.log @@ -123,7 +119,6 @@ worker.sidekiq: data.storage: - public/system - data.db: image: nanobox/postgresql:9.6 @@ -145,7 +140,6 @@ data.db: curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/${file} -X DELETE done - data.elastic: image: nanobox/elasticsearch:5 @@ -171,7 +165,6 @@ data.elastic: curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/${file} -X DELETE done - data.redis: image: nanobox/redis:4.0 @@ -191,7 +184,6 @@ data.redis: curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/${file} -X DELETE done - data.storage: image: nanobox/unfs:0.9 diff --git a/config/database.yml b/config/database.yml index 9b8d096e9..127a78abf 100644 --- a/config/database.yml +++ b/config/database.yml @@ -32,4 +32,3 @@ production: host: <%= ENV['DB_HOST'] || 'localhost' %> port: <%= ENV['DB_PORT'] || 5432 %> prepared_statements: <%= ENV['PREPARED_STATEMENTS'] || 'true' %> - diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index 7f879b1aa..bc48323e4 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -17,8 +17,8 @@ data: search: paths: - - app/ - - config/navigation.rb + - app/ + - config/navigation.rb relative_roots: - app/controllers diff --git a/docker-compose.yml b/docker-compose.yml index 01fe320a4..5c2c0c5df 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,5 @@ version: '3' services: - db: restart: always image: postgres:14-alpine @@ -8,11 +7,11 @@ services: networks: - internal_network healthcheck: - test: ["CMD", "pg_isready", "-U", "postgres"] + test: ['CMD', 'pg_isready', '-U', 'postgres'] volumes: - ./postgres14:/var/lib/postgresql/data environment: - - "POSTGRES_HOST_AUTH_METHOD=trust" + - 'POSTGRES_HOST_AUTH_METHOD=trust' redis: restart: always @@ -20,28 +19,28 @@ services: networks: - internal_network healthcheck: - test: ["CMD", "redis-cli", "ping"] + test: ['CMD', 'redis-cli', 'ping'] volumes: - ./redis:/data -# es: -# restart: always -# image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2 -# environment: -# - "ES_JAVA_OPTS=-Xms512m -Xmx512m" -# - "cluster.name=es-mastodon" -# - "discovery.type=single-node" -# - "bootstrap.memory_lock=true" -# networks: -# - internal_network -# healthcheck: -# test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"] -# volumes: -# - ./elasticsearch:/usr/share/elasticsearch/data -# ulimits: -# memlock: -# soft: -1 -# hard: -1 + # es: + # restart: always + # image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2 + # environment: + # - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + # - "cluster.name=es-mastodon" + # - "discovery.type=single-node" + # - "bootstrap.memory_lock=true" + # networks: + # - internal_network + # healthcheck: + # test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"] + # volumes: + # - ./elasticsearch:/usr/share/elasticsearch/data + # ulimits: + # memlock: + # soft: -1 + # hard: -1 web: build: . @@ -53,13 +52,14 @@ services: - external_network - internal_network healthcheck: - test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:3000/health || exit 1"] + # prettier-ignore + test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:3000/health || exit 1'] ports: - - "127.0.0.1:3000:3000" + - '127.0.0.1:3000:3000' depends_on: - db - redis -# - es + # - es volumes: - ./public/system:/mastodon/public/system @@ -73,9 +73,10 @@ services: - external_network - internal_network healthcheck: - test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1"] + # prettier-ignore + test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1'] ports: - - "127.0.0.1:4000:4000" + - '127.0.0.1:4000:4000' depends_on: - db - redis @@ -95,24 +96,24 @@ services: volumes: - ./public/system:/mastodon/public/system healthcheck: - test: ["CMD-SHELL", "ps aux | grep '[s]idekiq\ 6' || false"] + test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"] -## Uncomment to enable federation with tor instances along with adding the following ENV variables -## http_proxy=http://privoxy:8118 -## ALLOW_ACCESS_TO_HIDDEN_SERVICE=true -# tor: -# image: sirboops/tor -# networks: -# - external_network -# - internal_network -# -# privoxy: -# image: sirboops/privoxy -# volumes: -# - ./priv-config:/opt/config -# networks: -# - external_network -# - internal_network + ## Uncomment to enable federation with tor instances along with adding the following ENV variables + ## http_proxy=http://privoxy:8118 + ## ALLOW_ACCESS_TO_HIDDEN_SERVICE=true + # tor: + # image: sirboops/tor + # networks: + # - external_network + # - internal_network + # + # privoxy: + # image: sirboops/privoxy + # volumes: + # - ./priv-config:/opt/config + # networks: + # - external_network + # - internal_network networks: external_network: diff --git a/package.json b/package.json index d42c92ced..61b3622f7 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,9 @@ "test:lint": "${npm_execpath} run test:lint:js && ${npm_execpath} run test:lint:sass", "test:lint:js": "eslint --ext=js . --cache", "test:lint:sass": "sass-lint -v", - "test:jest": "cross-env NODE_ENV=test jest" + "test:jest": "cross-env NODE_ENV=test jest", + "format": "prettier --write '**/*.{json,yml}", + "format-check": "prettier --write '**/*.{json,yml}" }, "repository": { "type": "git", @@ -182,6 +184,7 @@ "eslint-plugin-promise": "~6.0.0", "eslint-plugin-react": "~7.29.3", "jest": "^27.5.1", + "prettier": "^2.6.0", "raf": "^3.4.1", "react-intl-translations-manager": "^5.0.3", "react-test-renderer": "^16.14.0", diff --git a/scalingo.json b/scalingo.json index 51d9b5b9f..511c1802a 100644 --- a/scalingo.json +++ b/scalingo.json @@ -92,8 +92,5 @@ "scripts": { "postdeploy": "bundle exec rails db:migrate && bundle exec rails db:seed" }, - "addons": [ - "postgresql", - "redis" - ] + "addons": ["postgresql", "redis"] } diff --git a/yarn.lock b/yarn.lock index 45e459c40..1327e9f73 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8651,6 +8651,11 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= +prettier@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.0.tgz#12f8f504c4d8ddb76475f441337542fa799207d4" + integrity sha512-m2FgJibYrBGGgQXNzfd0PuDGShJgRavjUoRCw1mZERIWVSXF0iLzLm+aOqTAbLnC3n6JzUhAA8uZnFVghHJ86A== + pretty-format@^25.2.1, pretty-format@^25.5.0: version "25.5.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.5.0.tgz#7873c1d774f682c34b8d48b6743a2bf2ac55791a" -- cgit From a651a9678a4602d3a9c0a27c1efa253a18af8e8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 14:54:59 +0900 Subject: Bump rubocop-rails from 2.14.0 to 2.14.2 (#17833) Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.14.0 to 2.14.2. - [Release notes](https://github.com/rubocop/rubocop-rails/releases) - [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.14.0...v2.14.2) --- updated-dependencies: - dependency-name: rubocop-rails dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index da4070dee..15043d44c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -431,7 +431,7 @@ GEM openssl-signature_algorithm (0.4.0) orm_adapter (0.5.0) ox (2.14.10) - parallel (1.21.0) + parallel (1.22.0) parser (3.1.1.0) ast (~> 2.4.1) parslet (2.0.0) @@ -570,7 +570,7 @@ GEM unicode-display_width (>= 1.4.0, < 3.0) rubocop-ast (1.16.0) parser (>= 3.1.1.0) - rubocop-rails (2.14.0) + rubocop-rails (2.14.2) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.7.0, < 2.0) -- cgit From 47ada1b6d185cb275eff73848bb76c059f8e3eb1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 14:55:12 +0900 Subject: Bump @babel/runtime from 7.17.7 to 7.17.8 (#17835) Bumps [@babel/runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-runtime) from 7.17.7 to 7.17.8. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.17.8/packages/babel-runtime) --- updated-dependencies: - dependency-name: "@babel/runtime" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 61b3622f7..c4eed3fd0 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "@babel/plugin-transform-runtime": "^7.17.0", "@babel/preset-env": "^7.16.11", "@babel/preset-react": "^7.16.7", - "@babel/runtime": "^7.17.7", + "@babel/runtime": "^7.17.8", "@gamestdio/websocket": "^0.3.2", "@github/webauthn-json": "^0.5.7", "@rails/ujs": "^6.1.5", diff --git a/yarn.lock b/yarn.lock index 1327e9f73..c0672ef4a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1036,10 +1036,10 @@ dependencies: regenerator-runtime "^0.12.0" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.7", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.7.tgz#a5f3328dc41ff39d803f311cfe17703418cf9825" - integrity sha512-L6rvG9GDxaLgFjg41K+5Yv9OMrU98sWe+Ykmc6FDJW/+vYZMhdOMKkISgzptMaERHvS2Y2lw9MDRm2gHhlQQoA== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.8", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": + version "7.17.8" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.8.tgz#3e56e4aff81befa55ac3ac6a0967349fd1c5bca2" + integrity sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA== dependencies: regenerator-runtime "^0.13.4" -- cgit From 7eb2e791eed587d9eaa7dee3480f03f7db5a6425 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 14:55:26 +0900 Subject: Bump @babel/core from 7.17.7 to 7.17.8 (#17836) Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.17.7 to 7.17.8. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.17.8/packages/babel-core) --- updated-dependencies: - dependency-name: "@babel/core" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index c4eed3fd0..941c67b74 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ }, "private": true, "dependencies": { - "@babel/core": "^7.17.7", + "@babel/core": "^7.17.8", "@babel/plugin-proposal-decorators": "^7.17.2", "@babel/plugin-transform-react-inline-elements": "^7.16.7", "@babel/plugin-transform-runtime": "^7.17.0", diff --git a/yarn.lock b/yarn.lock index c0672ef4a..ed993f6f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -33,18 +33,18 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2" integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ== -"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.17.7", "@babel/core@^7.7.2", "@babel/core@^7.8.0": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.7.tgz#f7c28228c83cdf2dbd1b9baa06eaf9df07f0c2f9" - integrity sha512-djHlEfFHnSnTAcPb7dATbiM5HxGOP98+3JLBZtjRb5I7RXrw7kFRoG2dXM8cm3H+o11A8IFH/uprmJpwFynRNQ== +"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.17.8", "@babel/core@^7.7.2", "@babel/core@^7.8.0": + version "7.17.8" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.8.tgz#3dac27c190ebc3a4381110d46c80e77efe172e1a" + integrity sha512-OdQDV/7cRBtJHLSOBqqbYNkOcydOgnX59TZx4puf41fzcVtN3e/4yqY8lMQsK+5X2lJtAdmA+6OHqsj1hBJ4IQ== dependencies: "@ampproject/remapping" "^2.1.0" "@babel/code-frame" "^7.16.7" "@babel/generator" "^7.17.7" "@babel/helper-compilation-targets" "^7.17.7" "@babel/helper-module-transforms" "^7.17.7" - "@babel/helpers" "^7.17.7" - "@babel/parser" "^7.17.7" + "@babel/helpers" "^7.17.8" + "@babel/parser" "^7.17.8" "@babel/template" "^7.16.7" "@babel/traverse" "^7.17.3" "@babel/types" "^7.17.0" @@ -295,10 +295,10 @@ "@babel/traverse" "^7.16.8" "@babel/types" "^7.16.8" -"@babel/helpers@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.7.tgz#6fc0a24280fd00026e85424bbfed4650e76d7127" - integrity sha512-TKsj9NkjJfTBxM7Phfy7kv6yYc4ZcOo+AaWGqQOKTPDOmcGkIFb5xNA746eKisQkm4yavUYh4InYM9S+VnO01w== +"@babel/helpers@^7.17.8": + version "7.17.8" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.8.tgz#288450be8c6ac7e4e44df37bcc53d345e07bc106" + integrity sha512-QcL86FGxpfSJwGtAvv4iG93UL6bmqBdmoVY0CMCU2g+oD2ezQse3PT5Pa+jiD6LJndBQi0EDlpzOWNlLuhz5gw== dependencies: "@babel/template" "^7.16.7" "@babel/traverse" "^7.17.3" @@ -322,10 +322,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.3", "@babel/parser@^7.17.7", "@babel/parser@^7.7.0": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.7.tgz#fc19b645a5456c8d6fdb6cecd3c66c0173902800" - integrity sha512-bm3AQf45vR4gKggRfvJdYJ0gFLoCbsPxiFLSH6hTVYABptNHY6l9NrhnucVjQ/X+SPtLANT9lc0fFhikj+VBRA== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.3", "@babel/parser@^7.17.8", "@babel/parser@^7.7.0": + version "7.17.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.8.tgz#2817fb9d885dd8132ea0f8eb615a6388cca1c240" + integrity sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ== "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": version "7.16.7" -- cgit From f29458da1d6b270d44dc0e6a5643a735ecb73aee Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 21 Mar 2022 19:08:29 +0100 Subject: Fix streaming server sometimes silently dropping subscriptions (#17841) --- streaming/index.js | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/streaming/index.js b/streaming/index.js index 3db94b160..d6b445a91 100644 --- a/streaming/index.js +++ b/streaming/index.js @@ -167,6 +167,11 @@ const startWorker = async (workerId) => { const redisPrefix = redisNamespace ? `${redisNamespace}:` : ''; + /** + * @type {Object.>} + */ + const subs = {}; + const redisSubscribeClient = await redisUrlToClient(redisParams, process.env.REDIS_URL); const redisClient = await redisUrlToClient(redisParams, process.env.REDIS_URL); @@ -190,6 +195,22 @@ const startWorker = async (workerId) => { }; }; + /** + * @param {string} message + * @param {string} channel + */ + const onRedisMessage = (message, channel) => { + const callbacks = subs[channel]; + + log.silly(`New message on channel ${channel}`); + + if (!callbacks) { + return; + } + + callbacks.forEach(callback => callback(message)); + }; + /** * @param {string} channel * @param {function(string): void} callback @@ -197,17 +218,33 @@ const startWorker = async (workerId) => { const subscribe = (channel, callback) => { log.silly(`Adding listener for ${channel}`); - redisSubscribeClient.subscribe(channel, callback); + subs[channel] = subs[channel] || []; + + if (subs[channel].length === 0) { + log.verbose(`Subscribe ${channel}`); + redisSubscribeClient.subscribe(channel, onRedisMessage); + } + + subs[channel].push(callback); }; /** * @param {string} channel - * @param {function(string): void} callback */ const unsubscribe = (channel, callback) => { log.silly(`Removing listener for ${channel}`); - redisSubscribeClient.unsubscribe(channel, callback); + if (!subs[channel]) { + return; + } + + subs[channel] = subs[channel].filter(item => item !== callback); + + if (subs[channel].length === 0) { + log.verbose(`Unsubscribe ${channel}`); + redisSubscribeClient.unsubscribe(channel); + delete subs[channel]; + } }; const FALSE_VALUES = [ -- cgit From 3afd59df0f6dd9b9d18718f1ef721aa1d8136ce4 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 21 Mar 2022 19:10:09 +0100 Subject: Fix tootctl email_domain_blocks add (#17842) Fixes #17831 --- lib/mastodon/email_domain_blocks_cli.rb | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/lib/mastodon/email_domain_blocks_cli.rb b/lib/mastodon/email_domain_blocks_cli.rb index f79df302a..f39f47069 100644 --- a/lib/mastodon/email_domain_blocks_cli.rb +++ b/lib/mastodon/email_domain_blocks_cli.rb @@ -32,9 +32,9 @@ module Mastodon multiple domains to the command. When the --with-dns-records option is given, an attempt to resolve the - given domains' DNS records will be made and the results (A, AAAA and MX) will - also be blocked. This can be helpful if you are blocking an e-mail server that - has many different domains pointing to it as it allows you to essentially block + given domains' MX records will be made and the results will also be blocked. + This can be helpful if you are blocking an e-mail server that has many + different domains pointing to it as it allows you to essentially block it at the root. LONG_DESC def add(*domains) @@ -53,26 +53,19 @@ module Mastodon next end - email_domain_block = EmailDomainBlock.new(domain: domain, with_dns_records: options[:with_dns_records] || false) - email_domain_block.save! - processed += 1 - - next unless email_domain_block.with_dns_records? - - hostnames = [] - ips = [] - - Resolv::DNS.open do |dns| - dns.timeouts = 5 - hostnames = dns.getresources(email_domain_block.domain, Resolv::DNS::Resource::IN::MX).to_a.map { |e| e.exchange.to_s } - - ([email_domain_block.domain] + hostnames).uniq.each do |hostname| - ips.concat(dns.getresources(hostname, Resolv::DNS::Resource::IN::A).to_a.map { |e| e.address.to_s }) - ips.concat(dns.getresources(hostname, Resolv::DNS::Resource::IN::AAAA).to_a.map { |e| e.address.to_s }) + other_domains = [] + if options[:with_dns_records] + Resolv::DNS.open do |dns| + dns.timeouts = 5 + other_domains = dns.getresources(@email_domain_block.domain, Resolv::DNS::Resource::IN::MX).to_a end end - (hostnames + ips).uniq.each do |hostname| + email_domain_block = EmailDomainBlock.new(domain: domain, other_domains: other_domains) + email_domain_block.save! + processed += 1 + + (email_domain_block.other_domains || []).uniq.each do |hostname| another_email_domain_block = EmailDomainBlock.new(domain: hostname, parent: email_domain_block) if EmailDomainBlock.where(domain: hostname).exists? -- cgit From 5d90b90755ec038e4eab900461365597e4b09396 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Mar 2022 11:30:20 +0900 Subject: Bump @babel/plugin-proposal-decorators from 7.17.2 to 7.17.8 (#17840) Bumps [@babel/plugin-proposal-decorators](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-proposal-decorators) from 7.17.2 to 7.17.8. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.17.8/packages/babel-plugin-proposal-decorators) --- updated-dependencies: - dependency-name: "@babel/plugin-proposal-decorators" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Yamagishi Kazutoshi --- package.json | 2 +- yarn.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 941c67b74..9b9e2259c 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "private": true, "dependencies": { "@babel/core": "^7.17.8", - "@babel/plugin-proposal-decorators": "^7.17.2", + "@babel/plugin-proposal-decorators": "^7.17.8", "@babel/plugin-transform-react-inline-elements": "^7.16.7", "@babel/plugin-transform-runtime": "^7.17.0", "@babel/preset-env": "^7.16.11", diff --git a/yarn.lock b/yarn.lock index ed993f6f5..dce6e2f1e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -96,10 +96,10 @@ browserslist "^4.17.5" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7", "@babel/helper-create-class-features-plugin@^7.17.1": - version "7.17.1" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.1.tgz#9699f14a88833a7e055ce57dcd3ffdcd25186b21" - integrity sha512-JBdSr/LtyYIno/pNnJ75lBcqc3Z1XXujzPanHqjvvrhOA+DTceTFuJi8XjmWTZh4r3fsdfqaCMN0iZemdkxZHQ== +"@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7", "@babel/helper-create-class-features-plugin@^7.17.6": + version "7.17.6" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.6.tgz#3778c1ed09a7f3e65e6d6e0f6fbfcc53809d92c9" + integrity sha512-SogLLSxXm2OkBbSsHZMM4tUi8fUzjs63AT/d0YQIzr6GSd8Hxsbk2KYDX0k0DweAzGMj/YWeiCsorIdtdcW8Eg== dependencies: "@babel/helper-annotate-as-pure" "^7.16.7" "@babel/helper-environment-visitor" "^7.16.7" @@ -369,12 +369,12 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-proposal-decorators@^7.17.2": - version "7.17.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.17.2.tgz#c36372ddfe0360cac1ee331a238310bddca11493" - integrity sha512-WH8Z95CwTq/W8rFbMqb9p3hicpt4RX4f0K659ax2VHxgOyT6qQmUaEVEjIh4WR9Eh9NymkVn5vwsrE68fAQNUw== +"@babel/plugin-proposal-decorators@^7.17.8": + version "7.17.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.17.8.tgz#4f0444e896bee85d35cf714a006fc5418f87ff00" + integrity sha512-U69odN4Umyyx1xO1rTII0IDkAEC+RNlcKXtqOblfpzqy1C+aOplb76BQNq0+XdpVkOaPlpEDwd++joY8FNFJKA== dependencies: - "@babel/helper-create-class-features-plugin" "^7.17.1" + "@babel/helper-create-class-features-plugin" "^7.17.6" "@babel/helper-plugin-utils" "^7.16.7" "@babel/helper-replace-supers" "^7.16.7" "@babel/plugin-syntax-decorators" "^7.17.0" -- cgit From 737a77cef3403a0b95159fd83bc96f7f01000c83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Mar 2022 11:30:32 +0900 Subject: Bump tzinfo-data from 1.2021.5 to 1.2022.1 (#17839) Bumps [tzinfo-data](https://github.com/tzinfo/tzinfo-data) from 1.2021.5 to 1.2022.1. - [Release notes](https://github.com/tzinfo/tzinfo-data/releases) - [Commits](https://github.com/tzinfo/tzinfo-data/compare/v1.2021.5...v1.2022.1) --- updated-dependencies: - dependency-name: tzinfo-data dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 536470c7d..ad2ccb925 100644 --- a/Gemfile +++ b/Gemfile @@ -89,7 +89,7 @@ gem 'stoplight', '~> 2.2.1' gem 'strong_migrations', '~> 0.7' gem 'tty-prompt', '~> 0.23', require: false gem 'twitter-text', '~> 3.1.0' -gem 'tzinfo-data', '~> 1.2021' +gem 'tzinfo-data', '~> 1.2022' gem 'webpacker', '~> 5.4' gem 'webpush', '~> 0.3' gem 'webauthn', '~> 3.0.0.alpha1' diff --git a/Gemfile.lock b/Gemfile.lock index 15043d44c..464993ccb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -666,7 +666,7 @@ GEM unf (~> 0.1.0) tzinfo (2.0.4) concurrent-ruby (~> 1.0) - tzinfo-data (1.2021.5) + tzinfo-data (1.2022.1) tzinfo (>= 1.0.0) unf (0.1.4) unf_ext @@ -834,7 +834,7 @@ DEPENDENCIES thor (~> 1.2) tty-prompt (~> 0.23) twitter-text (~> 3.1.0) - tzinfo-data (~> 1.2021) + tzinfo-data (~> 1.2022) webauthn (~> 3.0.0.alpha1) webmock (~> 3.14) webpacker (~> 5.4) -- cgit From 883a7918bed331a61cf542b21da19b80ff3325df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Mar 2022 11:30:45 +0900 Subject: Bump letter_opener from 1.7.0 to 1.8.1 (#17838) Bumps [letter_opener](https://github.com/ryanb/letter_opener) from 1.7.0 to 1.8.1. - [Release notes](https://github.com/ryanb/letter_opener/releases) - [Changelog](https://github.com/ryanb/letter_opener/blob/master/CHANGELOG.md) - [Commits](https://github.com/ryanb/letter_opener/compare/v1.7.0...v1.8.1) --- updated-dependencies: - dependency-name: letter_opener dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index ad2ccb925..0cf26980d 100644 --- a/Gemfile +++ b/Gemfile @@ -129,7 +129,7 @@ group :development do gem 'better_errors', '~> 2.9' gem 'binding_of_caller', '~> 1.0' gem 'bullet', '~> 7.0' - gem 'letter_opener', '~> 1.7' + gem 'letter_opener', '~> 1.8' gem 'letter_opener_web', '~> 2.0' gem 'memory_profiler' gem 'rubocop', '~> 1.26', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 464993ccb..cafb814a6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -349,8 +349,8 @@ GEM terrapin (~> 0.6.0) launchy (2.5.0) addressable (~> 2.7) - letter_opener (1.7.0) - launchy (~> 2.2) + letter_opener (1.8.1) + launchy (>= 2.2, < 3) letter_opener_web (2.0.0) actionmailer (>= 5.2) letter_opener (~> 1.7) @@ -770,7 +770,7 @@ DEPENDENCIES json-ld-preloaded (~> 3.2) kaminari (~> 1.2) kt-paperclip (~> 7.1) - letter_opener (~> 1.7) + letter_opener (~> 1.8) letter_opener_web (~> 2.0) link_header (~> 0.0) lograge (~> 0.11) -- cgit From 890fae8b543d938130e5c618ddda2387c3dabd95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Mar 2022 11:30:56 +0900 Subject: Bump eslint-plugin-react from 7.29.3 to 7.29.4 (#17837) Bumps [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) from 7.29.3 to 7.29.4. - [Release notes](https://github.com/yannickcr/eslint-plugin-react/releases) - [Changelog](https://github.com/yannickcr/eslint-plugin-react/blob/master/CHANGELOG.md) - [Commits](https://github.com/yannickcr/eslint-plugin-react/compare/v7.29.3...v7.29.4) --- updated-dependencies: - dependency-name: eslint-plugin-react dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 9b9e2259c..83bf03bd3 100644 --- a/package.json +++ b/package.json @@ -182,7 +182,7 @@ "eslint-plugin-import": "~2.25.4", "eslint-plugin-jsx-a11y": "~6.5.1", "eslint-plugin-promise": "~6.0.0", - "eslint-plugin-react": "~7.29.3", + "eslint-plugin-react": "~7.29.4", "jest": "^27.5.1", "prettier": "^2.6.0", "raf": "^3.4.1", diff --git a/yarn.lock b/yarn.lock index dce6e2f1e..394d08e59 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4387,10 +4387,10 @@ eslint-plugin-promise@~6.0.0: resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.0.0.tgz#017652c07c9816413a41e11c30adc42c3d55ff18" integrity sha512-7GPezalm5Bfi/E22PnQxDWH2iW9GTvAlUNTztemeHb6c1BniSyoeTrM87JkC0wYdi6aQrZX9p2qEiAno8aTcbw== -eslint-plugin-react@~7.29.3: - version "7.29.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.29.3.tgz#f4eab757f2756d25d6d4c2a58a9e20b004791f05" - integrity sha512-MzW6TuCnDOcta67CkpDyRfRsEVx9FNMDV8wZsDqe1luHPdGTrQIUaUXD27Ja3gHsdOIs/cXzNchWGlqm+qRVRg== +eslint-plugin-react@~7.29.4: + version "7.29.4" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.29.4.tgz#4717de5227f55f3801a5fd51a16a4fa22b5914d2" + integrity sha512-CVCXajliVh509PcZYRFyu/BoUEz452+jtQJq2b3Bae4v3xBUWPLCmtmBM+ZinG4MzwmxJgJ2M5rMqhqLVn7MtQ== dependencies: array-includes "^3.1.4" array.prototype.flatmap "^1.2.5" -- cgit From 69f9dc4f4eed9211a0a4ff55c18f64c99165a9e0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Mar 2022 06:08:05 +0100 Subject: Fix color of show more link in report dialog in web UI (#17844) --- app/javascript/styles/mastodon/components.scss | 53 +++++++------------------- 1 file changed, 14 insertions(+), 39 deletions(-) diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 97587b62b..da2492052 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -870,7 +870,8 @@ .status__content__spoiler-link { background: $action-button-color; - &:hover { + &:hover, + &:focus { background: lighten($action-button-color, 7%); text-decoration: none; } @@ -982,7 +983,7 @@ text-transform: uppercase; line-height: 20px; cursor: pointer; - vertical-align: middle; + vertical-align: top; } .status__wrapper--filtered { @@ -1042,42 +1043,6 @@ .audio-player { margin-top: 8px; } - - &.light { - .status__relative-time, - .status__visibility-icon { - color: $light-text-color; - } - - .status__display-name { - color: $inverted-text-color; - } - - .display-name { - color: $light-text-color; - - strong { - color: $inverted-text-color; - } - } - - .status__content { - color: $inverted-text-color; - - a { - color: $highlight-text-color; - } - - a.status__content__spoiler-link { - color: $primary-text-color; - background: $ui-primary-color; - - &:hover { - background: lighten($ui-primary-color, 8%); - } - } - } - } } .status__relative-time, @@ -1646,7 +1611,8 @@ a.account__display-name { background: $ui-base-lighter-color; color: $inverted-text-color; - &:hover { + &:hover, + &:focus { background: lighten($ui-base-lighter-color, 7%); text-decoration: none; } @@ -5158,6 +5124,15 @@ a.status-card.compact:hover { color: $inverted-text-color; } + .status__content__spoiler-link { + color: $primary-text-color; + background: $ui-primary-color; + + &:hover { + background: lighten($ui-primary-color, 8%); + } + } + .dialog-option .poll__input { border-color: $inverted-text-color; color: $ui-secondary-color; -- cgit From 4e9855e09aa4cc2720fed262ffaa6e0c94cf5688 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Mar 2022 09:48:12 +0100 Subject: Add hint about missing media attachment description in web UI (#17845) --- .../mastodon/features/compose/components/upload.js | 9 +++- app/javascript/styles/mastodon/components.scss | 60 +++++----------------- 2 files changed, 20 insertions(+), 49 deletions(-) diff --git a/app/javascript/mastodon/features/compose/components/upload.js b/app/javascript/mastodon/features/compose/components/upload.js index 1289d6b94..706824dc7 100644 --- a/app/javascript/mastodon/features/compose/components/upload.js +++ b/app/javascript/mastodon/features/compose/components/upload.js @@ -5,7 +5,6 @@ import Motion from '../../ui/util/optional_motion'; import spring from 'react-motion/lib/spring'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { FormattedMessage } from 'react-intl'; -import classNames from 'classnames'; import Icon from 'mastodon/components/icon'; export default class Upload extends ImmutablePureComponent { @@ -43,10 +42,16 @@ export default class Upload extends ImmutablePureComponent { {({ scale }) => (
-
+
{!isEditingStatus && ()}
+ + {(media.get('description') || '').length === 0 && ( +
+ +
+ )}
)} diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index da2492052..d1b36d33b 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -596,30 +596,24 @@ display: flex; align-items: flex-start; justify-content: space-between; - opacity: 0; - transition: opacity .1s ease; + } - .icon-button { - flex: 0 1 auto; - color: $secondary-text-color; - font-size: 14px; - font-weight: 500; - padding: 10px; - font-family: inherit; - - &:hover, - &:focus, - &:active { - color: lighten($secondary-text-color, 7%); - } - } + .icon-button { + flex: 0 1 auto; + color: $secondary-text-color; + font-size: 14px; + font-weight: 500; + padding: 10px; + font-family: inherit; - &.active { - opacity: 1; + &:hover, + &:focus, + &:active { + color: lighten($secondary-text-color, 7%); } } - &-description { + &__warning { position: absolute; z-index: 2; bottom: 0; @@ -627,34 +621,6 @@ right: 0; box-sizing: border-box; background: linear-gradient(0deg, rgba($base-shadow-color, 0.8) 0, rgba($base-shadow-color, 0.35) 80%, transparent); - padding: 10px; - opacity: 0; - transition: opacity .1s ease; - - textarea { - background: transparent; - color: $secondary-text-color; - border: 0; - padding: 0; - margin: 0; - width: 100%; - font-family: inherit; - font-size: 14px; - font-weight: 500; - - &:focus { - color: $white; - } - - &::placeholder { - opacity: 0.75; - color: $secondary-text-color; - } - } - - &.active { - opacity: 1; - } } } -- cgit From 392b367835c3c25e37be7c45e8cd130422de10aa Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Mar 2022 10:07:11 +0100 Subject: Fix IDN domains not being rendered correctly in a few left-over places (#17848) --- app/views/accounts/_moved.html.haml | 4 +- app/views/admin/account_actions/new.html.haml | 4 +- .../account_warnings/_account_warning.html.haml | 2 +- app/views/admin/accounts/show.html.haml | 2 +- app/views/admin/change_emails/show.html.haml | 2 +- app/views/admin/disputes/appeals/_appeal.html.haml | 2 +- app/views/admin/relationships/index.html.haml | 2 +- app/views/admin/statuses/index.html.haml | 2 +- app/views/admin_mailer/new_report.text.erb | 2 +- app/views/auth/registrations/_status.html.haml | 2 +- app/views/authorize_interactions/show.html.haml | 2 +- app/views/authorize_interactions/success.html.haml | 2 +- app/views/notification_mailer/_status.html.haml | 2 +- app/views/notification_mailer/digest.text.erb | 2 +- app/views/notification_mailer/favourite.html.haml | 2 +- app/views/notification_mailer/favourite.text.erb | 2 +- app/views/notification_mailer/follow.html.haml | 2 +- app/views/notification_mailer/follow.text.erb | 2 +- .../notification_mailer/follow_request.html.haml | 2 +- .../notification_mailer/follow_request.text.erb | 2 +- app/views/notification_mailer/mention.html.haml | 2 +- app/views/notification_mailer/mention.text.erb | 2 +- app/views/notification_mailer/reblog.html.haml | 2 +- app/views/notification_mailer/reblog.text.erb | 2 +- app/views/settings/aliases/index.html.haml | 2 +- app/views/settings/migrations/show.html.haml | 4 +- config/brakeman.ignore | 80 ++++++++++++++-------- 27 files changed, 79 insertions(+), 59 deletions(-) diff --git a/app/views/accounts/_moved.html.haml b/app/views/accounts/_moved.html.haml index 4f71b062d..2f46e0dd0 100644 --- a/app/views/accounts/_moved.html.haml +++ b/app/views/accounts/_moved.html.haml @@ -3,7 +3,7 @@ .moved-account-widget .moved-account-widget__message = fa_icon 'suitcase' - = t('accounts.moved_html', name: content_tag(:bdi, content_tag(:strong, display_name(account, custom_emojify: true), class: :emojify)), new_profile_link: link_to(content_tag(:strong, safe_join(['@', content_tag(:span, moved_to_account.acct)])), ActivityPub::TagManager.instance.url_for(moved_to_account), class: 'mention')) + = t('accounts.moved_html', name: content_tag(:bdi, content_tag(:strong, display_name(account, custom_emojify: true), class: :emojify)), new_profile_link: link_to(content_tag(:strong, safe_join(['@', content_tag(:span, moved_to_account.pretty_acct)])), ActivityPub::TagManager.instance.url_for(moved_to_account), class: 'mention')) .moved-account-widget__card = link_to ActivityPub::TagManager.instance.url_for(moved_to_account), class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'me noopener noreferrer' do @@ -17,4 +17,4 @@ %span.display-name %bdi %strong.emojify= display_name(moved_to_account, custom_emojify: true) - %span @#{moved_to_account.acct} + %span @#{moved_to_account.pretty_acct} diff --git a/app/views/admin/account_actions/new.html.haml b/app/views/admin/account_actions/new.html.haml index ca4f9663f..c7bb618df 100644 --- a/app/views/admin/account_actions/new.html.haml +++ b/app/views/admin/account_actions/new.html.haml @@ -1,11 +1,11 @@ - content_for :page_title do - = t('admin.account_actions.title', acct: @account.acct) + = t('admin.account_actions.title', acct: @account.pretty_acct) = simple_form_for @account_action, url: admin_account_action_path(@account.id) do |f| = f.input :report_id, as: :hidden .fields-group - = f.input :type, as: :radio_buttons, collection: Admin::AccountAction.types_for_account(@account), include_blank: false, wrapper: :with_block_label, label_method: ->(type) { safe_join([I18n.t("simple_form.labels.admin_account_action.types.#{type}"), content_tag(:span, I18n.t("simple_form.hints.admin_account_action.types.#{type}"), class: 'hint')])}, hint: t('simple_form.hints.admin_account_action.type_html', acct: @account.acct) + = f.input :type, as: :radio_buttons, collection: Admin::AccountAction.types_for_account(@account), include_blank: false, wrapper: :with_block_label, label_method: ->(type) { safe_join([I18n.t("simple_form.labels.admin_account_action.types.#{type}"), content_tag(:span, I18n.t("simple_form.hints.admin_account_action.types.#{type}"), class: 'hint')])}, hint: t('simple_form.hints.admin_account_action.type_html', acct: @account.pretty_acct) - if @account.local? %hr.spacer/ diff --git a/app/views/admin/account_warnings/_account_warning.html.haml b/app/views/admin/account_warnings/_account_warning.html.haml index 1462e76d0..030635185 100644 --- a/app/views/admin/account_warnings/_account_warning.html.haml +++ b/app/views/admin/account_warnings/_account_warning.html.haml @@ -5,7 +5,7 @@ = fa_icon 'warning' .log-entry__content .log-entry__title - = t(account_warning.action, scope: 'admin.strikes.actions', name: content_tag(:span, account_warning.account.username, class: 'username'), target: content_tag(:span, account_warning.target_account.acct, class: 'target')).html_safe + = t(account_warning.action, scope: 'admin.strikes.actions', name: content_tag(:span, account_warning.account.username, class: 'username'), target: content_tag(:span, account_warning.target_account.pretty_acct, class: 'target')).html_safe .log-entry__timestamp %time.formatted{ datetime: account_warning.created_at.iso8601 } = l(account_warning.created_at) diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index 9a1f07a06..805cf8a4f 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -1,5 +1,5 @@ - content_for :page_title do - = @account.acct + = @account.pretty_acct - if @account.instance_actor? .flash-message.notice diff --git a/app/views/admin/change_emails/show.html.haml b/app/views/admin/change_emails/show.html.haml index 6ff0d785e..bc00d6114 100644 --- a/app/views/admin/change_emails/show.html.haml +++ b/app/views/admin/change_emails/show.html.haml @@ -1,5 +1,5 @@ - content_for :page_title do - = t('admin.accounts.change_email.title', username: @account.acct) + = t('admin.accounts.change_email.title', username: @account.username) = simple_form_for @user, url: admin_account_change_email_path(@account.id) do |f| .fields-group diff --git a/app/views/admin/disputes/appeals/_appeal.html.haml b/app/views/admin/disputes/appeals/_appeal.html.haml index 02b8777e1..3f6efb856 100644 --- a/app/views/admin/disputes/appeals/_appeal.html.haml +++ b/app/views/admin/disputes/appeals/_appeal.html.haml @@ -4,7 +4,7 @@ = image_tag appeal.account.avatar.url(:original), alt: '', width: 40, height: 40, class: 'avatar' .log-entry__content .log-entry__title - = t(appeal.strike.action, scope: 'admin.strikes.actions', name: content_tag(:span, appeal.strike.account.username, class: 'username'), target: content_tag(:span, appeal.account.acct, class: 'target')).html_safe + = t(appeal.strike.action, scope: 'admin.strikes.actions', name: content_tag(:span, appeal.strike.account.username, class: 'username'), target: content_tag(:span, appeal.account.username, class: 'target')).html_safe .log-entry__timestamp %time.formatted{ datetime: appeal.strike.created_at.iso8601 } = l(appeal.strike.created_at) diff --git a/app/views/admin/relationships/index.html.haml b/app/views/admin/relationships/index.html.haml index 60b9b5b25..f82cf26a3 100644 --- a/app/views/admin/relationships/index.html.haml +++ b/app/views/admin/relationships/index.html.haml @@ -1,5 +1,5 @@ - content_for :page_title do - = t('admin.relationships.title', acct: @account.acct) + = t('admin.relationships.title', acct: @account.pretty_acct) .filters .filter-subset diff --git a/app/views/admin/statuses/index.html.haml b/app/views/admin/statuses/index.html.haml index 7e2114cc2..d3d7cc160 100644 --- a/app/views/admin/statuses/index.html.haml +++ b/app/views/admin/statuses/index.html.haml @@ -4,7 +4,7 @@ - content_for :page_title do = t('admin.statuses.title') \- - = "@#{@account.acct}" + = "@#{@account.pretty_acct}" .filters .filter-subset diff --git a/app/views/admin_mailer/new_report.text.erb b/app/views/admin_mailer/new_report.text.erb index d6c7d6bab..f8a5224a1 100644 --- a/app/views/admin_mailer/new_report.text.erb +++ b/app/views/admin_mailer/new_report.text.erb @@ -1,5 +1,5 @@ <%= raw t('application_mailer.salutation', name: display_name(@me)) %> -<%= raw(@report.account.local? ? t('admin_mailer.new_report.body', target: @report.target_account.acct, reporter: @report.account.acct) : t('admin_mailer.new_report.body_remote', target: @report.target_account.acct, domain: @report.account.domain)) %> +<%= raw(@report.account.local? ? t('admin_mailer.new_report.body', target: @report.target_account.pretty_acct, reporter: @report.account.pretty_acct) : t('admin_mailer.new_report.body_remote', target: @report.target_account.acct, domain: @report.account.domain)) %> <%= raw t('application_mailer.view')%> <%= admin_report_url(@report) %> diff --git a/app/views/auth/registrations/_status.html.haml b/app/views/auth/registrations/_status.html.haml index 68954a5da..759bbc41c 100644 --- a/app/views/auth/registrations/_status.html.haml +++ b/app/views/auth/registrations/_status.html.haml @@ -7,7 +7,7 @@ = t('auth.status.pending') - elsif @user.account.moved_to_account_id.present? .flash-message.warning - = t('auth.status.redirecting_to', acct: @user.account.moved_to_account.acct) + = t('auth.status.redirecting_to', acct: @user.account.moved_to_account.pretty_acct) = link_to t('migrations.cancel'), settings_migration_path %h3= t('auth.status.account_status') diff --git a/app/views/authorize_interactions/show.html.haml b/app/views/authorize_interactions/show.html.haml index 42c874134..2b4d2ed62 100644 --- a/app/views/authorize_interactions/show.html.haml +++ b/app/views/authorize_interactions/show.html.haml @@ -1,5 +1,5 @@ - content_for :page_title do - = t('authorize_follow.title', acct: @resource.acct) + = t('authorize_follow.title', acct: @resource.pretty_acct) .form-container .follow-prompt diff --git a/app/views/authorize_interactions/success.html.haml b/app/views/authorize_interactions/success.html.haml index 47fd09767..86fa55eac 100644 --- a/app/views/authorize_interactions/success.html.haml +++ b/app/views/authorize_interactions/success.html.haml @@ -1,5 +1,5 @@ - content_for :page_title do - = t('authorize_follow.title', acct: @resource.acct) + = t('authorize_follow.title', acct: @resource.pretty_acct) .form-container .follow-prompt diff --git a/app/views/notification_mailer/_status.html.haml b/app/views/notification_mailer/_status.html.haml index f520208e1..219e7e667 100644 --- a/app/views/notification_mailer/_status.html.haml +++ b/app/views/notification_mailer/_status.html.haml @@ -23,7 +23,7 @@ = image_tag full_asset_url(status.account.avatar.url), alt:'' %td{ align: 'left' } %bdi= display_name(status.account) - = "@#{status.account.acct}" + = "@#{status.account.pretty_acct}" - if status.spoiler_text? %div.auto-dir diff --git a/app/views/notification_mailer/digest.text.erb b/app/views/notification_mailer/digest.text.erb index b2c85a9e3..4cd4190c1 100644 --- a/app/views/notification_mailer/digest.text.erb +++ b/app/views/notification_mailer/digest.text.erb @@ -3,7 +3,7 @@ <%= raw t('notification_mailer.digest.body', since: l(@me.user_current_sign_in_at || @since), instance: root_url) %> <% @notifications.each do |notification| %> -* <%= raw t('notification_mailer.digest.mention', name: notification.from_account.acct) %> +* <%= raw t('notification_mailer.digest.mention', name: notification.from_account.pretty_acct) %> <%= raw Formatter.instance.plaintext(notification.target_status) %> diff --git a/app/views/notification_mailer/favourite.html.haml b/app/views/notification_mailer/favourite.html.haml index a715d615c..ebc5c29c7 100644 --- a/app/views/notification_mailer/favourite.html.haml +++ b/app/views/notification_mailer/favourite.html.haml @@ -20,7 +20,7 @@ = image_tag full_pack_url('media/images/mailer/icon_grade.png'), alt:'' %h1= t 'notification_mailer.favourite.title' - %p.lead= t('notification_mailer.favourite.body', name: @account.acct) + %p.lead= t('notification_mailer.favourite.body', name: @account.pretty_acct) = render 'status', status: @status diff --git a/app/views/notification_mailer/favourite.text.erb b/app/views/notification_mailer/favourite.text.erb index 2581b4909..f4f869656 100644 --- a/app/views/notification_mailer/favourite.text.erb +++ b/app/views/notification_mailer/favourite.text.erb @@ -1,5 +1,5 @@ <%= raw t('application_mailer.salutation', name: display_name(@me)) %> -<%= raw t('notification_mailer.favourite.body', name: @account.acct) %> +<%= raw t('notification_mailer.favourite.body', name: @account.pretty_acct) %> <%= render 'status', status: @status %> diff --git a/app/views/notification_mailer/follow.html.haml b/app/views/notification_mailer/follow.html.haml index cd84f7858..a59ef8835 100644 --- a/app/views/notification_mailer/follow.html.haml +++ b/app/views/notification_mailer/follow.html.haml @@ -20,7 +20,7 @@ = image_tag full_pack_url('media/images/mailer/icon_person_add.png'), alt: '' %h1= t 'notification_mailer.follow.title' - %p.lead= t('notification_mailer.follow.body', name: @account.acct) + %p.lead= t('notification_mailer.follow.body', name: @account.pretty_acct) %table.email-table{ cellspacing: 0, cellpadding: 0 } %tbody diff --git a/app/views/notification_mailer/follow.text.erb b/app/views/notification_mailer/follow.text.erb index cbe46f552..016a0a4cf 100644 --- a/app/views/notification_mailer/follow.text.erb +++ b/app/views/notification_mailer/follow.text.erb @@ -1,5 +1,5 @@ <%= raw t('application_mailer.salutation', name: display_name(@me)) %> -<%= raw t('notification_mailer.follow.body', name: @account.acct) %> +<%= raw t('notification_mailer.follow.body', name: @account.pretty_acct) %> <%= raw t('application_mailer.view')%> <%= web_url("accounts/#{@account.id}") %> diff --git a/app/views/notification_mailer/follow_request.html.haml b/app/views/notification_mailer/follow_request.html.haml index a63e27a90..4c32c831e 100644 --- a/app/views/notification_mailer/follow_request.html.haml +++ b/app/views/notification_mailer/follow_request.html.haml @@ -20,7 +20,7 @@ = image_tag full_pack_url('media/images/mailer/icon_person_add.png'), alt: '' %h1= t 'notification_mailer.follow_request.title' - %p.lead= t('notification_mailer.follow_request.body', name: @account.acct) + %p.lead= t('notification_mailer.follow_request.body', name: @account.pretty_acct) %table.email-table{ cellspacing: 0, cellpadding: 0 } %tbody diff --git a/app/views/notification_mailer/follow_request.text.erb b/app/views/notification_mailer/follow_request.text.erb index a018394b8..66aa97fe3 100644 --- a/app/views/notification_mailer/follow_request.text.erb +++ b/app/views/notification_mailer/follow_request.text.erb @@ -1,5 +1,5 @@ <%= raw t('application_mailer.salutation', name: display_name(@me)) %> -<%= raw t('notification_mailer.follow_request.body', name: @account.acct) %> +<%= raw t('notification_mailer.follow_request.body', name: @account.pretty_acct) %> <%= raw t('application_mailer.view')%> <%= web_url("follow_requests") %> diff --git a/app/views/notification_mailer/mention.html.haml b/app/views/notification_mailer/mention.html.haml index 619873cfa..cfb7465c1 100644 --- a/app/views/notification_mailer/mention.html.haml +++ b/app/views/notification_mailer/mention.html.haml @@ -20,7 +20,7 @@ = image_tag full_pack_url('media/images/mailer/icon_reply.png'), alt: '' %h1= t 'notification_mailer.mention.title' - %p.lead= t('notification_mailer.mention.body', name: @status.account.acct) + %p.lead= t('notification_mailer.mention.body', name: @status.account.pretty_acct) = render 'status', status: @status diff --git a/app/views/notification_mailer/mention.text.erb b/app/views/notification_mailer/mention.text.erb index 03f53813b..f104d5f92 100644 --- a/app/views/notification_mailer/mention.text.erb +++ b/app/views/notification_mailer/mention.text.erb @@ -1,5 +1,5 @@ <%= raw t('application_mailer.salutation', name: display_name(@me)) %> -<%= raw t('notification_mailer.mention.body', name: @status.account.acct) %> +<%= raw t('notification_mailer.mention.body', name: @status.account.pretty_acct) %> <%= render 'status', status: @status %> diff --git a/app/views/notification_mailer/reblog.html.haml b/app/views/notification_mailer/reblog.html.haml index a2811be23..c528536ec 100644 --- a/app/views/notification_mailer/reblog.html.haml +++ b/app/views/notification_mailer/reblog.html.haml @@ -20,7 +20,7 @@ = image_tag full_pack_url('media/images/mailer/icon_cached.png'), alt: '' %h1= t 'notification_mailer.reblog.title' - %p.lead= t('notification_mailer.reblog.body', name: @account.acct) + %p.lead= t('notification_mailer.reblog.body', name: @account.pretty_acct) = render 'status', status: @status diff --git a/app/views/notification_mailer/reblog.text.erb b/app/views/notification_mailer/reblog.text.erb index 8fc841bf6..73a3b3945 100644 --- a/app/views/notification_mailer/reblog.text.erb +++ b/app/views/notification_mailer/reblog.text.erb @@ -1,5 +1,5 @@ <%= raw t('application_mailer.salutation', name: display_name(@me)) %> -<%= raw t('notification_mailer.reblog.body', name: @account.acct) %> +<%= raw t('notification_mailer.reblog.body', name: @account.pretty_acct) %> <%= render 'status', status: @status %> diff --git a/app/views/settings/aliases/index.html.haml b/app/views/settings/aliases/index.html.haml index 5df0c9669..c618a82f1 100644 --- a/app/views/settings/aliases/index.html.haml +++ b/app/views/settings/aliases/index.html.haml @@ -29,5 +29,5 @@ - else - @aliases.each do |account_alias| %tr - %td= account_alias.acct + %td= account_alias.pretty_acct %td= table_link_to 'trash', t('aliases.remove'), settings_alias_path(account_alias), data: { method: :delete } diff --git a/app/views/settings/migrations/show.html.haml b/app/views/settings/migrations/show.html.haml index 078eaebc6..492f6fe12 100644 --- a/app/views/settings/migrations/show.html.haml +++ b/app/views/settings/migrations/show.html.haml @@ -8,7 +8,7 @@ = render 'application/card', account: current_account.moved_to_account .fields-row__column.fields-group.fields-row__column-6 %p.hint - %span.positive-hint= t('migrations.redirecting_to', acct: current_account.moved_to_account.acct) + %span.positive-hint= t('migrations.redirecting_to', acct: current_account.moved_to_account.pretty_acct) %p.hint= t('migrations.cancel_explanation') @@ -76,7 +76,7 @@ - if migration.target_account.present? = compact_account_link_to migration.target_account - else - = migration.acct + = migration.pretty_acct %td= number_with_delimiter migration.followers_count diff --git a/config/brakeman.ignore b/config/brakeman.ignore index c24146da4..80c5f6d4e 100644 --- a/config/brakeman.ignore +++ b/config/brakeman.ignore @@ -7,7 +7,7 @@ "check_name": "SQL", "message": "Possible SQL injection", "file": "app/models/status.rb", - "line": 105, + "line": 106, "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/", "code": "result.joins(\"INNER JOIN statuses_tags t#{id} ON t#{id}.status_id = statuses.id AND t#{id}.tag_id = #{id}\")", "render_path": null, @@ -27,7 +27,7 @@ "check_name": "SQL", "message": "Possible SQL injection", "file": "app/models/trends/query.rb", - "line": 60, + "line": 76, "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/", "code": "klass.joins(\"join unnest(array[#{ids.join(\",\")}]) with ordinality as x (id, ordering) on #{klass.table_name}.id = x.id\")", "render_path": null, @@ -60,6 +60,36 @@ "confidence": "High", "note": "" }, + { + "warning_type": "Cross-Site Scripting", + "warning_code": 2, + "fingerprint": "71cf98c8235b5cfa9946b5db8fdc1a2f3a862566abb34e4542be6f3acae78233", + "check_name": "CrossSiteScripting", + "message": "Unescaped model attribute", + "file": "app/views/admin/disputes/appeals/_appeal.html.haml", + "line": 7, + "link": "https://brakemanscanner.org/docs/warning_types/cross_site_scripting", + "code": "t((Unresolved Model).new.strike.action, :scope => \"admin.strikes.actions\", :name => content_tag(:span, (Unresolved Model).new.strike.account.username, :class => \"username\"), :target => content_tag(:span, (Unresolved Model).new.account.username, :class => \"target\"))", + "render_path": [ + { + "type": "template", + "name": "admin/disputes/appeals/index", + "line": 20, + "file": "app/views/admin/disputes/appeals/index.html.haml", + "rendered": { + "name": "admin/disputes/appeals/_appeal", + "file": "app/views/admin/disputes/appeals/_appeal.html.haml" + } + } + ], + "location": { + "type": "template", + "template": "admin/disputes/appeals/_appeal" + }, + "user_input": "(Unresolved Model).new.strike", + "confidence": "Weak", + "note": "" + }, { "warning_type": "SQL Injection", "warning_code": 0, @@ -121,33 +151,23 @@ "note": "" }, { - "warning_type": "Cross-Site Scripting", - "warning_code": 2, - "fingerprint": "afad51718ae373b2f19d2513029fd2afccf58b9148e475934bc6a162ee33c352", - "check_name": "CrossSiteScripting", - "message": "Unescaped model attribute", - "file": "app/views/admin/disputes/appeals/_appeal.html.haml", - "line": 7, - "link": "https://brakemanscanner.org/docs/warning_types/cross_site_scripting", - "code": "t((Unresolved Model).new.strike.action, :scope => \"admin.strikes.actions\", :name => content_tag(:span, (Unresolved Model).new.strike.account.username, :class => \"username\"), :target => content_tag(:span, (Unresolved Model).new.account.acct, :class => \"target\"))", - "render_path": [ - { - "type": "template", - "name": "admin/disputes/appeals/index", - "line": 20, - "file": "app/views/admin/disputes/appeals/index.html.haml", - "rendered": { - "name": "admin/disputes/appeals/_appeal", - "file": "app/views/admin/disputes/appeals/_appeal.html.haml" - } - } - ], + "warning_type": "Mass Assignment", + "warning_code": 105, + "fingerprint": "ab5035dd1a9f8c3a8d92fb2c37e8fe86fede4f87c91b71aa32e89c9eede602fc", + "check_name": "PermitAttributes", + "message": "Potentially dangerous key allowed for mass assignment", + "file": "app/controllers/api/v1/notifications_controller.rb", + "line": 81, + "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/", + "code": "params.permit(:account_id, :types => ([]), :exclude_types => ([]))", + "render_path": null, "location": { - "type": "template", - "template": "admin/disputes/appeals/_appeal" + "type": "method", + "class": "Api::V1::NotificationsController", + "method": "browserable_params" }, - "user_input": "(Unresolved Model).new.strike", - "confidence": "Weak", + "user_input": ":account_id", + "confidence": "High", "note": "" }, { @@ -184,7 +204,7 @@ { "type": "template", "name": "admin/trends/links/index", - "line": 45, + "line": 49, "file": "app/views/admin/trends/links/index.html.haml", "rendered": { "name": "admin/trends/links/_preview_card", @@ -207,7 +227,7 @@ "check_name": "PermitAttributes", "message": "Potentially dangerous key allowed for mass assignment", "file": "app/controllers/api/v1/reports_controller.rb", - "line": 36, + "line": 26, "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/", "code": "params.permit(:account_id, :comment, :category, :forward, :status_ids => ([]), :rule_ids => ([]))", "render_path": null, @@ -221,6 +241,6 @@ "note": "" } ], - "updated": "2022-02-15 03:48:53 +0100", + "updated": "2022-03-22 07:48:32 +0100", "brakeman_version": "5.2.1" } -- cgit From d5df9d4797eea86a37522c9936228888f69244fd Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Mar 2022 11:58:13 +0100 Subject: Fix wrong position of fade-out element in account card in web UI (#17846) --- app/javascript/styles/mastodon/admin.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index dc4d65edd..68e6d2482 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -1306,7 +1306,7 @@ a.sparkline { width: 50px; height: 21px; position: absolute; - bottom: 8px; + bottom: 0; right: 15px; background: linear-gradient(to left, $ui-base-color, transparent); pointer-events: none; -- cgit From 410989e081b812d6f025489ab589428f987d26c0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Mar 2022 11:58:25 +0100 Subject: Change frequency of trends review notifications from 2 hours to 6 hours (#17850) --- config/sidekiq.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/sidekiq.yml b/config/sidekiq.yml index c8b1a20dd..f2ae9279b 100644 --- a/config/sidekiq.yml +++ b/config/sidekiq.yml @@ -22,7 +22,7 @@ class: Scheduler::EmailDomainBlockRefreshScheduler queue: scheduler trends_review_notifications_scheduler: - every: '2h' + every: '6h' class: Scheduler::Trends::ReviewNotificationsScheduler queue: scheduler media_cleanup_scheduler: -- cgit From 67d550830b3b1a9a2b65b1ab98ea4bcd491666c5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Mar 2022 12:29:04 +0100 Subject: Fix locale not being set in REST API (#17847) --- app/controllers/activitypub/base_controller.rb | 1 + app/controllers/api/base_controller.rb | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/controllers/activitypub/base_controller.rb b/app/controllers/activitypub/base_controller.rb index 4cbc3ab8f..196d85a32 100644 --- a/app/controllers/activitypub/base_controller.rb +++ b/app/controllers/activitypub/base_controller.rb @@ -2,6 +2,7 @@ class ActivityPub::BaseController < Api::BaseController skip_before_action :require_authenticated_user! + skip_around_action :set_locale private diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb index 72c30dec7..d96285b44 100644 --- a/app/controllers/api/base_controller.rb +++ b/app/controllers/api/base_controller.rb @@ -15,8 +15,6 @@ class Api::BaseController < ApplicationController protect_from_forgery with: :null_session - skip_around_action :set_locale - rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e| render json: { error: e.to_s }, status: 422 end -- cgit From 91e6df70266bd475c3d4ef2b411f42cff805bd47 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Mar 2022 09:48:12 +0100 Subject: [Glitch] Add hint about missing media attachment description in web UI Port 4e9855e09aa4cc2720fed262ffaa6e0c94cf5688 to glitch-soc Signed-off-by: Claire --- .../glitch/features/compose/components/upload.js | 9 +++- .../glitch/styles/components/composer.scss | 63 ++++++---------------- .../glitch/styles/mastodon-light/diff.scss | 8 --- 3 files changed, 24 insertions(+), 56 deletions(-) diff --git a/app/javascript/flavours/glitch/features/compose/components/upload.js b/app/javascript/flavours/glitch/features/compose/components/upload.js index 338bfca37..963b95c87 100644 --- a/app/javascript/flavours/glitch/features/compose/components/upload.js +++ b/app/javascript/flavours/glitch/features/compose/components/upload.js @@ -5,7 +5,6 @@ import Motion from 'flavours/glitch/util/optional_motion'; import spring from 'react-motion/lib/spring'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { FormattedMessage } from 'react-intl'; -import classNames from 'classnames'; import Icon from 'flavours/glitch/components/icon'; import { isUserTouching } from 'flavours/glitch/util/is_mobile'; @@ -44,10 +43,16 @@ export default class Upload extends ImmutablePureComponent { {({ scale }) => (
-
+
{!isEditingStatus && ()}
+ + {(media.get('description') || '').length === 0 && ( +
+ +
+ )}
)} diff --git a/app/javascript/flavours/glitch/styles/components/composer.scss b/app/javascript/flavours/glitch/styles/components/composer.scss index 937751d00..96ea096e1 100644 --- a/app/javascript/flavours/glitch/styles/components/composer.scss +++ b/app/javascript/flavours/glitch/styles/components/composer.scss @@ -425,54 +425,12 @@ background-repeat: no-repeat; overflow: hidden; - textarea { - display: block; - position: absolute; - box-sizing: border-box; - bottom: 0; - left: 0; - margin: 0; - border: 0; - padding: 10px; - width: 100%; - color: $secondary-text-color; - background: linear-gradient(0deg, rgba($base-shadow-color, 0.8) 0, rgba($base-shadow-color, 0.35) 80%, transparent); - font-size: 14px; - font-family: inherit; - font-weight: 500; - opacity: 0; - z-index: 2; - transition: opacity .1s ease; - - &:focus { color: $white } - - &::placeholder { - opacity: 0.54; - color: $secondary-text-color; - } - } - & > .close { mix-blend-mode: difference } } - &.active { - & > div { - textarea { opacity: 1 } - } - } -} - -.composer--upload_form--actions { - background: linear-gradient(180deg, rgba($base-shadow-color, 0.8) 0, rgba($base-shadow-color, 0.35) 80%, transparent); - display: flex; - align-items: flex-start; - justify-content: space-between; - opacity: 0; - transition: opacity .1s ease; - .icon-button { flex: 0 1 auto; - color: $ui-secondary-color; + color: $secondary-text-color; font-size: 14px; font-weight: 500; padding: 10px; @@ -481,15 +439,28 @@ &:hover, &:focus, &:active { - color: lighten($ui-secondary-color, 4%); + color: lighten($secondary-text-color, 7%); } } - &.active { - opacity: 1; + &__warning { + position: absolute; + z-index: 2; + bottom: 0; + left: 0; + right: 0; + box-sizing: border-box; + background: linear-gradient(0deg, rgba($base-shadow-color, 0.8) 0, rgba($base-shadow-color, 0.35) 80%, transparent); } } +.composer--upload_form--actions { + background: linear-gradient(180deg, rgba($base-shadow-color, 0.8) 0, rgba($base-shadow-color, 0.35) 80%, transparent); + display: flex; + align-items: flex-start; + justify-content: space-between; +} + .composer--upload_form--progress { display: flex; padding: 10px; diff --git a/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss b/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss index 020d39aff..bb91abdac 100644 --- a/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss +++ b/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss @@ -165,14 +165,6 @@ } } -.composer--upload_form--item > div input { - color: lighten($white, 7%); - - &::placeholder { - color: lighten($white, 10%); - } -} - .dropdown-menu__separator, .dropdown-menu__item.edited-timestamp__history__item, .dropdown-menu__container__header, -- cgit From 33e7ef4d3d163125d73826143edcc0a0f7470781 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Mar 2022 11:58:13 +0100 Subject: [Glitch] Fix wrong position of fade-out element in account card in web UI Port d5df9d4797eea86a37522c9936228888f69244fd Signed-off-by: Claire --- app/javascript/flavours/glitch/styles/admin.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss index 40cd899b3..27be22f1b 100644 --- a/app/javascript/flavours/glitch/styles/admin.scss +++ b/app/javascript/flavours/glitch/styles/admin.scss @@ -1322,7 +1322,7 @@ a.sparkline { width: 50px; height: 21px; position: absolute; - bottom: 8px; + bottom: 0; right: 15px; background: linear-gradient(to left, $ui-base-color, transparent); pointer-events: none; -- cgit From b475c8ab97c839f20757ef606659b15f8d47e79f Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 22 Mar 2022 18:08:08 +0100 Subject: Fix minor issues in v3.5.0rc1 changelog (#17852) --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 519c561a6..52a62a213 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file. ## Unreleased ### Added -- **Add support for post editing** ([Gargron](https://github.com/mastodon/mastodon/pull/16697), [Gargron](https://github.com/mastodon/mastodon/pull/17727), [Gargron](https://github.com/mastodon/mastodon/pull/17728), [Gargron](https://github.com/mastodon/mastodon/pull/17320), [Gargron](https://github.com/mastodon/mastodon/pull/17404), [Gargron](https://github.com/mastodon/mastodon/pull/17390), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17335), [Gargron](https://github.com/mastodon/mastodon/pull/17696), [Gargron](https://github.com/mastodon/mastodon/pull/17745), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17740), [Gargron](https://github.com/mastodon/mastodon/pull/17697), [Gargron](https://github.com/mastodon/mastodon/pull/17648), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17531), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17499), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17498), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17380), [Gargron](https://github.com/mastodon/mastodon/pull/17373), [Gargron](https://github.com/mastodon/mastodon/pull/17334), [Gargron](https://github.com/mastodon/mastodon/pull/17333), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17699), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17748)) +- **Add support for incoming edited posts** ([Gargron](https://github.com/mastodon/mastodon/pull/16697), [Gargron](https://github.com/mastodon/mastodon/pull/17727), [Gargron](https://github.com/mastodon/mastodon/pull/17728), [Gargron](https://github.com/mastodon/mastodon/pull/17320), [Gargron](https://github.com/mastodon/mastodon/pull/17404), [Gargron](https://github.com/mastodon/mastodon/pull/17390), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17335), [Gargron](https://github.com/mastodon/mastodon/pull/17696), [Gargron](https://github.com/mastodon/mastodon/pull/17745), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17740), [Gargron](https://github.com/mastodon/mastodon/pull/17697), [Gargron](https://github.com/mastodon/mastodon/pull/17648), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17531), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17499), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17498), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17380), [Gargron](https://github.com/mastodon/mastodon/pull/17373), [Gargron](https://github.com/mastodon/mastodon/pull/17334), [Gargron](https://github.com/mastodon/mastodon/pull/17333), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17699), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17748)) - Previous versions remain available for perusal and comparison - People who reblogged a post are notified when it's edited - New REST APIs: @@ -14,7 +14,7 @@ All notable changes to this project will be documented in this file. - `GET /api/v1/statuses/:id/history` - `GET /api/v1/statuses/:id/source` - New streaming API event: - - `update` + - `status.update` - **Add appeals for moderator decisions** ([Gargron](https://github.com/mastodon/mastodon/pull/17364), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17725), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17566), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17652), [Gargron](https://github.com/mastodon/mastodon/pull/17616), [Gargron](https://github.com/mastodon/mastodon/pull/17615), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17554), [Gargron](https://github.com/mastodon/mastodon/pull/17523)) - All default moderator decisions now notify the affected user by e-mail - They now link to an appeal page instead of suggesting replying to the e-mail @@ -63,7 +63,7 @@ All notable changes to this project will be documented in this file. - Add `types` param to `GET /api/v1/notifications` in REST API ([Gargron](https://github.com/mastodon/mastodon/pull/17767)) - **Add notifications for moderators about new sign-ups** ([Gargron](https://github.com/mastodon/mastodon/pull/16953), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17629)) - When a new user confirms e-mail, moderators receive a notification - - New streaming API event: + - New notification type: - `admin.sign_up` - Add authentication history ([Gargron](https://github.com/mastodon/mastodon/pull/16408), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/16428), [baby-gnu](https://github.com/mastodon/mastodon/pull/16654)) - Add ability to automatically delete old posts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/16529), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17691), [tribela](https://github.com/mastodon/mastodon/pull/16653)) -- cgit From 2de44d3e47404ee0ac6f701e685a4626502c6390 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Mar 2022 18:20:08 +0100 Subject: Fix regression of status colors in actions modal in web UI (#17851) Regression in #17844 --- app/javascript/styles/mastodon/components.scss | 37 ++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index d1b36d33b..d627d9557 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -1154,6 +1154,43 @@ .audio-player { margin-top: 8px; } + + &.light { + .status__relative-time, + .status__visibility-icon { + color: $light-text-color; + } + + .status__display-name { + color: $inverted-text-color; + } + + .display-name { + color: $light-text-color; + + strong { + color: $inverted-text-color; + } + } + + .status__content { + color: $inverted-text-color; + + a { + color: $highlight-text-color; + } + + a.status__content__spoiler-link { + color: $primary-text-color; + background: $ui-primary-color; + + &:hover, + &:focus { + background: lighten($ui-primary-color, 8%); + } + } + } + } } .detailed-status__meta { -- cgit From 8751c3c4954799aec24cecc1cae68df27d19ceee Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Mar 2022 18:20:25 +0100 Subject: Fix crash when search fails in web UI (#17853) --- app/javascript/mastodon/features/explore/results.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/javascript/mastodon/features/explore/results.js b/app/javascript/mastodon/features/explore/results.js index ff900de08..339f883c5 100644 --- a/app/javascript/mastodon/features/explore/results.js +++ b/app/javascript/mastodon/features/explore/results.js @@ -24,15 +24,15 @@ const appendLoadMore = (id, list, onLoadMore) => { } }; -const renderAccounts = (results, onLoadMore) => appendLoadMore('accounts', results.get('accounts').map(item => ( +const renderAccounts = (results, onLoadMore) => appendLoadMore('accounts', results.get('accounts', ImmutableList()).map(item => ( )), onLoadMore); -const renderHashtags = (results, onLoadMore) => appendLoadMore('hashtags', results.get('hashtags').map(item => ( +const renderHashtags = (results, onLoadMore) => appendLoadMore('hashtags', results.get('hashtags', ImmutableList()).map(item => ( )), onLoadMore); -const renderStatuses = (results, onLoadMore) => appendLoadMore('statuses', results.get('statuses').map(item => ( +const renderStatuses = (results, onLoadMore) => appendLoadMore('statuses', results.get('statuses', ImmutableList()).map(item => ( )), onLoadMore); -- cgit From 749fe73ec4500d78b3deb8cdd260ff6eb6c66e7c Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 22 Mar 2022 18:41:46 +0100 Subject: Add tooltip for instance delivery warnings (#17854) --- app/views/admin/instances/_instance.html.haml | 2 +- config/locales/en.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/admin/instances/_instance.html.haml b/app/views/admin/instances/_instance.html.haml index 8a4396002..93f9bd418 100644 --- a/app/views/admin/instances/_instance.html.haml +++ b/app/views/admin/instances/_instance.html.haml @@ -1,7 +1,7 @@ .directory__tag = link_to admin_instance_path(instance) do %h4 - = fa_icon 'warning fw' if instance.failing? + = fa_icon 'warning fw', title: t('admin.instances.availability.warning') if instance.failing? = instance.domain %small diff --git a/config/locales/en.yml b/config/locales/en.yml index d4a42e867..a6ded38f7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -490,6 +490,7 @@ en: other: Failed attempts on %{count} different days. no_failures_recorded: No failures on record. title: Availability + warning: The last attempt to connect to this server has been unsuccessful back_to_all: All back_to_limited: Limited back_to_warning: Warning -- cgit From 6391a869aee853b01bdd9136b390e2f9b21857cb Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Mar 2022 06:08:05 +0100 Subject: [Glitch] Fix color of show more link in report dialog in web UI Port 69f9dc4f4eed9211a0a4ff55c18f64c99165a9e0 to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/styles/components/modal.scss | 9 +++++++++ app/javascript/flavours/glitch/styles/components/status.scss | 10 ++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/app/javascript/flavours/glitch/styles/components/modal.scss b/app/javascript/flavours/glitch/styles/components/modal.scss index 7e6918356..61c292b19 100644 --- a/app/javascript/flavours/glitch/styles/components/modal.scss +++ b/app/javascript/flavours/glitch/styles/components/modal.scss @@ -609,6 +609,15 @@ color: $inverted-text-color; } + .status__content__spoiler-link { + color: $primary-text-color; + background: $ui-primary-color; + + &:hover { + background: lighten($ui-primary-color, 8%); + } + } + .dialog-option .poll__input { border-color: $inverted-text-color; color: $ui-secondary-color; diff --git a/app/javascript/flavours/glitch/styles/components/status.scss b/app/javascript/flavours/glitch/styles/components/status.scss index ad6c24ea6..0d7dfd64d 100644 --- a/app/javascript/flavours/glitch/styles/components/status.scss +++ b/app/javascript/flavours/glitch/styles/components/status.scss @@ -198,7 +198,8 @@ .status__content__spoiler-link { background: lighten($ui-base-color, 30%); - &:hover { + &:hover, + &:focus { background: lighten($ui-base-color, 33%); text-decoration: none; } @@ -222,13 +223,13 @@ background: lighten($ui-base-color, 30%); border: 0; color: $inverted-text-color; - font-weight: 500; + font-weight: 700; font-size: 11px; padding: 0 5px; text-transform: uppercase; line-height: inherit; cursor: pointer; - vertical-align: bottom; + vertical-align: top; &:hover { background: lighten($ui-base-color, 33%); @@ -760,7 +761,8 @@ a.status__display-name, background: $ui-base-lighter-color; color: $inverted-text-color; - &:hover { + &:hover, + &:focus { background: lighten($ui-base-color, 29%); text-decoration: none; } -- cgit From 2287eebae0c1d699436a8cf3218d7cfe990a3605 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 24 Mar 2022 09:15:25 +0100 Subject: Fix description of “Allow posts with Content Warnings to trend” setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/admin/settings/edit.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/settings/edit.html.haml b/app/views/admin/settings/edit.html.haml index a287e52ff..a47cb2a88 100644 --- a/app/views/admin/settings/edit.html.haml +++ b/app/views/admin/settings/edit.html.haml @@ -87,7 +87,7 @@ = f.input :trendable_by_default, as: :boolean, wrapper: :with_label, label: t('admin.settings.trendable_by_default.title'), hint: t('admin.settings.trendable_by_default.desc_html') .fields-group - = f.input :trending_status_cw, as: :boolean, wrapper: :with_label, label: t('admin.settings.trending_status_cw.title'), hint: t('trending_status_cw.desc_html') + = f.input :trending_status_cw, as: :boolean, wrapper: :with_label, label: t('admin.settings.trending_status_cw.title'), hint: t('admin.settings.trending_status_cw.desc_html') .fields-group = f.input :noindex, as: :boolean, wrapper: :with_label, label: t('admin.settings.default_noindex.title'), hint: t('admin.settings.default_noindex.desc_html') -- cgit From 9565b17d5d743d7ae4028d484b407d649210f6d2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 24 Mar 2022 11:23:46 +0100 Subject: New Crowdin updates (#17829) * New translations en.json (Kurmanji (Kurdish)) * New translations doorkeeper.en.yml (Kurmanji (Kurdish)) * New translations en.yml (Kurmanji (Kurdish)) * New translations en.yml (Kurmanji (Kurdish)) * New translations simple_form.en.yml (Kurmanji (Kurdish)) * New translations en.yml (Thai) * New translations en.yml (Thai) * New translations en.yml (Thai) * New translations en.yml (Thai) * New translations en.json (Japanese) * New translations en.json (Japanese) * New translations doorkeeper.en.yml (Indonesian) * New translations en.json (Persian) * New translations en.json (Persian) * New translations en.json (Persian) * New translations en.json (Persian) * New translations en.json (Persian) * New translations en.json (Persian) * New translations en.json (Persian) * New translations en.json (Persian) * New translations en.json (Persian) * New translations en.json (Persian) * New translations en.json (Persian) * New translations en.json (Persian) * New translations en.json (Persian) * New translations en.yml (Thai) * New translations en.yml (Thai) * New translations en.yml (Korean) * New translations en.yml (Portuguese) * New translations en.yml (Hungarian) * New translations en.yml (Armenian) * New translations en.yml (Georgian) * New translations en.yml (Lithuanian) * New translations en.yml (Macedonian) * New translations en.yml (Dutch) * New translations en.yml (Norwegian) * New translations en.yml (Punjabi) * New translations en.yml (Polish) * New translations en.yml (Albanian) * New translations en.yml (Basque) * New translations en.yml (Serbian (Cyrillic)) * New translations en.yml (Turkish) * New translations en.yml (Ukrainian) * New translations en.yml (Chinese Traditional) * New translations en.yml (Urdu (Pakistan)) * New translations en.yml (Icelandic) * New translations en.yml (Portuguese, Brazilian) * New translations en.yml (Indonesian) * New translations en.yml (Tamil) * New translations en.yml (Spanish, Argentina) * New translations en.yml (Finnish) * New translations en.yml (Greek) * New translations en.yml (Galician) * New translations en.yml (Slovak) * New translations en.yml (Chinese Simplified) * New translations en.yml (Swedish) * New translations en.yml (Arabic) * New translations en.yml (French) * New translations en.yml (Spanish) * New translations en.yml (Catalan) * New translations en.yml (Hebrew) * New translations en.yml (Italian) * New translations en.yml (Japanese) * New translations en.yml (Russian) * New translations en.yml (Slovenian) * New translations en.yml (German) * New translations en.yml (Vietnamese) * New translations en.yml (Persian) * New translations en.yml (Romanian) * New translations en.yml (Afrikaans) * New translations en.yml (Bulgarian) * New translations en.yml (Czech) * New translations en.yml (Danish) * New translations en.yml (Spanish, Mexico) * New translations en.yml (Scottish Gaelic) * New translations en.yml (Occitan) * New translations en.yml (Bengali) * New translations en.yml (Marathi) * New translations en.yml (Silesian) * New translations en.yml (Taigi) * New translations en.yml (Ido) * New translations en.yml (Kabyle) * New translations en.yml (Sanskrit) * New translations en.yml (Sardinian) * New translations en.yml (Corsican) * New translations en.yml (Sorani (Kurdish)) * New translations en.yml (Serbian (Latin)) * New translations en.yml (Asturian) * New translations en.yml (Kannada) * New translations en.yml (Cornish) * New translations en.yml (Sinhala) * New translations en.yml (Breton) * New translations en.yml (Malayalam) * New translations en.yml (Tatar) * New translations en.yml (Chinese Traditional, Hong Kong) * New translations en.yml (Uyghur) * New translations en.yml (Esperanto) * New translations en.yml (Welsh) * New translations en.yml (Telugu) * New translations en.yml (Malay) * New translations en.yml (Hindi) * New translations en.yml (Latvian) * New translations en.yml (Estonian) * New translations en.yml (Kazakh) * New translations en.yml (Norwegian Nynorsk) * New translations en.yml (Croatian) * New translations en.yml (Standard Moroccan Tamazight) * New translations en.yml (Catalan) * New translations en.yml (Chinese Traditional) * New translations en.yml (Latvian) * New translations en.yml (Icelandic) * New translations en.yml (Swedish) * New translations en.yml (Thai) * New translations en.yml (Portuguese) * New translations en.yml (Thai) * New translations en.yml (Russian) * New translations en.yml (Russian) * New translations en.yml (Thai) * New translations en.yml (Danish) * New translations en.yml (Spanish) * New translations en.yml (Spanish, Argentina) * New translations en.json (Japanese) * New translations en.yml (German) * New translations en.yml (Hungarian) * New translations en.yml (Italian) * New translations en.yml (Kurmanji (Kurdish)) * New translations en.yml (Chinese Simplified) * New translations en.yml (Indonesian) * New translations en.yml (Turkish) * New translations en.json (Persian) * New translations simple_form.en.yml (Persian) * New translations en.yml (Thai) * New translations simple_form.en.yml (Thai) * New translations simple_form.en.yml (Persian) * New translations simple_form.en.yml (Persian) * New translations en.yml (Thai) * New translations en.json (Dutch) * New translations en.json (Dutch) * New translations en.yml (Dutch) * New translations en.json (Dutch) * New translations en.yml (Dutch) * New translations en.json (Dutch) * New translations simple_form.en.yml (Dutch) * New translations en.json (Dutch) * New translations en.json (Dutch) * New translations en.json (Dutch) * New translations doorkeeper.en.yml (Dutch) * New translations doorkeeper.en.yml (Dutch) * New translations en.json (Dutch) * New translations doorkeeper.en.yml (Dutch) * New translations en.json (Dutch) * New translations en.json (Dutch) * New translations en.yml (Dutch) * New translations en.json (Dutch) * New translations en.yml (Dutch) * New translations simple_form.en.yml (Dutch) * New translations simple_form.en.yml (Dutch) * New translations doorkeeper.en.yml (Dutch) * New translations activerecord.en.yml (Dutch) * New translations en.yml (Dutch) * New translations doorkeeper.en.yml (Dutch) * New translations en.yml (Korean) * New translations en.yml (Galician) * Run `bundle exec i18n-tasks normalize` * Run `yarn manage:translations` Co-authored-by: Yamagishi Kazutoshi --- app/javascript/mastodon/locales/fa.json | 142 ++++++++++----------- app/javascript/mastodon/locales/ja.json | 2 +- app/javascript/mastodon/locales/ku.json | 4 +- app/javascript/mastodon/locales/nl.json | 212 ++++++++++++++++---------------- config/locales/activerecord.nl.yml | 2 +- config/locales/ca.yml | 1 + config/locales/da.yml | 1 + config/locales/de.yml | 3 + config/locales/doorkeeper.id.yml | 33 +++++ config/locales/doorkeeper.ku.yml | 4 +- config/locales/doorkeeper.nl.yml | 46 ++++++- config/locales/es-AR.yml | 1 + config/locales/es.yml | 1 + config/locales/gl.yml | 1 + config/locales/hu.yml | 1 + config/locales/id.yml | 1 + config/locales/is.yml | 1 + config/locales/it.yml | 1 + config/locales/ko.yml | 1 + config/locales/ku.yml | 11 +- config/locales/lv.yml | 1 + config/locales/nl.yml | 96 +++++++-------- config/locales/pt-PT.yml | 1 + config/locales/ru.yml | 4 + config/locales/simple_form.fa.yml | 9 ++ config/locales/simple_form.ku.yml | 2 +- config/locales/simple_form.nl.yml | 48 ++++---- config/locales/simple_form.th.yml | 2 +- config/locales/sv.yml | 2 + config/locales/th.yml | 13 ++ config/locales/tr.yml | 1 + config/locales/zh-CN.yml | 1 + config/locales/zh-TW.yml | 1 + 33 files changed, 383 insertions(+), 267 deletions(-) diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index 820b90640..d5276039d 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -3,16 +3,16 @@ "account.add_or_remove_from_list": "افزودن یا برداشتن از سیاهه‌ها", "account.badges.bot": "روبات", "account.badges.group": "گروه", - "account.block": "مسدود کردن @{name}", + "account.block": "مسدود کردن ‎@{name}", "account.block_domain": "مسدود کردن دامنهٔ {domain}", "account.blocked": "مسدود", "account.browse_more_on_origin_server": "مرور بیش‌تر روی نمایهٔ اصلی", "account.cancel_follow_request": "لغو درخواست پی‌گیری", - "account.direct": "پیام مستقیم به @{name}", - "account.disable_notifications": "آگاهی به من هنگام فرستادن‌های @{name} پایان یابد", + "account.direct": "پیام مستقیم به ‎@{name}", + "account.disable_notifications": "آگاهی به من هنگام فرستادن‌های ‎@{name} پایان یابد", "account.domain_blocked": "دامنه مسدود شد", "account.edit_profile": "ویرایش نمایه", - "account.enable_notifications": "هنگام فرسته‌های @{name} مرا آگاه کن", + "account.enable_notifications": "هنگام فرسته‌های ‎@{name} مرا آگاه کن", "account.endorse": "معرّفی در نمایه", "account.follow": "پی‌گیری", "account.followers": "پی‌گیرندگان", @@ -22,34 +22,34 @@ "account.following_counter": "{count, plural, one {{counter} پی‌گرفته} other {{counter} پی‌گرفته}}", "account.follows.empty": "این کاربر هنوز پی‌گیر کسی نیست.", "account.follows_you": "پی می‌گیردتان", - "account.hide_reblogs": "نهفتن تقویت‌های @{name}", + "account.hide_reblogs": "نهفتن تقویت‌های ‎@{name}", "account.joined": "پیوسته از {date}", "account.link_verified_on": "مالکیت این پیوند در {date} بررسی شد", "account.locked_info": "این حساب خصوصی است. صاحبش تصمیم می‌گیرد که چه کسی پی‌گیرش باشد.", "account.media": "رسانه", - "account.mention": "نام‌بردن از @{name}", + "account.mention": "نام‌بردن از ‎@{name}", "account.moved_to": "{name} منتقل شده به:", - "account.mute": "خموشاندن @{name}", - "account.mute_notifications": "خموشاندن آگاهی‌ها از @{name}", + "account.mute": "خموشاندن ‎@{name}", + "account.mute_notifications": "خموشاندن آگاهی‌های ‎@{name}", "account.muted": "خموش", "account.posts": "فرسته", "account.posts_with_replies": "فرسته‌ها و پاسخ‌ها", - "account.report": "گزارش @{name}", + "account.report": "گزارش ‎@{name}", "account.requested": "منتظر پذیرش است. برای لغو درخواست پی‌گیری کلیک کنید", - "account.share": "هم‌رسانی نمایهٔ @{name}", - "account.show_reblogs": "نمایش تقویت‌های @{name}", + "account.share": "هم‌رسانی نمایهٔ ‎@{name}", + "account.show_reblogs": "نمایش تقویت‌های ‎@{name}", "account.statuses_counter": "{count, plural, one {{counter} فرسته} other {{counter} فرسته}}", - "account.unblock": "رفع مسدودیت @{name}", + "account.unblock": "رفع مسدودیت ‎@{name}", "account.unblock_domain": "رفع مسدودیت دامنهٔ {domain}", "account.unblock_short": "رفع مسدودیت", "account.unendorse": "معرّفی نکردن در نمایه", "account.unfollow": "ناپی‌گیری", - "account.unmute": "ناخموشی @{name}", - "account.unmute_notifications": "ناخموشی آگاهی‌ها از @{name}", + "account.unmute": "ناخموشی ‎@{name}", + "account.unmute_notifications": "ناخموشی آگاهی‌های ‎@{name}", "account.unmute_short": "ناخموشی", "account_note.placeholder": "برای افزودن یادداشت کلیک کنید", - "admin.dashboard.daily_retention": "User retention rate by day after sign-up", - "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.daily_retention": "نرخ حفظ کاربر در روز پس از ثبت نام", + "admin.dashboard.monthly_retention": "نرخ حفظ کاربر در ماه پس از ثبت نام", "admin.dashboard.retention.average": "میانگین", "admin.dashboard.retention.cohort": "ماه ثبت‌نام", "admin.dashboard.retention.cohort_size": "کاربران جدید", @@ -79,13 +79,13 @@ "column.lists": "سیاهه‌ها", "column.mutes": "کاربران خموش", "column.notifications": "آگاهی‌ها", - "column.pins": "فرسته‌های سنجاق‌شده", + "column.pins": "فرسته‌های سنجاق شده", "column.public": "خط زمانی همگانی", "column_back_button.label": "بازگشت", "column_header.hide_settings": "نهفتن تنظیمات", "column_header.moveLeft_settings": "جابه‌جایی ستون به چپ", "column_header.moveRight_settings": "جابه‌جایی ستون به راست", - "column_header.pin": "سنجاق‌کردن", + "column_header.pin": "سنجاق کردن", "column_header.show_settings": "نمایش تنظیمات", "column_header.unpin": "برداشتن سنجاق", "column_subheading.settings": "تنظیمات", @@ -94,7 +94,7 @@ "community.column_settings.remote_only": "تنها دوردست", "compose_form.direct_message_warning": "این فرسته تنها به کاربرانی که از آن‌ها نام برده شده فرستاده خواهد شد.", "compose_form.direct_message_warning_learn_more": "بیشتر بدانید", - "compose_form.hashtag_warning": "از آن‌جا که این فرسته فهرست‌نشده است، در نتایج جست‌وجوی برچسب‌ها پیدا نخواهد شد. تنها فرسته‌های عمومی را می‌توان با جست‌وجوی برچسب یافت.", + "compose_form.hashtag_warning": "از آن‌جا که این فرسته فهرست نشده است، در نتایج جست‌وجوی هشتگ‌ها پیدا نخواهد شد. تنها فرسته‌های عمومی را می‌توان با جست‌وجوی هشتگ یافت.", "compose_form.lock_disclaimer": "حسابتان {locked} نیست. هر کسی می‌تواند پی‌گیرتان شده و فرسته‌های ویژهٔ پی‌گیرانتان را ببیند.", "compose_form.lock_disclaimer.lock": "قفل‌شده", "compose_form.placeholder": "تازه چه خبر؟", @@ -144,7 +144,7 @@ "directory.local": "تنها از {domain}", "directory.new_arrivals": "تازه‌واردان", "directory.recently_active": "کاربران فعال اخیر", - "embed.instructions": "برای جاگذاری این فرسته در سایت خودتان، کد زیر را کپی کنید.", + "embed.instructions": "برای جاسازی این فرسته در سایت خودتان، کد زیر را رونوشت کنید.", "embed.preview": "این گونه دیده خواهد شد:", "emoji_button.activity": "فعالیت", "emoji_button.custom": "سفارشی", @@ -164,11 +164,11 @@ "empty_column.account_timeline": "هیچ فرسته‌ای این‌جا نیست!", "empty_column.account_unavailable": "نمایهٔ موجود نیست", "empty_column.blocks": "هنوز کسی را مسدود نکرده‌اید.", - "empty_column.bookmarked_statuses": "هنوز هیچ فرستهٔ نشان‌شده‌ای ندارید. هنگامی که فرسته‌ای را نشان‌کنید، این‌جا نشان داده خواهد شد.", + "empty_column.bookmarked_statuses": "هنوز هیچ فرستهٔ نشانه‌گذاری شده‌ای ندارید. هنگامی که فرسته‌ای را نشانه‌گذاری کنید، این‌جا نشان داده خواهد شد.", "empty_column.community": "خط زمانی محلّی خالی است. چیزی بنویسید تا چرخش بچرخد!", "empty_column.direct": "هنوز هیچ پیام مستقیمی ندارید. هنگامی که چنین پیامی بگیرید یا بفرستید این‌جا نشان داده خواهد شد.", "empty_column.domain_blocks": "هنوز هیچ دامنه‌ای مسدود نشده است.", - "empty_column.explore_statuses": "Nothing is trending right now. Check back later!", + "empty_column.explore_statuses": "الآن چیزی پرطرفدار نیست. بعداً دوباره بررسی کنید!", "empty_column.favourited_statuses": "شما هنوز هیچ فرسته‌ای را نپسندیده‌اید. هنگامی که فرسته‌ای را بپسندید، این‌جا نشان داده خواهد شد.", "empty_column.favourites": "هنوز هیچ کسی این فرسته را نپسندیده است. هنگامی که کسی آن را بپسندد، این‌جا نشان داده خواهد شد.", "empty_column.follow_recommendations": "ظاهرا هیچ پیشنهادی برای شما نمی‌توانیم تولید کنیم. می‌توانید از امکان جست‌وجو برای یافتن افرادی که ممکن است بشناسید و یا کاوش میان برچسب‌های داغ استفاده کنید.", @@ -247,7 +247,7 @@ "keyboard_shortcuts.my_profile": "گشودن نمایه‌تان", "keyboard_shortcuts.notifications": "گشودن ستون آگاهی‌ها", "keyboard_shortcuts.open_media": "گشودن رسانه", - "keyboard_shortcuts.pinned": "گشودن سیاههٔ فرسته‌های سنجاق شده", + "keyboard_shortcuts.pinned": "گشودن فهرست فرسته‌های سنجاق شده", "keyboard_shortcuts.profile": "گشودن نمایهٔ نویسنده", "keyboard_shortcuts.reply": "پاسخ به فرسته", "keyboard_shortcuts.requests": "گشودن سیاههٔ درخواست‌های پی‌گیری", @@ -305,7 +305,7 @@ "navigation_bar.logout": "خروج", "navigation_bar.mutes": "کاربران خموشانده", "navigation_bar.personal": "شخصی", - "navigation_bar.pins": "فرسته‌های سنجاق‌شده", + "navigation_bar.pins": "فرسته‌های سنجاق شده", "navigation_bar.preferences": "ترجیحات", "navigation_bar.public_timeline": "خط زمانی همگانی", "navigation_bar.security": "امنیت", @@ -392,40 +392,40 @@ "report.block": "مسدود کردن", "report.block_explanation": "شما فرسته‌هایشان را نخواهید دید. آن‌ها نمی‌توانند فرسته‌هایتان را ببینند یا شما را پی‌بگیرند. آنها می‌توانند بگویند که مسدود شده‌اند.", "report.categories.other": "غیره", - "report.categories.spam": "Spam", - "report.categories.violation": "Content violates one or more server rules", - "report.category.subtitle": "Choose the best match", - "report.category.title": "Tell us what's going on with this {type}", - "report.category.title_account": "profile", - "report.category.title_status": "post", - "report.close": "Done", - "report.comment.title": "Is there anything else you think we should know?", + "report.categories.spam": "هرزنامه", + "report.categories.violation": "محتوا یک یا چند قانون کارساز را نقض می‌کند", + "report.category.subtitle": "منطبق‌ترین را انتخاب کنید", + "report.category.title": "به ما بگویید با این {type} چه مشکلی دارید", + "report.category.title_account": "نمایه", + "report.category.title_status": "فرسته", + "report.close": "انجام شد", + "report.comment.title": "آیا چیز دیگری هست که فکر می‌کنید باید بدانیم؟", "report.forward": "فرستادن به {target}", "report.forward_hint": "این حساب در کارساز دیگری ثبت شده. آیا می‌خواهید رونوشتی ناشناس از این گزارش به آن‌جا هم فرستاده شود؟", - "report.mute": "Mute", - "report.mute_explanation": "You will not see their posts. They can still follow you and see your posts and will not know that they are muted.", - "report.next": "Next", + "report.mute": "خموش", + "report.mute_explanation": "شما فرسته‌های آن‌ها را نخواهید دید. آن‌ها همچنان می‌توانند شما را پی‌بگیرند و فرسته‌هایتان را ببینند و نمی‌دانند که خموش شده‌اند.", + "report.next": "بعدی", "report.placeholder": "توضیحات اضافه", - "report.reasons.dislike": "I don't like it", - "report.reasons.dislike_description": "It is not something you want to see", - "report.reasons.other": "It's something else", - "report.reasons.other_description": "The issue does not fit into other categories", - "report.reasons.spam": "It's spam", - "report.reasons.spam_description": "Malicious links, fake engagement, or repetitive replies", - "report.reasons.violation": "It violates server rules", - "report.reasons.violation_description": "You are aware that it breaks specific rules", - "report.rules.subtitle": "Select all that apply", - "report.rules.title": "Which rules are being violated?", - "report.statuses.subtitle": "Select all that apply", - "report.statuses.title": "Are there any posts that back up this report?", + "report.reasons.dislike": "من آن را دوست ندارم", + "report.reasons.dislike_description": "این چیزی نیست که بخواهید ببینید", + "report.reasons.other": "بخواطر چیز دیگری است", + "report.reasons.other_description": "این موضوع در دسته‌بندی‌های دیگر نمی‌گنجد", + "report.reasons.spam": "این هرزنامه است", + "report.reasons.spam_description": "پیوندهای مخرب، تعامل جعلی یا پاسخ‌های تکراری", + "report.reasons.violation": "قوانین کارساز را نقض می‌کند", + "report.reasons.violation_description": "شما آگاه هستید که قوانین خاصی را زیر پا می‌گذارد", + "report.rules.subtitle": "همهٔ موارد انجام شده را برگزینید", + "report.rules.title": "کدام قوانین نقض شده‌اند؟", + "report.statuses.subtitle": "همهٔ موارد انجام شده را برگزینید", + "report.statuses.title": "آیا فرسته‌ای وجود دارد که از این گزارش پشتیبانی کند؟", "report.submit": "فرستادن", "report.target": "در حال گزارش {target}", - "report.thanks.take_action": "Here are your options for controlling what you see on Mastodon:", - "report.thanks.take_action_actionable": "While we review this, you can take action against @{name}:", - "report.thanks.title": "Don't want to see this?", - "report.thanks.title_actionable": "Thanks for reporting, we'll look into this.", - "report.unfollow": "Unfollow @{name}", - "report.unfollow_explanation": "You are following this account. To not see their posts in your home feed anymore, unfollow them.", + "report.thanks.take_action": "در اینجا گزینه‌هایی برای کنترل آنچه در ماستودون میبینید، وجود دارد:", + "report.thanks.take_action_actionable": "در حالی که ما این مورد را بررسی می‌کنیم، می‌توانید علیه ‎@{name} اقدام کنید:", + "report.thanks.title": "نمی‌خواهید این را ببینید؟", + "report.thanks.title_actionable": "ممنون بابت گزارش، ما آن را بررسی خواهیم کرد.", + "report.unfollow": "ناپی‌گیری ‎@{name}", + "report.unfollow_explanation": "شما این حساب را پی‌گرفته‌اید، برای اینکه دیگر فرسته‌هایش را در خوراک خانه‌تان نبینید؛ آن را پی‌نگیرید.", "search.placeholder": "جست‌وجو", "search_popout.search_format": "راهنمای جست‌وجوی پیشرفته", "search_popout.tips.full_text": "جست‌وجوی متنی ساده فرسته‌هایی که نوشته، پسندیده، تقویت‌کرده یا در آن‌ها نام‌برده شده‌اید را به علاوهٔ نام‌های کاربری، نام‌های نمایشی و برچسب‌ها برمی‌گرداند.", @@ -434,39 +434,39 @@ "search_popout.tips.text": "جست‌وجوی متنی ساده برای نام‌ها، نام‌های کاربری، و برچسب‌ها", "search_popout.tips.user": "کاربر", "search_results.accounts": "افراد", - "search_results.all": "All", + "search_results.all": "همه", "search_results.hashtags": "برچسب‌ها", - "search_results.nothing_found": "Could not find anything for these search terms", + "search_results.nothing_found": "چیزی برای این عبارت جست‌وجو یافت نشد", "search_results.statuses": "فرسته‌ها", - "search_results.statuses_fts_disabled": "جست‌وجوی محتوای فرسته‌ها در این کارساز ماستودون فعال نشده است.", + "search_results.statuses_fts_disabled": "جست‌وجوی محتوای فرسته‌ها در این کارساز ماستودون به کار انداخته نشده است.", "search_results.total": "{count, number} {count, plural, one {نتیجه} other {نتیجه}}", - "status.admin_account": "گشودن واسط مدیریت برای @{name}", + "status.admin_account": "گشودن واسط مدیریت برای ‎@{name}", "status.admin_status": "گشودن این فرسته در واسط مدیریت", - "status.block": "مسدود کردن @{name}", + "status.block": "مسدود کردن ‎@{name}", "status.bookmark": "نشانک", "status.cancel_reblog_private": "لغو تقویت", "status.cannot_reblog": "این فرسته قابل تقویت نیست", - "status.copy": "رونویسی از نشانی فرسته", + "status.copy": "رونوشت پیوند فرسته", "status.delete": "حذف", "status.detailed_status": "نمایش کامل گفتگو", - "status.direct": "پیام مستقیم به @{name}", - "status.edit": "Edit", - "status.edited": "Edited {date}", - "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", - "status.embed": "جاگذاری", + "status.direct": "پیام مستقیم به ‎@{name}", + "status.edit": "ویرایش", + "status.edited": "ویرایش شده در {date}", + "status.edited_x_times": "{count, plural, one {{count} مرتبه} other {{count} مرتبه}} ویرایش شد", + "status.embed": "جاسازی", "status.favourite": "پسندیدن", "status.filtered": "پالوده", - "status.history.created": "{name} created {date}", - "status.history.edited": "{name} edited {date}", + "status.history.created": "توسط {name} در {date} ایجاد شد", + "status.history.edited": "توسط {name} در {date} ویرایش شد", "status.load_more": "بار کردن بیش‌تر", "status.media_hidden": "رسانهٔ نهفته", - "status.mention": "نام‌بردن از @{name}", + "status.mention": "نام‌بردن از ‎@{name}", "status.more": "بیشتر", - "status.mute": "خموشاندن @{name}", + "status.mute": "خموشاندن ‎@{name}", "status.mute_conversation": "خموشاندن گفت‌وگو", "status.open": "گسترش این فرسته", - "status.pin": "سنجاق‌کردن در نمایه", - "status.pinned": "فرستهٔ سنجاق‌شده", + "status.pin": "سنجاق کردن در نمایه", + "status.pinned": "فرستهٔ سنجاق شده", "status.read_more": "بیشتر بخوانید", "status.reblog": "تقویت", "status.reblog_private": "تقویت برای مخاطبان نخستین", @@ -476,7 +476,7 @@ "status.remove_bookmark": "برداشتن نشانک", "status.reply": "پاسخ", "status.replyAll": "پاسخ به رشته", - "status.report": "گزارش @{name}", + "status.report": "گزارش ‎@{name}", "status.sensitive_warning": "محتوای حساس", "status.share": "هم‌رسانی", "status.show_less": "نمایش کمتر", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index 8c7878a84..b5257e80d 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -188,7 +188,7 @@ "errors.unexpected_crash.copy_stacktrace": "スタックトレースをクリップボードにコピー", "errors.unexpected_crash.report_issue": "問題を報告", "explore.search_results": "検索結果", - "explore.suggested_follows": "あなたに", + "explore.suggested_follows": "おすすめ", "explore.title": "エクスプローラー", "explore.trending_links": "ニュース", "explore.trending_statuses": "投稿", diff --git a/app/javascript/mastodon/locales/ku.json b/app/javascript/mastodon/locales/ku.json index 0298c51ec..2bf8fc520 100644 --- a/app/javascript/mastodon/locales/ku.json +++ b/app/javascript/mastodon/locales/ku.json @@ -342,7 +342,7 @@ "notifications.filter.all": "Hemû", "notifications.filter.boosts": "Bilindkirî", "notifications.filter.favourites": "Bijarte", - "notifications.filter.follows": "Şopîner", + "notifications.filter.follows": "Dişopîne", "notifications.filter.mentions": "Qalkirin", "notifications.filter.polls": "Encamên rapirsiyê", "notifications.filter.statuses": "Ji kesên tu dişopînî re rojanekirin", @@ -501,7 +501,7 @@ "time_remaining.seconds": "{number, plural, one {# çirke} other {# çirke}} maye", "timeline_hint.remote_resource_not_displayed": "{resource} Ji rajekerên din nayê dîtin.", "timeline_hint.resources.followers": "Şopîner", - "timeline_hint.resources.follows": "Şopîner", + "timeline_hint.resources.follows": "Dişopîne", "timeline_hint.resources.statuses": "Şandiyên kevn", "trends.counter_by_accounts": "{count, plural, one {{counter} kes} other {{counter} kes}} diaxivin", "trends.trending_now": "Rojev", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index f30755286..d1cfdd5f4 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -9,44 +9,44 @@ "account.browse_more_on_origin_server": "Meer op het originele profiel bekijken", "account.cancel_follow_request": "Volgverzoek annuleren", "account.direct": "@{name} een direct bericht sturen", - "account.disable_notifications": "Geef geen melding meer wanneer @{name} toot", + "account.disable_notifications": "Geef geen melding meer wanneer @{name} een bericht plaatst", "account.domain_blocked": "Domein geblokkeerd", "account.edit_profile": "Profiel bewerken", - "account.enable_notifications": "Geef een melding wanneer @{name} toot", + "account.enable_notifications": "Geef een melding wanneer @{name} een bericht plaatst", "account.endorse": "Op profiel weergeven", "account.follow": "Volgen", "account.followers": "Volgers", "account.followers.empty": "Niemand volgt nog deze gebruiker.", "account.followers_counter": "{count, plural, one {{counter} volger} other {{counter} volgers}}", - "account.following": "Following", + "account.following": "Volgend", "account.following_counter": "{count, plural, one {{counter} volgend} other {{counter} volgend}}", "account.follows.empty": "Deze gebruiker volgt nog niemand.", "account.follows_you": "Volgt jou", "account.hide_reblogs": "Boosts van @{name} verbergen", "account.joined": "Geregistreerd in {date}", "account.link_verified_on": "Eigendom van deze link is gecontroleerd op {date}", - "account.locked_info": "De privacystatus van dit account is op besloten gezet. De eigenaar bepaalt handmatig wie hen kan volgen.", + "account.locked_info": "De privacystatus van dit account is op besloten gezet. De eigenaar bepaalt handmatig wie diegene kan volgen.", "account.media": "Media", "account.mention": "@{name} vermelden", "account.moved_to": "{name} is verhuisd naar:", "account.mute": "@{name} negeren", "account.mute_notifications": "Meldingen van @{name} negeren", "account.muted": "Genegeerd", - "account.posts": "Toots", - "account.posts_with_replies": "Toots en reacties", + "account.posts": "Berichten", + "account.posts_with_replies": "Berichten en reacties", "account.report": "@{name} rapporteren", "account.requested": "Wacht op goedkeuring. Klik om het volgverzoek te annuleren", "account.share": "Profiel van @{name} delen", "account.show_reblogs": "Boosts van @{name} tonen", - "account.statuses_counter": "{count, plural, one {{counter} toot} other {{counter} toots}}", + "account.statuses_counter": "{count, plural, one {{counter} bericht} other {{counter} berichten}}", "account.unblock": "@{name} deblokkeren", "account.unblock_domain": "{domain} niet langer verbergen", - "account.unblock_short": "Unblock", + "account.unblock_short": "Deblokkeren", "account.unendorse": "Niet op profiel weergeven", "account.unfollow": "Ontvolgen", "account.unmute": "@{name} niet langer negeren", "account.unmute_notifications": "Meldingen van @{name} niet langer negeren", - "account.unmute_short": "Unmute", + "account.unmute_short": "Niet langer negeren", "account_note.placeholder": "Klik om een opmerking toe te voegen", "admin.dashboard.daily_retention": "User retention rate by day after sign-up", "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", @@ -79,7 +79,7 @@ "column.lists": "Lijsten", "column.mutes": "Genegeerde gebruikers", "column.notifications": "Meldingen", - "column.pins": "Vastgezette toots", + "column.pins": "Vastgezette berichten", "column.public": "Globale tijdlijn", "column_back_button.label": "Terug", "column_header.hide_settings": "Instellingen verbergen", @@ -92,10 +92,10 @@ "community.column_settings.local_only": "Alleen lokaal", "community.column_settings.media_only": "Alleen media", "community.column_settings.remote_only": "Alleen andere servers", - "compose_form.direct_message_warning": "Deze toot wordt alleen naar vermelde gebruikers verstuurd.", + "compose_form.direct_message_warning": "Dit bericht wordt alleen naar vermelde gebruikers verstuurd.", "compose_form.direct_message_warning_learn_more": "Meer leren", - "compose_form.hashtag_warning": "Deze toot valt niet onder een hashtag te bekijken, omdat deze niet op openbare tijdlijnen wordt getoond. Alleen openbare toots kunnen via hashtags gevonden worden.", - "compose_form.lock_disclaimer": "Jouw account is niet {locked}. Iedereen kan jou volgen en kan de toots zien die je alleen aan jouw volgers hebt gericht.", + "compose_form.hashtag_warning": "Dit bericht valt niet onder een hashtag te bekijken, omdat deze niet op openbare tijdlijnen wordt getoond. Alleen openbare berichten kunnen via hashtags gevonden worden.", + "compose_form.lock_disclaimer": "Jouw account is niet {locked}. Iedereen kan jou volgen en kan de berichten zien die je alleen aan jouw volgers hebt gericht.", "compose_form.lock_disclaimer.lock": "besloten", "compose_form.placeholder": "Wat wil je kwijt?", "compose_form.poll.add_option": "Keuze toevoegen", @@ -106,7 +106,7 @@ "compose_form.poll.switch_to_single": "Poll wijzigen om een enkele keuze toe te staan", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", - "compose_form.save_changes": "Save changes", + "compose_form.save_changes": "Wijzigingen opslaan", "compose_form.sensitive.hide": "{count, plural, one {Media als gevoelig markeren} other {Media als gevoelig markeren}}", "compose_form.sensitive.marked": "{count, plural, one {Media is als gevoelig gemarkeerd} other {Media is als gevoelig gemarkeerd}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is niet als gevoelig gemarkeerd} other {Media is niet als gevoelig gemarkeerd}}", @@ -118,22 +118,22 @@ "confirmations.block.confirm": "Blokkeren", "confirmations.block.message": "Weet je het zeker dat je {name} wilt blokkeren?", "confirmations.delete.confirm": "Verwijderen", - "confirmations.delete.message": "Weet je het zeker dat je deze toot wilt verwijderen?", + "confirmations.delete.message": "Weet je het zeker dat je dit bericht wilt verwijderen?", "confirmations.delete_list.confirm": "Verwijderen", "confirmations.delete_list.message": "Weet je zeker dat je deze lijst definitief wilt verwijderen?", "confirmations.discard_edit_media.confirm": "Weggooien", "confirmations.discard_edit_media.message": "Je hebt niet-opgeslagen wijzigingen in de mediabeschrijving of voorvertonning, wil je deze toch weggooien?", "confirmations.domain_block.confirm": "Verberg alles van deze server", - "confirmations.domain_block.message": "Weet je het echt heel erg zeker dat je alles van {domain} wilt negeren? In de meeste gevallen is het blokkeren of negeren van een paar specifieke personen voldoende en beter. Je zult geen toots van deze server op openbare tijdlijnen zien of in jouw meldingen. Jouw volgers van deze server worden verwijderd.", + "confirmations.domain_block.message": "Weet je het echt heel erg zeker dat je alles van {domain} wilt negeren? In de meeste gevallen is het blokkeren of negeren van een paar specifieke personen voldoende en beter. Je zult geen berichten van deze server op openbare tijdlijnen zien of in jouw meldingen. Jouw volgers van deze server worden verwijderd.", "confirmations.logout.confirm": "Uitloggen", "confirmations.logout.message": "Weet je zeker dat je wilt uitloggen?", "confirmations.mute.confirm": "Negeren", - "confirmations.mute.explanation": "Dit verbergt toots van hen en toots waar hen in wordt vermeld, maar hen kan nog steeds jouw toots bekijken en jou volgen.", + "confirmations.mute.explanation": "Dit verbergt diens berichten en berichten waar diegene in wordt vermeld, maar diegene kan nog steeds jouw berichten bekijken en jou volgen.", "confirmations.mute.message": "Weet je het zeker dat je {name} wilt negeren?", "confirmations.redraft.confirm": "Verwijderen en herschrijven", - "confirmations.redraft.message": "Weet je zeker dat je deze toot wilt verwijderen en herschrijven? Je verliest wel de boosts en favorieten, en de reacties op de originele toot zitten niet meer aan de nieuwe toot vast.", + "confirmations.redraft.message": "Weet je zeker dat je dit bericht wilt verwijderen en herschrijven? Je verliest wel de boosts en favorieten, en de reacties op het originele bericht raak je kwijt.", "confirmations.reply.confirm": "Reageren", - "confirmations.reply.message": "Door nu te reageren overschrijf je de toot die je op dit moment aan het schrijven bent. Weet je zeker dat je verder wil gaan?", + "confirmations.reply.message": "Door nu te reageren overschrijf je het bericht dat je op dit moment aan het schrijven bent. Weet je zeker dat je verder wil gaan?", "confirmations.unfollow.confirm": "Ontvolgen", "confirmations.unfollow.message": "Weet je het zeker dat je {name} wilt ontvolgen?", "conversation.delete": "Gesprek verwijderen", @@ -144,7 +144,7 @@ "directory.local": "Alleen {domain}", "directory.new_arrivals": "Nieuwe accounts", "directory.recently_active": "Onlangs actief", - "embed.instructions": "Embed deze toot op jouw website, door de onderstaande code te kopiëren.", + "embed.instructions": "Embed dit bericht op jouw website door de onderstaande code te kopiëren.", "embed.preview": "Zo komt het eruit te zien:", "emoji_button.activity": "Activiteiten", "emoji_button.custom": "Lokale emoji’s", @@ -161,41 +161,41 @@ "emoji_button.symbols": "Symbolen", "emoji_button.travel": "Reizen en locaties", "empty_column.account_suspended": "Account opgeschort", - "empty_column.account_timeline": "Hier zijn geen toots!", + "empty_column.account_timeline": "Hier zijn geen berichten!", "empty_column.account_unavailable": "Profiel is niet beschikbaar", "empty_column.blocks": "Jij hebt nog geen enkele gebruiker geblokkeerd.", - "empty_column.bookmarked_statuses": "Jij hebt nog geen toots aan je bladwijzers toegevoegd. Wanneer je er een aan jouw bladwijzers toevoegt, valt deze hier te zien.", - "empty_column.community": "De lokale tijdlijn is nog leeg. Toot iets in het openbaar om de spits af te bijten!", + "empty_column.bookmarked_statuses": "Jij hebt nog geen berichten aan je bladwijzers toegevoegd. Wanneer je er een aan jouw bladwijzers toevoegt, valt deze hier te zien.", + "empty_column.community": "De lokale tijdlijn is nog leeg. Plaats een openbaar bericht om de spits af te bijten!", "empty_column.direct": "Je hebt nog geen directe berichten. Wanneer je er een verzend of ontvangt, zijn deze hier te zien.", "empty_column.domain_blocks": "Er zijn nog geen geblokkeerde domeinen.", - "empty_column.explore_statuses": "Nothing is trending right now. Check back later!", - "empty_column.favourited_statuses": "Jij hebt nog geen favoriete toots. Wanneer je er een aan jouw favorieten toevoegt, valt deze hier te zien.", - "empty_column.favourites": "Niemand heeft deze toot nog aan hun favorieten toegevoegd. Wanneer iemand dit doet, valt dat hier te zien.", + "empty_column.explore_statuses": "Momenteel zijn er geen trends. Kom later terug!", + "empty_column.favourited_statuses": "Jij hebt nog geen favoriete berichten. Wanneer je er een aan jouw favorieten toevoegt, valt deze hier te zien.", + "empty_column.favourites": "Niemand heeft dit bericht nog aan diens favorieten toegevoegd. Wanneer iemand dit doet, valt dat hier te zien.", "empty_column.follow_recommendations": "Het lijkt er op dat er geen aanbevelingen voor jou aangemaakt kunnen worden. Je kunt proberen te zoeken naar mensen die je wellicht kent, zoeken op hashtags, de lokale en globale tijdlijnen bekijken of de gebruikersgids doorbladeren.", "empty_column.follow_requests": "Jij hebt nog enkel volgverzoek ontvangen. Wanneer je er eentje ontvangt, valt dat hier te zien.", "empty_column.hashtag": "Er is nog niks te vinden onder deze hashtag.", "empty_column.home": "Deze tijdlijn is leeg! Volg meer mensen om het te vullen. {suggestions}", "empty_column.home.suggestions": "Enkele aanbevelingen bekijken", - "empty_column.list": "Er is nog niks te zien in deze lijst. Wanneer lijstleden nieuwe toots publiceren, zijn deze hier te zien.", + "empty_column.list": "Er is nog niks te zien in deze lijst. Wanneer lijstleden nieuwe berichten plaatsen, zijn deze hier te zien.", "empty_column.lists": "Jij hebt nog geen enkele lijst. Wanneer je er eentje hebt aangemaakt, valt deze hier te zien.", "empty_column.mutes": "Jij hebt nog geen gebruikers genegeerd.", "empty_column.notifications": "Je hebt nog geen meldingen. Begin met iemand een gesprek.", - "empty_column.public": "Er is hier helemaal niks! Toot iets in het openbaar of volg mensen van andere servers om het te vullen", + "empty_column.public": "Er is hier helemaal niks! Plaatst een openbaar bericht of volg mensen van andere servers om het te vullen", "error.unexpected_crash.explanation": "Als gevolg van een bug in onze broncode of als gevolg van een compatibiliteitsprobleem met jouw webbrowser, kan deze pagina niet goed worden weergegeven.", "error.unexpected_crash.explanation_addons": "Deze pagina kon niet correct geladen worden. Deze fout wordt waarschijnlijk door een browser-add-on of een automatische vertalingshulpmiddel veroorzaakt.", "error.unexpected_crash.next_steps": "Probeer deze pagina te vernieuwen. Wanneer dit niet helpt is het nog steeds mogelijk om Mastodon in een andere webbrowser of mobiele app te gebruiken.", "error.unexpected_crash.next_steps_addons": "Probeer deze uit te schakelen en de pagina te verversen. Wanneer dat niet helpt, kun je Mastodon nog altijd met een andere webbrowser of mobiele app gebruiken.", "errors.unexpected_crash.copy_stacktrace": "Stacktrace naar klembord kopiëren", "errors.unexpected_crash.report_issue": "Technisch probleem melden", - "explore.search_results": "Search results", - "explore.suggested_follows": "For you", - "explore.title": "Explore", - "explore.trending_links": "News", - "explore.trending_statuses": "Posts", + "explore.search_results": "Zoekresultaten", + "explore.suggested_follows": "Voor jou", + "explore.title": "Verkennen", + "explore.trending_links": "Nieuws", + "explore.trending_statuses": "Berichten", "explore.trending_tags": "Hashtags", "follow_recommendations.done": "Klaar", - "follow_recommendations.heading": "Volg mensen waarvan je graag toots wil zien! Hier zijn enkele aanbevelingen.", - "follow_recommendations.lead": "Toots van mensen die je volgt zullen in chronologische volgorde onder start verschijnen. Wees niet bang om hierin fouten te maken, want je kunt mensen op elk moment net zo eenvoudig ontvolgen!", + "follow_recommendations.heading": "Volg mensen waarvan je graag berichten wil zien! Hier zijn enkele aanbevelingen.", + "follow_recommendations.lead": "Berichten van mensen die je volgt zullen in chronologische volgorde onder start verschijnen. Wees niet bang om hierin fouten te maken, want je kunt mensen op elk moment net zo eenvoudig ontvolgen!", "follow_request.authorize": "Goedkeuren", "follow_request.reject": "Afkeuren", "follow_requests.unlocked_explanation": "Ook al is jouw account niet besloten, de medewerkers van {domain} denken dat jij misschien de volgende volgverzoeken handmatig wil controleren.", @@ -227,13 +227,13 @@ "intervals.full.minutes": "{number, plural, one {# minuut} other {# minuten}}", "keyboard_shortcuts.back": "Ga terug", "keyboard_shortcuts.blocked": "Geblokkeerde gebruikers tonen", - "keyboard_shortcuts.boost": "Toot boosten", + "keyboard_shortcuts.boost": "Bericht boosten", "keyboard_shortcuts.column": "Op één van de kolommen focussen", - "keyboard_shortcuts.compose": "Tekstveld voor toots focussen", + "keyboard_shortcuts.compose": "Tekstveld om een bericht te schrijven focussen", "keyboard_shortcuts.description": "Omschrijving", "keyboard_shortcuts.direct": "Jouw directe berichten tonen", "keyboard_shortcuts.down": "Naar beneden in de lijst bewegen", - "keyboard_shortcuts.enter": "Toot volledig tonen", + "keyboard_shortcuts.enter": "Volledig bericht tonen", "keyboard_shortcuts.favourite": "Aan jouw favorieten toevoegen", "keyboard_shortcuts.favourites": "Favorieten tonen", "keyboard_shortcuts.federated": "Globale tijdlijn tonen", @@ -247,7 +247,7 @@ "keyboard_shortcuts.my_profile": "Jouw profiel tonen", "keyboard_shortcuts.notifications": "Meldingen tonen", "keyboard_shortcuts.open_media": "Media openen", - "keyboard_shortcuts.pinned": "Jouw vastgezette toots tonen", + "keyboard_shortcuts.pinned": "Jouw vastgemaakte berichten tonen", "keyboard_shortcuts.profile": "Gebruikersprofiel auteur openen", "keyboard_shortcuts.reply": "Reageren", "keyboard_shortcuts.requests": "Jouw volgverzoeken tonen", @@ -256,7 +256,7 @@ "keyboard_shortcuts.start": "\"Aan de slag\" tonen", "keyboard_shortcuts.toggle_hidden": "Inhoudswaarschuwing tonen/verbergen", "keyboard_shortcuts.toggle_sensitivity": "Media tonen/verbergen", - "keyboard_shortcuts.toot": "Nieuwe toot schrijven", + "keyboard_shortcuts.toot": "Nieuw bericht schrijven", "keyboard_shortcuts.unfocus": "Tekst- en zoekveld ontfocussen", "keyboard_shortcuts.up": "Naar boven in de lijst bewegen", "lightbox.close": "Sluiten", @@ -289,12 +289,12 @@ "navigation_bar.blocks": "Geblokkeerde gebruikers", "navigation_bar.bookmarks": "Bladwijzers", "navigation_bar.community_timeline": "Lokale tijdlijn", - "navigation_bar.compose": "Nieuw toot schrijven", + "navigation_bar.compose": "Nieuw bericht schrijven", "navigation_bar.direct": "Directe berichten", "navigation_bar.discover": "Ontdekken", "navigation_bar.domain_blocks": "Geblokkeerde domeinen", "navigation_bar.edit_profile": "Profiel bewerken", - "navigation_bar.explore": "Explore", + "navigation_bar.explore": "Verkennen", "navigation_bar.favourites": "Favorieten", "navigation_bar.filters": "Filters", "navigation_bar.follow_requests": "Volgverzoeken", @@ -305,23 +305,23 @@ "navigation_bar.logout": "Uitloggen", "navigation_bar.mutes": "Genegeerde gebruikers", "navigation_bar.personal": "Persoonlijk", - "navigation_bar.pins": "Vastgezette toots", + "navigation_bar.pins": "Vastgemaakte berichten", "navigation_bar.preferences": "Instellingen", "navigation_bar.public_timeline": "Globale tijdlijn", "navigation_bar.security": "Beveiliging", - "notification.admin.sign_up": "{name} signed up", - "notification.favourite": "{name} voegde jouw toot als favoriet toe", + "notification.admin.sign_up": "{name} heeft zich aangemeld", + "notification.favourite": "{name} voegde jouw bericht als favoriet toe", "notification.follow": "{name} volgt jou nu", "notification.follow_request": "{name} wil jou graag volgen", "notification.mention": "{name} vermeldde jou", "notification.own_poll": "Jouw poll is beëindigd", "notification.poll": "Een poll waaraan jij hebt meegedaan is beëindigd", - "notification.reblog": "{name} boostte jouw toot", - "notification.status": "{name} heeft zojuist een toot geplaatst", - "notification.update": "{name} edited a post", + "notification.reblog": "{name} boostte jouw bericht", + "notification.status": "{name} heeft zojuist een bericht geplaatst", + "notification.update": "{name} heeft een bericht bewerkt", "notifications.clear": "Meldingen verwijderen", "notifications.clear_confirmation": "Weet je het zeker dat je al jouw meldingen wilt verwijderen?", - "notifications.column_settings.admin.sign_up": "New sign-ups:", + "notifications.column_settings.admin.sign_up": "Nieuwe aanmeldingen:", "notifications.column_settings.alert": "Desktopmeldingen", "notifications.column_settings.favourite": "Favorieten:", "notifications.column_settings.filter_bar.advanced": "Alle categorieën tonen", @@ -335,10 +335,10 @@ "notifications.column_settings.reblog": "Boosts:", "notifications.column_settings.show": "In kolom tonen", "notifications.column_settings.sound": "Geluid afspelen", - "notifications.column_settings.status": "Nieuwe toots:", + "notifications.column_settings.status": "Nieuwe berichten:", "notifications.column_settings.unread_notifications.category": "Ongelezen meldingen", "notifications.column_settings.unread_notifications.highlight": "Ongelezen meldingen markeren", - "notifications.column_settings.update": "Edits:", + "notifications.column_settings.update": "Bewerkingen:", "notifications.filter.all": "Alles", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favorieten", @@ -365,7 +365,7 @@ "poll.votes": "{votes, plural, one {# stem} other {# stemmen}}", "poll_button.add_poll": "Poll toevoegen", "poll_button.remove_poll": "Poll verwijderen", - "privacy.change": "Zichtbaarheid van toot aanpassen", + "privacy.change": "Zichtbaarheid van bericht aanpassen", "privacy.direct.long": "Alleen aan vermelde gebruikers tonen", "privacy.direct.short": "Direct", "privacy.private.long": "Alleen aan volgers tonen", @@ -378,100 +378,100 @@ "regeneration_indicator.label": "Aan het laden…", "regeneration_indicator.sublabel": "Jouw tijdlijn wordt aangemaakt!", "relative_time.days": "{number}d", - "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", - "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", - "relative_time.full.just_now": "just now", - "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", - "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", + "relative_time.full.days": "{number, plural, one {# dag} other {# dagen}} geleden", + "relative_time.full.hours": "{number, plural, one {# uur} other {# uur}} geleden", + "relative_time.full.just_now": "zojuist", + "relative_time.full.minutes": "{number, plural, one {# minuut} other {# minuten}} geleden", + "relative_time.full.seconds": "{number, plural, one {# seconde} other {# seconden}} geleden", "relative_time.hours": "{number}u", "relative_time.just_now": "nu", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "vandaag", "reply_indicator.cancel": "Annuleren", - "report.block": "Block", - "report.block_explanation": "You will not see their posts. They will not be able to see your posts or follow you. They will be able to tell that they are blocked.", - "report.categories.other": "Other", + "report.block": "Blokkeren", + "report.block_explanation": "Je kunt diens berichten niet zien. Je kunt door diegene niet gevolgd worden en jouw berichten zijn onzichtbaar. Diegene kan zien dat die door jou is geblokkeerd.", + "report.categories.other": "Overig", "report.categories.spam": "Spam", - "report.categories.violation": "Content violates one or more server rules", - "report.category.subtitle": "Choose the best match", - "report.category.title": "Tell us what's going on with this {type}", - "report.category.title_account": "profile", - "report.category.title_status": "post", - "report.close": "Done", - "report.comment.title": "Is there anything else you think we should know?", + "report.categories.violation": "De inhoud overtreedt een of meerdere serverregels", + "report.category.subtitle": "Kies wat het meeste overeenkomt", + "report.category.title": "Vertel ons wat er met dit {type} aan de hand is", + "report.category.title_account": "profiel", + "report.category.title_status": "bericht", + "report.close": "Klaar", + "report.comment.title": "Zijn er nog andere dingen waarvan je denkt dat wij dat moeten weten?", "report.forward": "Naar {target} doorsturen", "report.forward_hint": "Het account bevindt zich op een andere server. Wil je daar eveneens een geanonimiseerde kopie van deze rapportage naar toe sturen?", - "report.mute": "Mute", - "report.mute_explanation": "You will not see their posts. They can still follow you and see your posts and will not know that they are muted.", - "report.next": "Next", + "report.mute": "Negeren", + "report.mute_explanation": "Je kunt diens berichten niet zien. Je kunt nog wel gevolgd worden en jouw berichten zijn nog zichtbaar, maar diegene kan niet zien dat die wordt genegeerd.", + "report.next": "Volgende", "report.placeholder": "Extra opmerkingen", - "report.reasons.dislike": "I don't like it", - "report.reasons.dislike_description": "It is not something you want to see", - "report.reasons.other": "It's something else", - "report.reasons.other_description": "The issue does not fit into other categories", - "report.reasons.spam": "It's spam", - "report.reasons.spam_description": "Malicious links, fake engagement, or repetitive replies", - "report.reasons.violation": "It violates server rules", - "report.reasons.violation_description": "You are aware that it breaks specific rules", - "report.rules.subtitle": "Select all that apply", - "report.rules.title": "Which rules are being violated?", - "report.statuses.subtitle": "Select all that apply", - "report.statuses.title": "Are there any posts that back up this report?", + "report.reasons.dislike": "Ik vind het niet leuk", + "report.reasons.dislike_description": "Het is iets wat je niet wilt zien", + "report.reasons.other": "Het is iets anders", + "report.reasons.other_description": "Het probleem past niet in een andere categorie", + "report.reasons.spam": "Het is spam", + "report.reasons.spam_description": "Schadelijke links, reclame, misleiding of herhalende antwoorden", + "report.reasons.violation": "Het schendt de serverregels", + "report.reasons.violation_description": "Je weet dat het specifieke regels schendt", + "report.rules.subtitle": "Selecteer wat van toepassing is", + "report.rules.title": "Welke regels worden geschonden?", + "report.statuses.subtitle": "Selecteer wat van toepassing is", + "report.statuses.title": "Zijn er berichten die deze rapportage ondersteunen?", "report.submit": "Verzenden", "report.target": "{target} rapporteren", - "report.thanks.take_action": "Here are your options for controlling what you see on Mastodon:", - "report.thanks.take_action_actionable": "While we review this, you can take action against @{name}:", - "report.thanks.title": "Don't want to see this?", - "report.thanks.title_actionable": "Thanks for reporting, we'll look into this.", - "report.unfollow": "Unfollow @{name}", - "report.unfollow_explanation": "You are following this account. To not see their posts in your home feed anymore, unfollow them.", + "report.thanks.take_action": "Hier zijn jouw opties waarmee je kunt bepalen wat je in Mastodon wilt zien:", + "report.thanks.take_action_actionable": "Terwijl wij jouw rapportage beroordelen, kun je deze acties ondernemen tegen @{name}:", + "report.thanks.title": "Wil je dit niet zien?", + "report.thanks.title_actionable": "Dank je voor het rapporteren. Wij gaan er naar kijken.", + "report.unfollow": "@{name} ontvolgen", + "report.unfollow_explanation": "Je volgt dit account. Om diens berichten niet meer op jouw starttijdlijn te zien, kun je diegene ontvolgen.", "search.placeholder": "Zoeken", "search_popout.search_format": "Geavanceerd zoeken", - "search_popout.tips.full_text": "Gebruik gewone tekst om te zoeken in jouw toots, gebooste toots, favorieten en in toots waarin je bent vermeldt, en tevens naar gebruikersnamen, weergavenamen en hashtags.", + "search_popout.tips.full_text": "Gebruik gewone tekst om te zoeken in jouw berichten, gebooste berichten, favorieten en in berichten waarin je bent vermeldt, en tevens naar gebruikersnamen, weergavenamen en hashtags.", "search_popout.tips.hashtag": "hashtag", - "search_popout.tips.status": "toot", + "search_popout.tips.status": "bericht", "search_popout.tips.text": "Gebruik gewone tekst om te zoeken op weergavenamen, gebruikersnamen en hashtags", "search_popout.tips.user": "gebruiker", "search_results.accounts": "Gebruikers", - "search_results.all": "All", + "search_results.all": "Alles", "search_results.hashtags": "Hashtags", - "search_results.nothing_found": "Could not find anything for these search terms", - "search_results.statuses": "Toots", - "search_results.statuses_fts_disabled": "Het zoeken in toots is op deze Mastodon-server niet ingeschakeld.", + "search_results.nothing_found": "Deze zoektermen leveren geen resultaat op", + "search_results.statuses": "Berichten", + "search_results.statuses_fts_disabled": "Het zoeken in berichten is op deze Mastodon-server niet ingeschakeld.", "search_results.total": "{count, number} {count, plural, one {resultaat} other {resultaten}}", "status.admin_account": "Moderatie-omgeving van @{name} openen", - "status.admin_status": "Deze toot in de moderatie-omgeving openen", + "status.admin_status": "Dit bericht in de moderatie-omgeving openen", "status.block": "@{name} blokkeren", "status.bookmark": "Bladwijzer toevoegen", "status.cancel_reblog_private": "Niet langer boosten", - "status.cannot_reblog": "Deze toot kan niet geboost worden", - "status.copy": "Link naar toot kopiëren", + "status.cannot_reblog": "Dit bericht kan niet geboost worden", + "status.copy": "Link naar bericht kopiëren", "status.delete": "Verwijderen", "status.detailed_status": "Uitgebreide gespreksweergave", "status.direct": "@{name} een direct bericht sturen", - "status.edit": "Edit", - "status.edited": "Edited {date}", - "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", + "status.edit": "Bewerken", + "status.edited": "Bewerkt op {date}", + "status.edited_x_times": "{count, plural, one {{count} keer} other {{count} keer}} bewerkt", "status.embed": "Insluiten", "status.favourite": "Favoriet", "status.filtered": "Gefilterd", - "status.history.created": "{name} created {date}", - "status.history.edited": "{name} edited {date}", + "status.history.created": "{name} plaatste dit {date}", + "status.history.edited": "{name} bewerkte dit {date}", "status.load_more": "Meer laden", "status.media_hidden": "Media verborgen", "status.mention": "@{name} vermelden", "status.more": "Meer", "status.mute": "@{name} negeren", "status.mute_conversation": "Negeer gesprek", - "status.open": "Volledige toot tonen", + "status.open": "Volledig bericht tonen", "status.pin": "Aan profielpagina vastmaken", - "status.pinned": "Vastgemaakte toot", + "status.pinned": "Vastgemaakt bericht", "status.read_more": "Meer lezen", "status.reblog": "Boosten", "status.reblog_private": "Boost naar oorspronkelijke ontvangers", "status.reblogged_by": "{name} boostte", - "status.reblogs.empty": "Niemand heeft deze toot nog geboost. Wanneer iemand dit doet, valt dat hier te zien.", + "status.reblogs.empty": "Niemand heeft dit bericht nog geboost. Wanneer iemand dit doet, valt dat hier te zien.", "status.redraft": "Verwijderen en herschrijven", "status.remove_bookmark": "Bladwijzer verwijderen", "status.reply": "Reageren", @@ -502,7 +502,7 @@ "timeline_hint.remote_resource_not_displayed": "{resource} van andere servers worden niet getoond.", "timeline_hint.resources.followers": "Volgers", "timeline_hint.resources.follows": "Volgend", - "timeline_hint.resources.statuses": "Oudere toots", + "timeline_hint.resources.statuses": "Oudere berichten", "trends.counter_by_accounts": "{count, plural, one {{counter} persoon} other {{counter} personen}} zijn aan het praten", "trends.trending_now": "Huidige trends", "ui.beforeunload": "Je concept gaat verloren wanneer je Mastodon verlaat.", diff --git a/config/locales/activerecord.nl.yml b/config/locales/activerecord.nl.yml index 6bbdc5b40..b5a122001 100644 --- a/config/locales/activerecord.nl.yml +++ b/config/locales/activerecord.nl.yml @@ -24,7 +24,7 @@ nl: status: attributes: reblog: - taken: van toot bestaat al + taken: van bericht bestaat al user: attributes: email: diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 054db2e5b..6c5fc95fe 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -490,6 +490,7 @@ ca: other: Intents fallits en %{count} diferents dies. no_failures_recorded: Sense errors registrats. title: Disponibilitat + warning: El darrer intent de connectar a aquest servidor no ha tingut èxit back_to_all: Totes back_to_limited: Limitades back_to_warning: Avís diff --git a/config/locales/da.yml b/config/locales/da.yml index 34e56ded4..b264dffae 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -490,6 +490,7 @@ da: other: Mislykkede forsøg på %{count} forskellige dage. no_failures_recorded: Ingen fejl noteret. title: Tilgængelighed + warning: Seneste forsøg på at oprette forbindelse til denne server mislykkedes back_to_all: Alle back_to_limited: Begrænset back_to_warning: Advarsel diff --git a/config/locales/de.yml b/config/locales/de.yml index 4768f4e80..d595fdd42 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -373,6 +373,7 @@ de: enable: Aktivieren enabled: Aktiviert enabled_msg: Das Emoji wurde aktiviert + image_hint: PNG oder GIF bis %{size} list: Liste listed: Gelistet new: @@ -489,6 +490,7 @@ de: other: Fehlgeschlagener Versuch am %{count}. Tag. no_failures_recorded: Keine Fehler bei der Aufzeichnung. title: Verfügbarkeit + warning: Der letzte Versuch, sich mit diesem Server zu verbinden, war nicht erfolgreich back_to_all: Alle back_to_limited: Beschränkt back_to_warning: Warnung @@ -1436,6 +1438,7 @@ de: disallowed_hashtags: one: 'enthält einen verbotenen Hashtag: %{tags}' other: 'enthält verbotene Hashtags: %{tags}' + edited_at_html: Bearbeitet %{date} errors: in_reply_not_found: Der Beitrag, auf den du antworten möchtest, scheint nicht zu existieren. open_in_web: Im Web öffnen diff --git a/config/locales/doorkeeper.id.yml b/config/locales/doorkeeper.id.yml index 050d97dc5..9a3fed94d 100644 --- a/config/locales/doorkeeper.id.yml +++ b/config/locales/doorkeeper.id.yml @@ -73,6 +73,10 @@ id: index: authorized_at: Diberi hak otorisasi pada %{date} description_html: Ini adalah aplikasi yang dapat mengakses akun Anda menggunakan API. Jika ada aplikasi yang tidak Anda kenal di sini, atau aplikasi yang berperilaku aneh, Anda dapat mencabut hak aksesnya. + last_used_at: Terakhir dipakai pada %{date} + never_used: Tidak pernah dipakai + scopes: Hak akses + superapp: Internal title: Aplikasi yang anda izinkan errors: messages: @@ -108,6 +112,33 @@ id: authorized_applications: destroy: notice: Aplikasi dicabut. + grouped_scopes: + access: + read: Akses baca-saja + read/write: Akses baca dan tulis + write: Akses tulis-saja + title: + accounts: Akun + admin/accounts: Administrasi akun + admin/all: Semua fungsi administratif + admin/reports: Administrasi laporan + all: Segalanya + blocks: Blokir + bookmarks: Markah + conversations: Percakapan + crypto: Enkripsi end-to-end + favourites: Favorit + filters: Saringan + follow: Hubungan + follows: Mengikuti + lists: Daftar + media: Lampiran media + mutes: Bisukan + notifications: Notifikasi + push: Notifikasi dorong + reports: Laporan + search: Pencarian + statuses: Kiriman layouts: admin: nav: @@ -122,6 +153,7 @@ id: admin:write: ubah semua data di server admin:write:accounts: lakukan aksi moderasi akun admin:write:reports: lakukan aksi moderasi laporan + crypto: menggunakan enkripsi end-to-end follow: mengikuti, blokir, menghapus blokir, dan berhenti mengikuti akun push: terima notifikasi dorong read: membaca data pada akun anda @@ -141,6 +173,7 @@ id: write:accounts: ubah profil Anda write:blocks: blokir akun dan domain write:bookmarks: status markah + write:conversations: bisukan dan hapus percakapan write:favourites: status favorit write:filters: buat saringan write:follows: ikuti orang diff --git a/config/locales/doorkeeper.ku.yml b/config/locales/doorkeeper.ku.yml index 3a98486e3..6db8bb73d 100644 --- a/config/locales/doorkeeper.ku.yml +++ b/config/locales/doorkeeper.ku.yml @@ -130,7 +130,7 @@ ku: favourites: Bijarte filters: Parzûn follow: Pêwendî - follows: Şopîner + follows: Dişopîne lists: Rêzok media: Pêvekên medya mutes: Bêdengkirin @@ -162,7 +162,7 @@ ku: read:bookmarks: şûnpelên xwe bibîne read:favourites: bijarteyên xwe bibîne read:filters: parzûnûn xwe bibîne - read:follows: şopînerên xwe bibîne + read:follows: ên tu dişopînî bibîne read:lists: rêzoka xwe bibîne read:mutes: ajimêrên bêdeng kirî bibîne read:notifications: agahdariyên xwe bibîne diff --git a/config/locales/doorkeeper.nl.yml b/config/locales/doorkeeper.nl.yml index cb0c70aab..76f3b88c3 100644 --- a/config/locales/doorkeeper.nl.yml +++ b/config/locales/doorkeeper.nl.yml @@ -60,6 +60,8 @@ nl: error: title: Er is een fout opgetreden new: + prompt_html: "%{client_name} heeft toestemming nodig om toegang te krijgen tot jouw account. Het betreft een third-party-toepassing.Als je dit niet vertrouwt, moet je geen toestemming verlenen." + review_permissions: Toestemmingen beoordelen title: Autorisatie vereist show: title: Kopieer deze autorisatiecode en plak het in de toepassing. @@ -69,6 +71,11 @@ nl: confirmations: revoke: Weet je het zeker? index: + authorized_at: Toestemming verleent op %{date} + last_used_at: Voor het laatst gebruikt op %{date} + never_used: Nooit gebruikt + scopes: Toestemmingen + superapp: Intern title: Jouw geautoriseerde toepassingen errors: messages: @@ -104,6 +111,33 @@ nl: authorized_applications: destroy: notice: Toepassing ingetrokken. + grouped_scopes: + access: + read: Alleen leestoegang + read/write: Lees- en schrijftoegang + write: Alleen schrijftoegang + title: + accounts: Accounts + admin/accounts: Accountbeheer + admin/all: Alle beheerfuncties + admin/reports: Rapportagebeheer + all: Alles + blocks: Blokkeren + bookmarks: Bladwijzers + conversations: Gesprekken + crypto: End-to-end-encryptie + favourites: Favorieten + filters: Filters + follow: Relaties + follows: Volgend + lists: Lijsten + media: Mediabijlagen + mutes: Negeren + notifications: Meldingen + push: Pushmeldingen + reports: Rapportages + search: Zoeken + statuses: Berichten layouts: admin: nav: @@ -118,6 +152,7 @@ nl: admin:write: wijzig alle gegevens op de server admin:write:accounts: moderatieacties op accounts uitvoeren admin:write:reports: moderatieacties op rapportages uitvoeren + crypto: end-to-end-encryptie gebruiken follow: relaties tussen accounts bewerken push: jouw pushmeldingen ontvangen read: alle gegevens van jouw account lezen @@ -130,14 +165,15 @@ nl: read:lists: jouw lijsten bekijken read:mutes: jouw genegeerde gebruikers bekijken read:notifications: jouw meldingen bekijken - read:reports: jouw gerapporteerde toots bekijken + read:reports: jouw gerapporteerde berichten bekijken read:search: namens jou zoeken - read:statuses: alle toots bekijken + read:statuses: alle berichten bekijken write: alle gegevens van jouw account bewerken write:accounts: jouw profiel bewerken write:blocks: accounts en domeinen blokkeren - write:bookmarks: toots aan bladwijzers toevoegen - write:favourites: toots als favoriet markeren + write:bookmarks: berichten aan bladwijzers toevoegen + write:conversations: gespreken negeren en verwijderen + write:favourites: berichten als favoriet markeren write:filters: filters aanmaken write:follows: mensen volgen write:lists: lijsten aanmaken @@ -145,4 +181,4 @@ nl: write:mutes: mensen en gesprekken negeren write:notifications: meldingen verwijderen write:reports: andere mensen rapporteren - write:statuses: toots publiceren + write:statuses: berichten plaatsen diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index 7dee30a27..2acc958a7 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -490,6 +490,7 @@ es-AR: other: Intentos fallidos en %{count} días. no_failures_recorded: No hay fallos en el registro. title: Disponibilidad + warning: El último intento de conexión a este servidor no fue exitoso back_to_all: Todos back_to_limited: Limitados back_to_warning: Advertencia diff --git a/config/locales/es.yml b/config/locales/es.yml index bcce44e20..31970da48 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -490,6 +490,7 @@ es: other: Intentos fallidos en %{count} días diferentes. no_failures_recorded: No hay fallos en el registro. title: Disponibilidad + warning: El último intento de conexión a este servidor no ha tenido éxito back_to_all: Todos back_to_limited: Limitados back_to_warning: Advertencia diff --git a/config/locales/gl.yml b/config/locales/gl.yml index f3a4beb70..27642844c 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -490,6 +490,7 @@ gl: other: Intentos fallidos durante %{count} días distintos. no_failures_recorded: Non hai fallos rexistrados. title: Dispoñibilidade + warning: Fallou o último intento de conectar con este servidor back_to_all: Todo back_to_limited: Limitado back_to_warning: Aviso diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 000184317..ec2d4fa94 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -492,6 +492,7 @@ hu: other: Sikertelen próbálkozás %{count} különböző napon. no_failures_recorded: Nem rögzítettünk hibát. title: Elérhetőség + warning: Sikertelen volt az utolsó csatlakozási próbálkozás ehhez a szerverhez back_to_all: Mind back_to_limited: Korlátozott back_to_warning: Figyelmeztetés diff --git a/config/locales/id.yml b/config/locales/id.yml index 97443b4a5..63b9066ce 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -477,6 +477,7 @@ id: other: Upaya gagal dalam %{count} hari berbeda. no_failures_recorded: Tidak ada kegagalan tercatat. title: Ketersediaan + warning: Upaya terakhir untuk menyambung ke server ini tidak berhasil back_to_all: Semua back_to_limited: Terbatas back_to_warning: Peringatan diff --git a/config/locales/is.yml b/config/locales/is.yml index 04d193975..92eb0e31e 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -490,6 +490,7 @@ is: other: Misheppnaðar tilraunir á %{count} mismunandi dögum. no_failures_recorded: Engar misheppnaðar tilraunir á skrá. title: Tiltækileiki + warning: Síðasta tilraun til að tengjast þessum netþjóni mistókst back_to_all: Allt back_to_limited: Takmarkað back_to_warning: Aðvörun diff --git a/config/locales/it.yml b/config/locales/it.yml index d96e58540..5af135fbc 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -490,6 +490,7 @@ it: other: Tentativo fallito %{count} giorni differenti. no_failures_recorded: Nessun fallimento registrato. title: Disponibilità + warning: L'ultimo tentativo di connessione a questo server non è riuscito back_to_all: Tutto back_to_limited: Limitato back_to_warning: Avviso diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 7dacd90d3..19cabb1ce 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -481,6 +481,7 @@ ko: other: 실패한 전달 시도 총 %{count}일. no_failures_recorded: 실패 기록이 없습니다. title: 가용성 + warning: 이 서버에 대한 마지막 연결 시도가 성공적이지 않았습니다 back_to_all: 전체 back_to_limited: 제한됨 back_to_warning: 경고 diff --git a/config/locales/ku.yml b/config/locales/ku.yml index 5245f85ec..7dac9ae44 100644 --- a/config/locales/ku.yml +++ b/config/locales/ku.yml @@ -133,7 +133,7 @@ ku: enabled: Çalakkirî enabled_msg: Ajimêra %{username} bi serkeftî hat çalak kirin followers: Şopîner - follows: Dişopînê + follows: Dişopîne header: Jormalper inbox_url: Peyamên hatî URl invite_request_text: Sedemên tevlêbûnê @@ -492,6 +492,7 @@ ku: other: Hewldanên têkçûyî di %{count} rojên cuda de. no_failures_recorded: Di tomarê de têkçûn tune. title: Berdestbûnî + warning: Hewldana dawî ji bo girêdana bi vê rajekarê re bi ser neket back_to_all: Hemû back_to_limited: Sînorkirî back_to_warning: Hişyarî @@ -543,7 +544,7 @@ ku: title: Giştî total_blocked_by_us: Ji aliyê me ve hatiye astengkirin total_followed_by_them: Ji aliyê wan ve hatiye şopandin - total_followed_by_us: Ji aliyê ve me hate şopandin + total_followed_by_us: Ji aliyê me ve hatiye şopandin total_reported: Giliyên derheqê wan de total_storage: Pêvekên medyayê totals_time_period_hint_html: Tevahiyên ku li jêr têne xuyakirin daneyên hemû deman dihewîne. @@ -975,7 +976,7 @@ ku: close: An jî, tu dikarî tenê ev çarçoveyê bigirî. return: Profîla vê bikarhênerê nîşan bike web: Biçe tevneyê - title: Bişopîne %{acct} + title: "%{acct} bişopîne" challenge: confirm: Bidomîne hint_html: "Nîşe:Ji bo demjimêreke din em ê pêborîna te careke din ji te nexwazin." @@ -1247,7 +1248,7 @@ ku: follow: body: "%{name} niha te dişopîne!" subject: "%{name} niha te dişopîne" - title: Şopînereke nû + title: Şopînera nû follow_request: action: Daxwazên şopandinê bi rê ve bibe body: "%{name} daxwaza şopandina te kir" @@ -1416,7 +1417,7 @@ ku: notifications: Agahdarî preferences: Hilbijarte profile: Profîl - relationships: Yên tê şopandin û şopîner + relationships: Şopandin û şopîner statuses_cleanup: Bi xweberî ve jêbirina şandiya strikes: Binpêkirinên çavdêriyê two_factor_authentication: Piştrastkirinê du-faktorî diff --git a/config/locales/lv.yml b/config/locales/lv.yml index 8f6df9961..3440da7ef 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -501,6 +501,7 @@ lv: zero: Neizdevušies mēģinājumi %{count} dienās. no_failures_recorded: Nav reģistrētu kļūdu. title: Pieejamība + warning: Pēdējais mēģinājums izveidot savienojumu ar šo serveri ir bijis neveiksmīgs back_to_all: Visas back_to_limited: Ierobežotās back_to_warning: Brīdinājums diff --git a/config/locales/nl.yml b/config/locales/nl.yml index a51ef07af..276fdb9b2 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -1,7 +1,7 @@ --- nl: about: - about_hashtag_html: Dit zijn openbare toots die getagged zijn met #%{hashtag}. Je kunt er op reageren of iets anders mee doen als je op Mastodon (of ergens anders in de fediverse) een account hebt. + about_hashtag_html: Dit zijn openbare berichten die getagged zijn met #%{hashtag}. Je kunt er op reageren of iets anders mee doen als je op Mastodon (of ergens anders in de fediverse) een account hebt. about_mastodon_html: Mastodon is een sociaal netwerk dat gebruikt maakt van open webprotocollen en vrije software. Het is net zoals e-mail gedecentraliseerd. about_this: Over deze server active_count_after: actief @@ -31,7 +31,7 @@ nl: source_code: Broncode status_count_after: one: toot - other: toots + other: berichten status_count_before: Zij schreven tagline: Vrienden volgen en nieuwe ontdekken terms: Gebruiksvoorwaarden @@ -41,7 +41,7 @@ nl: reason: 'Reden:' rejecting_media: 'Mediabestanden van deze server worden niet verwerkt en er worden geen thumbnails getoond. Je moet handmatig naar deze server doorklikken om de mediabestanden te kunnen bekijken:' rejecting_media_title: Mediabestanden geweigerd - silenced: Toots van deze server worden nergens weergegeven, behalve op jouw eigen starttijdlijn wanneer je het account volgt. + silenced: Berichten van deze server worden nergens weergegeven, behalve op jouw eigen starttijdlijn wanneer je het account volgt. silenced_title: Beperkte servers suspended: Je bent niet in staat om iemand van deze server te volgen, en er worden geen gegevens van deze server verwerkt of opgeslagen, en met deze server uitgewisseld. suspended_title: Opgeschorte servers @@ -74,9 +74,9 @@ nl: following: Je moet dit account wel al volgen, alvorens je het kan aanbevelen posts: one: Toot - other: Toots - posts_tab_heading: Toots - posts_with_replies: Toots en reacties + other: Berichten + posts_tab_heading: Berichten + posts_with_replies: Berichten en reacties roles: admin: Beheerder bot: Bot @@ -193,7 +193,7 @@ nl: targeted_reports: Door anderen gerapporteerd silence: Beperken silenced: Beperkt - statuses: Toots + statuses: Berichten subscribe: Abonneren suspended: Opgeschort suspension_irreversible: De gegevens van dit account zijn onomkeerbaar verwijderd. Je kunt het opschorten van dit account ongedaan maken zodat het weer valt te gebruiken, maar de verwijderde gegevens worden hiermee niet hersteld. @@ -229,7 +229,7 @@ nl: destroy_custom_emoji: Lokale emoji verwijderen destroy_domain_allow: Domeingoedkeuring verwijderen destroy_domain_block: Domeinblokkade verwijderen - destroy_email_domain_block: E-maildomeinblokkade verwijderen + destroy_email_domain_block: Blokkade van e-maildomein verwijderen destroy_ip_block: IP-regel verwijderen destroy_status: Toot verwijderen destroy_unavailable_domain: Niet beschikbaar domein verwijderen @@ -245,16 +245,16 @@ nl: reset_password_user: Wachtwoord opnieuw instellen resolve_report: Rapportage oplossen sensitive_account: De media in jouw account als gevoelig markeren - silence_account: Account negeren + silence_account: Account beperken suspend_account: Account opschorten unassigned_report: Rapportage niet langer toewijzen unsensitive_account: De media in jouw account niet langer als gevoelig markeren - unsilence_account: Account niet langer negeren + unsilence_account: Account niet langer beperken unsuspend_account: Account niet langer opschorten update_announcement: Mededeling bijwerken update_custom_emoji: Lokale emoji bijwerken update_domain_block: Domeinblokkade bijwerken - update_status: Toot bijwerken + update_status: Bericht bijwerken actions: assigned_to_self_report_html: "%{name} heeft rapportage %{target} aan zichzelf toegewezen" change_email_user_html: "%{name} veranderde het e-mailadres van gebruiker %{target}" @@ -274,7 +274,7 @@ nl: destroy_domain_block_html: Domein %{target} is door %{name} gedeblokkeerd destroy_email_domain_block_html: "%{name} heeft het e-maildomein %{target} gedeblokkeerd" destroy_ip_block_html: "%{name} verwijderde regel voor IP %{target}" - destroy_status_html: Toot van %{target} is door %{name} verwijderd + destroy_status_html: Bericht van %{target} is door %{name} verwijderd destroy_unavailable_domain_html: "%{name} heeft de bezorging voor domein %{target} hervat" disable_2fa_user_html: De vereiste tweestapsverificatie voor %{target} is door %{name} uitgeschakeld disable_custom_emoji_html: Emoji %{target} is door %{name} uitgeschakeld @@ -297,8 +297,8 @@ nl: update_announcement_html: "%{name} heeft de mededeling %{target} bijgewerkt" update_custom_emoji_html: Emoji %{target} is door %{name} bijgewerkt update_domain_block_html: "%{name} heeft de domeinblokkade bijgewerkt voor %{target}" - update_status_html: "%{name} heeft de toots van %{target} bijgewerkt" - deleted_status: "(verwijderde toot}" + update_status_html: "%{name} heeft de berichten van %{target} bijgewerkt" + deleted_status: "(verwijderd bericht}" empty: Geen logs gevonden. filter_by_action: Op actie filteren filter_by_user: Op gebruiker filteren @@ -461,11 +461,11 @@ nl: relays: add_new: Nieuwe relayserver toevoegen delete: Verwijderen - description_html: Een federatierelay is een tussenliggende server die grote hoeveelheden openbare toots uitwisselt tussen servers die zich hierop hebben geabonneerd. Het kan kleine en middelgrote servers helpen om content uit de fediverse te ontdekken, waarvoor anders lokale gebruikers handmatig mensen van externe servers moeten volgen. + description_html: Een federatierelay is een tussenliggende server die grote hoeveelheden openbare berichten uitwisselt tussen servers die zich hierop hebben geabonneerd. Het kan kleine en middelgrote servers helpen om content van de fediverse te ontdekken, waarvoor anders lokale gebruikers handmatig mensen van externe servers moeten volgen. disable: Uitschakelen disabled: Uitgeschakeld enable: Inschakelen - enable_hint: Eenmaal ingeschakeld gaat jouw server zich op alle openbare toots van deze relayserver abonneren en stuurt het de openbare toots van jouw server naar de relayserver. + enable_hint: Eenmaal ingeschakeld gaat jouw server zich op alle openbare berichten van deze relayserver abonneren en stuurt het de openbare berichten van jouw server naar de relayserver. enabled: Ingeschakeld inbox_url: Relay-URL pending: Aan het wachten op toestemming van de relayserver @@ -506,7 +506,7 @@ nl: reported_by: Gerapporteerd door resolved: Opgelost resolved_msg: Rapportage succesvol opgelost! - status: Toot + status: Bericht title: Rapportages unassign: Niet langer toewijzen unresolved: Onopgelost @@ -520,7 +520,7 @@ nl: title: Serverregels settings: activity_api_enabled: - desc_html: Wekelijks overzicht van de hoeveelheid lokale toots, actieve gebruikers en nieuwe registraties + desc_html: Wekelijks overzicht van de hoeveelheid lokale berichten, actieve gebruikers en nieuwe registraties title: Statistieken over gebruikersactiviteit via de API publiceren bootstrap_timeline_accounts: desc_html: Meerdere gebruikersnamen met komma's scheiden. Deze accounts worden in ieder geval aan nieuwe gebruikers aanbevolen @@ -533,7 +533,7 @@ nl: title: Aangepaste CSS default_noindex: desc_html: Heeft invloed op alle gebruikers die deze instelling niet zelf hebben veranderd - title: Toots van gebruikers standaard niet door zoekmachines laten indexeren + title: Berichten van gebruikers standaard niet door zoekmachines laten indexeren domain_blocks: all: Aan iedereen disabled: Aan niemand @@ -561,7 +561,7 @@ nl: desc_html: Wordt op de voorpagina weergegeven wanneer registratie van nieuwe accounts is uitgeschakeld
En ook hier kan je HTML gebruiken title: Bericht wanneer registratie is uitgeschakeld deletion: - desc_html: Toestaan dat iedereen hun eigen account kan verwijderen + desc_html: Toestaan dat iedereen diens eigen account kan verwijderen title: Verwijderen account toestaan min_invite_role: disabled: Niemand @@ -606,7 +606,7 @@ nl: title: Hashtags toestaan om trending te worden zonder voorafgaande beoordeling trends: desc_html: Eerder beoordeelde hashtags die op dit moment trending zijn openbaar tonen - title: Trending hashtags + title: Trends site_uploads: delete: Geüpload bestand verwijderen destroyed_msg: Verwijderen website-upload geslaagd! @@ -615,8 +615,8 @@ nl: deleted: Verwijderd media: title: Media - no_status_selected: Er werden geen toots gewijzigd, omdat er geen enkele werd geselecteerd - title: Toots van account + no_status_selected: Er werden geen berichten gewijzigd, omdat er geen enkele werd geselecteerd + title: Berichten van account with_media: Met media system_checks: database_schema_check: @@ -662,14 +662,14 @@ nl: guide_link: https://crowdin.com/project/mastodon/nl guide_link_text: Iedereen kan bijdragen. sensitive_content: Gevoelige inhoud - toot_layout: Lay-out van toots + toot_layout: Lay-out van berichten application_mailer: notification_preferences: E-mailvoorkeuren wijzigen salutation: "%{name}," settings: 'E-mailvoorkeuren wijzigen: %{link}' view: 'Bekijk:' view_profile: Profiel bekijken - view_status: Toot bekijken + view_status: Bericht bekijken applications: created: Aanmaken toepassing geslaagd destroyed: Verwijderen toepassing geslaagd @@ -768,8 +768,8 @@ nl: success_msg: Jouw account is succesvol verwijderd warning: before: 'Lees deze tekst zorgvuldig voordat je verder gaat:' - caches: Toots en media die op andere servers zijn opgeslagen kunnen daar achterblijven - data_removal: Jouw toots en andere gegevens worden permanent verwijderd + caches: Berichten en media die op andere servers zijn opgeslagen kunnen daar achterblijven + data_removal: Jouw berichten en andere gegevens worden permanent verwijderd email_change_html: Je kunt je e-mailadres wijzigen zonder dat je jouw account hoeft te verwijderen email_contact_html: Wanneer het nog steeds niet aankomt, kun je voor hulp e-mailen naar %{email} email_reconfirmation_html: Wanneer je de bevestigingsmail niet hebt ontvangen, kun je deze opnieuw aanvragen @@ -805,7 +805,7 @@ nl: archive_takeout: date: Datum download: Jouw archief downloaden - hint_html: Je kunt een archief opvragen van jouw toots en geüploade media. De geëxporteerde gegevens zijn in het ActivityPub-formaat, dat door hiervoor geschikte software valt uit te lezen. Je kunt elke 7 dagen een kopie van je archief aanvragen. + hint_html: Je kunt een archief opvragen van jouw berichten en geüploade media. De geëxporteerde gegevens zijn in het ActivityPub-formaat, dat door hiervoor geschikte software valt uit te lezen. Je kunt elke 7 dagen een kopie van je archief aanvragen. in_progress: Jouw archief wordt samengesteld... request: Jouw archief opvragen size: Omvang @@ -820,7 +820,7 @@ nl: add_new: Nieuwe toevoegen errors: limit: Je hebt al het maximaal aantal hashtags uitgelicht - hint_html: "Wat zijn uitgelichte hashtags? Deze worden prominent op jouw openbare profiel getoond en stelt mensen in staat om jouw openbare toots per hashtag te bekijken. Het zijn een goed hulpmiddel om creatieve werkzaamheden of langetermijnprojecten bij te houden." + hint_html: "Wat zijn uitgelichte hashtags? Deze worden prominent op jouw openbare profiel getoond en stelt mensen in staat om jouw openbare berichten per hashtag te bekijken. Het zijn een goed hulpmiddel om creatieve werkzaamheden of langetermijnprojecten bij te houden." filters: contexts: account: Profielen @@ -901,7 +901,7 @@ nl: limit: Je hebt het maximaal aantal lijsten bereikt media_attachments: validations: - images_and_video: Een video kan niet aan een toot met afbeeldingen worden gekoppeld + images_and_video: Een video kan niet aan een bericht met afbeeldingen worden gekoppeld not_ready: Kan geen bestanden toevoegen die nog niet zijn verwerkt. Probeer het later opnieuw! too_many: Er kunnen niet meer dan 4 afbeeldingen toegevoegd worden migrations: @@ -954,8 +954,8 @@ nl: other: "%{count} nieuwe meldingen sinds jouw laatste bezoek \U0001F418" title: Tijdens jouw afwezigheid... favourite: - body: 'Jouw toot werd door %{name} aan hun favorieten toegevoegd:' - subject: "%{name} voegde jouw toot als favoriet toe" + body: 'Jouw bericht werd door %{name} aan diens favorieten toegevoegd:' + subject: "%{name} voegde jouw bericht als favoriet toe" title: Nieuwe favoriet follow: body: "%{name} volgt jou nu!" @@ -974,11 +974,11 @@ nl: poll: subject: Een poll van %{name} is beëindigd reblog: - body: 'Jouw toot werd door %{name} geboost:' - subject: "%{name} boostte jouw toot" + body: 'Jouw bericht werd door %{name} geboost:' + subject: "%{name} boostte jouw bericht" title: Nieuwe boost status: - subject: "%{name} heeft zojuist een toot geplaatst" + subject: "%{name} heeft zojuist een bericht geplaatst" notifications: email_events: E-mailmeldingen voor gebeurtenissen email_events_hint: 'Selecteer gebeurtenissen waarvoor je meldingen wilt ontvangen:' @@ -997,7 +997,7 @@ nl: code_hint: Voer de code in die door de authenticatie-app werd gegenereerd description_html: Na het instellen van tweestapsverificatie met een authenticatie-app, kun je alleen inloggen als je jouw mobiele telefoon bij je hebt. Hiermee genereer je namelijk de in te voeren toegangscode. enable: Inschakelen - instructions_html: "Scan deze QR-code in Google Authenticator of een soortgelijke app op jouw mobiele telefoon. Van nu af aan genereert deze app toegangscodes die je bij het inloggen moet invoeren." + instructions_html: "Scan deze QR-code in Google Authenticator of een soortgelijke app op jouw mobiele telefoon. Vanaf nu genereert deze app toegangscodes die je bij het inloggen moet invoeren." manual_instructions: 'Voor het geval je de QR-code niet kunt scannen en het handmatig moet invoeren, vind je hieronder de geheime code in platte tekst:' setup: Instellen wrong_code: De ingevoerde code is ongeldig! Klopt de systeemtijd van de server en die van jouw apparaat? @@ -1053,17 +1053,17 @@ nl: remote_interaction: favourite: proceed: Doorgaan met toevoegen aan jouw favorieten - prompt: 'Je wilt de volgende toot aan jouw favorieten toevoegen:' + prompt: 'Je wilt het volgende bericht aan jouw favorieten toevoegen:' reblog: proceed: Doorgaan met boosten - prompt: 'Je wilt de volgende toot boosten:' + prompt: 'Je wilt het volgende bericht boosten:' reply: proceed: Doorgaan met reageren - prompt: 'Je wilt op de volgende toot reageren:' + prompt: 'Je wilt op het volgende bericht reageren:' scheduled_statuses: - over_daily_limit: Je hebt de limiet van %{limit} in te plannen toots voor die dag overschreden - over_total_limit: Je hebt de limiet van %{limit} in te plannen toots overschreden - too_soon: De datum voor de ingeplande toot moet in de toekomst liggen + over_daily_limit: Je hebt de limiet van %{limit} in te plannen berichten voor vandaag overschreden + over_total_limit: Je hebt de limiet van %{limit} in te plannen berichten overschreden + too_soon: De datum voor het ingeplande bericht moet in de toekomst liggen sessions: activity: Laatst actief browser: Webbrowser @@ -1093,7 +1093,7 @@ nl: adobe_air: Adobe Air android: Android blackberry: Blackberry - chrome_os: ChromeOS + chrome_os: Chrome OS firefox_os: Firefox OS ios: iOS linux: Linux @@ -1144,12 +1144,12 @@ nl: one: 'bevatte een niet toegestane hashtag: %{tags}' other: 'bevatte niet toegestane hashtags: %{tags}' errors: - in_reply_not_found: De toot waarop je probeert te reageren lijkt niet te bestaan. + in_reply_not_found: Het bericht waarop je probeert te reageren lijkt niet te bestaan. open_in_web: In de webapp openen over_character_limit: Limiet van %{max} tekens overschreden pin_errors: - limit: Je hebt het maximaal aantal toots al vastgezet - ownership: Een toot van iemand anders kan niet worden vastgezet + limit: Je hebt het maximaal aantal bericht al vastgemaakt + ownership: Een bericht van iemand anders kan niet worden vastgemaakt reblog: Een boost kan niet worden vastgezet poll: total_people: @@ -1174,7 +1174,7 @@ nl: unlisted: Minder openbaar unlisted_long: Aan iedereen tonen, maar niet op openbare tijdlijnen stream_entries: - pinned: Vastgemaakte toot + pinned: Vastgemaakt bericht reblogged: boostte sensitive_content: Gevoelige inhoud tags: @@ -1332,7 +1332,7 @@ nl: otp_lost_help_html: Als je toegang tot beiden kwijt bent geraakt, neem dan contact op via %{email} seamless_external_login: Je bent ingelogd via een externe dienst, daarom zijn wachtwoorden en e-mailinstellingen niet beschikbaar. signed_in_as: 'Ingelogd als:' - suspicious_sign_in_confirmation: Het lijkt er op dat je nog niet eerder op dit apparaat bent ingelogd, en je bent een tijdje niet ingelogd, dus sturen we een beveiligingscode naar je e-mailadres om te bevestigen dat jij het bent. + suspicious_sign_in_confirmation: Het lijkt er op dat je nog niet eerder op dit apparaat bent ingelogd, dus sturen we een beveiligingscode naar jouw e-mailadres om te bevestigen dat jij het bent. verification: explanation_html: 'Je kunt jezelf verifiëren als de eigenaar van de links in de metadata van jouw profiel. Hiervoor moet op de gelinkte website een link terug naar jouw Mastodonprofiel staan. Deze link moet het rel="me"-attribuut bevatten. De omschrijving van de link maakt niet uit. Hier is een voorbeeld:' verification: Verificatie diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index 0fdfff517..348545cbf 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -490,6 +490,7 @@ pt-PT: other: Tentativas em %{count} dias diferentes. no_failures_recorded: Sem falhas registadas. title: Disponibilidade + warning: A última tentativa de conectar a este servidor não foi bem sucedida back_to_all: Todas back_to_limited: Limitadas back_to_warning: Aviso diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 579ea6462..4440f3336 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -480,6 +480,7 @@ ru: availability: no_failures_recorded: Сбоев в записи нет. title: Доступность + warning: Последняя попытка подключения к этому серверу не удалась back_to_all: Все узлы back_to_limited: Все ограниченные узлы back_to_warning: Все узлы требующие внимания @@ -742,6 +743,7 @@ ru: none: "%{name} отправил(а) предупреждение %{target}" sensitive: "%{name} отметил(а) учетную запись %{target} как деликатную" silence: "%{name} ограничил(а) учетную запись %{target}" + appeal_approved: Обжаловано appeal_pending: Обжалование в обработке system_checks: database_schema_check: @@ -806,6 +808,8 @@ ru: empty: Вы еще не определили пресеты предупреждений. title: Управление шаблонами предупреждений admin_mailer: + new_appeal: + subject: "%{username} обжалует решение модерации на %{instance}" new_pending_account: body: Ниже указана информация учётной записи. Вы можете одобрить или отклонить заявку. subject: Новая учётная запись для рассмотрения на %{instance} (%{username}) diff --git a/config/locales/simple_form.fa.yml b/config/locales/simple_form.fa.yml index 679d7d8fd..7fdd3b7a8 100644 --- a/config/locales/simple_form.fa.yml +++ b/config/locales/simple_form.fa.yml @@ -27,6 +27,8 @@ fa: scheduled_at: برای انتشار فوری اعلامیه، خالی بگذارید starts_at: اختیاری. در صورتی که اعلامیه‌تان محدود به بازهٔ زمانی خاصی است text: می‌توانید مانند یک بوق‌ معمولی بنویسید. یادتان باشد که اعلامیهٔ شما فضای صفحهٔ کاربران را اشغال خواهد کرد + appeal: + text: فقط یک بار می‌توانید برای اخطار اعتراض کنید defaults: autofollow: کسانی که از راه دعوت‌نامه عضو می‌شوند به طور خودکار پیگیر شما خواهند شد avatar: یکی از قالب‌های PNG یا GIF یا JPG. بیشترین اندازه %{size}. تصویر به اندازهٔ %{dimensions} پیکسل تبدیل خواهد شد @@ -35,6 +37,7 @@ fa: current_password: به دلایل امنیتی لطفاً رمز این حساب را وارد کنید current_username: برای تأیید، لطفاً نام کاربری حساب فعلی را وارد کنید digest: تنها وقتی فرستاده می‌شود که مدتی طولانی فعالیتی نداشته باشید و در این مدت برای شما پیغام خصوصی‌ای نوشته شده باشد + discoverable: اجازه دهید حساب‌تان از طریق پیشنهادها، پرطرفدارها و سایر قابلیت‌ها، توسط افراد غریبه قابل کشف باشد email: به شما ایمیل تأییدی فرستاده خواهد شد fields: شما می‌توانید تا چهار مورد را در یک جدول در نمایهٔ خود نمایش دهید header: یکی از قالب‌های PNG یا GIF یا JPG. بیشترین اندازه %{size}. تصویر به اندازهٔ %{dimensions} پیکسل تبدیل خواهد شد @@ -60,6 +63,7 @@ fa: domain_allow: domain: این دامین خواهد توانست داده‌ها از این سرور را دریافت کند و داده‌های از این دامین در این‌جا پردازش و ذخیره خواهند شد email_domain_block: + domain: این می‌تواند نام دامنه‌ای باشد که در نشانی رایانامه یا رکورد MX استفاده می‌شود. پس از ثبت نام بررسی خواهند شد. with_dns_records: تلاشی برای resolve کردن رکوردهای ساناد دامنهٔ داده‌شده انجام شده و نتیجه نیز مسدود خواهد شد featured_tag: name: 'شاید بخواهید چنین چیزهایی را به کار ببرید:' @@ -116,6 +120,8 @@ fa: scheduled_at: زمان‌بندی انتشار starts_at: آغاز رویداد text: اعلامیه + appeal: + text: توضیح دهید که چرا این تصمیم باید معکوس شود defaults: autofollow: دعوت از دیگران برای عضو شدن و پیگیری حساب شما avatar: تصویر نمایه @@ -194,6 +200,7 @@ fa: sign_up_requires_approval: محدود کردن ثبت نام‌ها severity: قانون notification_emails: + appeal: شخصی به تصمیم ناظر اعتراض کرد digest: فرستادن رایانامه‌های خلاصه favourite: وقتی کسی نوشتهٔ شما را پسندید ایمیل بفرست follow: وقتی کسی پیگیر شما شد ایمیل بفرست @@ -201,6 +208,8 @@ fa: mention: وقتی کسی از شما نام برد ایمیل بفرست pending_account: وقتی حساب تازه‌ای نیاز به بازبینی داشت ایمیل بفرست reblog: وقتی کسی نوشتهٔ شما را بازبوقید ایمیل بفرست + report: گزارش جدیدی فرستاده شد + trending_tag: روند جدیدی نیازمند بازبینی است rule: text: قانون tag: diff --git a/config/locales/simple_form.ku.yml b/config/locales/simple_form.ku.yml index 4f38ae030..dcf723591 100644 --- a/config/locales/simple_form.ku.yml +++ b/config/locales/simple_form.ku.yml @@ -144,7 +144,7 @@ ku: inbox_url: URLya guhêzkera wergirtî irreversible: Li şûna veşartinê jê bibe locale: Zimanê navrûyê - locked: Ajimêr qefl bike + locked: Ajimêr kilît bike max_uses: Hejmara bikaranîna herî zêde new_password: Pêborîna nû note: Jiyanname diff --git a/config/locales/simple_form.nl.yml b/config/locales/simple_form.nl.yml index 13d86443c..33968b508 100644 --- a/config/locales/simple_form.nl.yml +++ b/config/locales/simple_form.nl.yml @@ -7,18 +7,18 @@ nl: account_migration: acct: Vul de gebruikersnaam@domein van het account in, waarnaartoe je wilt verhuizen account_warning_preset: - text: Je kunt voor toots specifieke tekst gebruiken, zoals URL's, hashtags en vermeldingen + text: Je kunt specifieke tekst voor berichten gebruiken, zoals URL's, hashtags en vermeldingen title: Optioneel. Niet zichtbaar voor de ontvanger admin_account_action: - include_statuses: De gebruiker ziet welke toots verantwoordelijk zijn voor de moderatieactie of waarschuwing - send_email_notification: De gebruiker ontvangt een uitleg over wat er met hun account is gebeurd - text_html: Optioneel. Je kunt voor toots specifieke tekst gebruiken. Om tijd te besparen kun je presets voor waarschuwingen toevoegen + include_statuses: De gebruiker ziet welke berichten verantwoordelijk zijn voor de moderatieactie of waarschuwing + send_email_notification: De gebruiker ontvangt een uitleg over wat er met diens account is gebeurd + text_html: Optioneel. Je kunt specifieke tekst voor berichten gebruiken. Om tijd te besparen kun je presets voor waarschuwingen toevoegen type_html: Kies wat er met %{acct} moet gebeuren types: - disable: Voorkom dat de gebruiker hun account gebruikt, maar verwijder of verberg de inhoud niet. + disable: Voorkom dat de gebruiker diens account gebruikt, maar verwijder of verberg de inhoud niet. none: Gebruik dit om een waarschuwing naar de gebruiker te sturen, zonder dat nog een andere actie wordt uitgevoerd. sensitive: Forceer dat alle mediabijlagen van deze gebruiker als gevoelig worden gemarkeerd. - silence: Voorkom dat de gebruiker openbare toots kan versturen, verberg hun toots en meldingen voor mensen die hen niet volgen. + silence: Voorkom dat de gebruiker openbare berichten kan versturen, verberg diens berichten en meldingen voor mensen die diegene niet volgen. suspend: Alle interacties van en met dit account blokkeren en de inhoud verwijderen. Dit kan binnen dertig dagen worden teruggedraaid. warning_preset_id: Optioneel. Je kunt nog steeds handmatig tekst toevoegen aan het eind van de voorinstelling announcement: @@ -26,7 +26,7 @@ nl: ends_at: Optioneel. De publicatie van de mededeling wordt op dit tijdstip automatisch beëindigd scheduled_at: Laat leeg om de mededeling meteen te publiceren starts_at: Optioneel. In het geval dat jouw mededeling aan een bepaald tijdvak is gebonden - text: Je kunt voor toots specifieke tekst gebruiken. Let op de ruimte die de mededeling op het scherm van de gebruiker inneemt + text: Je kunt specifieke tekst voor berichten gebruiken. Let op de ruimte die de mededeling op het scherm van de gebruiker inneemt defaults: autofollow: Mensen die zich via de uitnodiging hebben geregistreerd, volgen jou automatisch avatar: PNG, GIF of JPG. Maximaal %{size}. Wordt teruggeschaald naar %{dimensions}px @@ -39,20 +39,20 @@ nl: fields: Je kan maximaal 4 items als een tabel op je profiel weergeven header: PNG, GIF of JPG. Maximaal %{size}. Wordt teruggeschaald naar %{dimensions}px inbox_url: Kopieer de URL van de voorpagina van de relayserver die je wil gebruiken - irreversible: Gefilterde toots verdwijnen onomkeerbaar, zelfs als de filter later wordt verwijderd + irreversible: Gefilterde berichten verdwijnen onomkeerbaar, zelfs als de filter later wordt verwijderd locale: De taal van de gebruikersomgeving, e-mails en pushmeldingen locked: Door het goedkeuren van volgers handmatig bepalen wie jou mag volgen password: Gebruik tenminste 8 tekens phrase: Komt overeen ongeacht hoofd-/kleine letters of een inhoudswaarschuwing scopes: Tot welke API's heeft de toepassing toegang. Wanneer je een toestemming van het bovenste niveau kiest, hoef je geen individuele toestemmingen meer te kiezen. - setting_aggregate_reblogs: Geen nieuwe boosts tonen voor toots die recentelijk nog zijn geboost (heeft alleen effect op nieuw ontvangen boosts) + setting_aggregate_reblogs: Geen nieuwe boosts tonen voor berichten die recentelijk nog zijn geboost (heeft alleen effect op nieuw ontvangen boosts) setting_default_sensitive: Gevoelige media wordt standaard verborgen en kan met één klik worden getoond setting_display_media_default: Als gevoelig gemarkeerde media verbergen setting_display_media_hide_all: Media altijd verbergen setting_display_media_show_all: Media altijd tonen setting_hide_network: Wie jij volgt en wie jou volgen wordt niet op jouw profiel getoond - setting_noindex: Heeft invloed op jouw openbare profiel en toots - setting_show_application: De toepassing de je gebruikt om te tooten wordt in de gedetailleerde weergave van de toot getoond + setting_noindex: Heeft invloed op jouw openbare profiel en pagina's met berichten + setting_show_application: De toepassing de je gebruikt om berichten te plaatsen wordt in de gedetailleerde weergave van het bericht getoond setting_use_blurhash: Wazige kleurovergangen zijn gebaseerd op de kleuren van de verborgen media, waarmee elk detail verdwijnt setting_use_pending_items: De tijdlijn wordt bijgewerkt door op het aantal nieuwe items te klikken, in plaats van dat deze automatisch wordt bijgewerkt username: Jouw gebruikersnaam is uniek op %{domain} @@ -85,7 +85,7 @@ nl: tag: name: Je kunt elk woord met een hoofdletter beginnen, om zo bijvoorbeeld de tekst leesbaarder te maken user: - chosen_languages: Alleen toots in de aangevinkte talen worden op de openbare tijdlijnen getoond + chosen_languages: Alleen berichten in de aangevinkte talen worden op de openbare tijdlijnen getoond labels: account: fields: @@ -99,7 +99,7 @@ nl: text: Tekst van preset title: Titel admin_account_action: - include_statuses: Gerapporteerde toots aan de e-mail toevoegen + include_statuses: Gerapporteerde berichten aan de e-mail toevoegen send_email_notification: Meld dit per e-mail aan de gebruiker text: Aangepaste waarschuwing type: Actie @@ -146,22 +146,22 @@ nl: setting_advanced_layout: Geavanceerde webomgeving inschakelen setting_aggregate_reblogs: Boosts in tijdlijnen groeperen setting_auto_play_gif: Speel geanimeerde GIF's automatisch af - setting_boost_modal: Vraag voor het boosten van een toot een bevestiging - setting_crop_images: Afbeeldingen bijsnijden tot 16x9 in toots op tijdlijnen - setting_default_language: Taal van jouw toots - setting_default_privacy: Standaardzichtbaarheid van jouw toots + setting_boost_modal: Vraag voor het boosten van een bericht een bevestiging + setting_crop_images: Afbeeldingen bijsnijden tot 16x9 in berichten op tijdlijnen + setting_default_language: Taal van jouw berichten + setting_default_privacy: Zichtbaarheid van nieuwe berichten setting_default_sensitive: Media altijd als gevoelig markeren - setting_delete_modal: Vraag voor het verwijderen van een toot een bevestiging + setting_delete_modal: Vraag voor het verwijderen van een bericht een bevestiging setting_disable_swiping: Swipebewegingen uitschakelen setting_display_media: Mediaweergave setting_display_media_default: Standaard setting_display_media_hide_all: Alles verbergen setting_display_media_show_all: Alles tonen - setting_expand_spoilers: Altijd toots met inhoudswaarschuwingen uitklappen + setting_expand_spoilers: Altijd berichten met inhoudswaarschuwingen uitklappen setting_hide_network: Jouw volgers en wie je volgt verbergen - setting_noindex: Jouw toots niet door zoekmachines laten indexeren + setting_noindex: Jouw berichten niet door zoekmachines laten indexeren setting_reduce_motion: Langzamere animaties - setting_show_application: Toepassing onthullen die je voor het verzenden van toots gebruikt + setting_show_application: Toepassing onthullen die je voor het verzenden van berichten gebruikt setting_system_font_ui: Standaardlettertype van jouw systeem gebruiken setting_theme: Thema website setting_trends: Trends van vandaag tonen @@ -195,19 +195,19 @@ nl: severity: Regel notification_emails: digest: Periodiek e-mails met een samenvatting versturen - favourite: Wanneer iemand jouw toot aan hun favorieten heeft toegevoegd + favourite: Wanneer iemand jouw bericht aan diens favorieten heeft toegevoegd follow: Wanneer iemand jou is gaan volgen follow_request: Wanneer iemand jou wil volgen mention: Wanneer iemand jou heeft vermeld pending_account: Wanneer een nieuw account moet worden beoordeeld - reblog: Wanneer iemand jouw toot heeft geboost + reblog: Wanneer iemand jouw bericht heeft geboost rule: text: Regel tag: listable: Toestaan dat deze hashtag in zoekopdrachten en aanbevelingen te zien valt name: Hashtag trendable: Toestaan dat deze hashtag onder trends te zien valt - usable: Toestaan dat deze hashtag in toots gebruikt mag worden + usable: Toestaan dat deze hashtag in berichten gebruikt mag worden 'no': Nee recommended: Aanbevolen required: diff --git a/config/locales/simple_form.th.yml b/config/locales/simple_form.th.yml index 6127cb9d5..b954b50fe 100644 --- a/config/locales/simple_form.th.yml +++ b/config/locales/simple_form.th.yml @@ -74,7 +74,7 @@ th: text: นี่จะช่วยให้เราตรวจทานใบสมัครของคุณ ip_block: comment: ไม่จำเป็น จดจำเหตุผลที่คุณเพิ่มกฎนี้ - ip: ป้อนที่อยู่ IPv4 หรือ IPv6 คุณสามารถปิดกั้นทั้งช่วงได้โดยใช้ไวยากรณ์ CIDR ระวังอย่าล็อคตัวเองออก! + ip: ป้อนที่อยู่ IPv4 หรือ IPv6 คุณสามารถปิดกั้นทั้งช่วงได้โดยใช้ไวยากรณ์ CIDR ระวังอย่าล็อคตัวคุณเองออก! severities: no_access: ปิดกั้นการเข้าถึงทรัพยากรทั้งหมด sign_up_requires_approval: การลงทะเบียนใหม่จะต้องมีการอนุมัติของคุณ diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 40337ce69..441044516 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -404,6 +404,8 @@ sv: status: Status title: Följ rekommendationer instances: + availability: + warning: Det senaste försöket att ansluta till denna värddator har misslyckats back_to_all: Alla back_to_limited: Begränsat back_to_warning: Varning diff --git a/config/locales/th.yml b/config/locales/th.yml index beafc4da4..d6248b7a8 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -556,6 +556,9 @@ th: other: "%{count} หมายเหตุ" action_log: รายการบันทึกการตรวจสอบ action_taken_by: ใช้การกระทำโดย + actions: + resolve_description_html: จะไม่ใช้การกระทำกับบัญชีที่รายงาน ไม่มีการบันทึกการดำเนินการ และจะปิดรายงาน + actions_description_html: ตัดสินใจว่าการกระทำใดที่จะใช้เพื่อแก้ปัญหารายงานนี้ หากคุณใช้การกระทำที่เป็นการลงโทษกับบัญชีที่รายงาน จะส่งการแจ้งเตือนอีเมลถึงเขา ยกเว้นเมื่อมีการเลือกหมวดหมู่ สแปม are_you_sure: คุณแน่ใจหรือไม่? assign_to_self: มอบหมายให้ฉัน assigned: ผู้ควบคุมที่ได้รับมอบหมาย @@ -883,6 +886,7 @@ th: confirming: กำลังรอการยืนยันอีเมลให้เสร็จสมบูรณ์ functional: บัญชีของคุณทำงานได้อย่างเต็มที่ pending: ใบสมัครของคุณกำลังรอดำเนินการตรวจทานโดยพนักงานของเรา นี่อาจใช้เวลาสักครู่ คุณจะได้รับอีเมลหากใบสมัครของคุณได้รับการอนุมัติ + view_strikes: ดูการดำเนินการที่ผ่านมากับบัญชีของคุณ too_fast: ส่งแบบฟอร์มเร็วเกินไป ลองอีกครั้ง trouble_logging_in: มีปัญหาในการเข้าสู่ระบบ? use_security_key: ใช้กุญแจความปลอดภัย @@ -954,6 +958,7 @@ th: submit: ส่งการอุทธรณ์ associated_report: รายงานที่เกี่ยวข้อง created_at: ลงวันที่ + description_html: นี่คือการกระทำที่ใช้กับบัญชีของคุณและคำเตือนที่ส่งถึงคุณโดยพนักงานของ %{instance} recipient: ส่งถึง status: 'โพสต์ #%{id}' title: "%{action} จาก %{date}" @@ -1410,9 +1415,11 @@ th: user_mailer: appeal_approved: action: ไปยังบัญชีของคุณ + explanation: อนุมัติการอุทธรณ์การดำเนินการกับบัญชีของคุณเมื่อ %{strike_date} ที่คุณได้ส่งเมื่อ %{appeal_date} แล้ว บัญชีของคุณอยู่ในสถานะที่ดีอีกครั้งหนึ่ง subject: อนุมัติการอุทธรณ์ของคุณจาก %{date} แล้ว title: อนุมัติการอุทธรณ์แล้ว appeal_rejected: + explanation: ปฏิเสธการอุทธรณ์การดำเนินการกับบัญชีของคุณเมื่อ %{strike_date} ที่คุณได้ส่งเมื่อ %{appeal_date} แล้ว subject: ปฏิเสธการอุทธรณ์ของคุณจาก %{date} แล้ว title: ปฏิเสธการอุทธรณ์แล้ว backup_ready: @@ -1431,6 +1438,12 @@ th: categories: spam: สแปม violation: เนื้อหาละเมิดหลักเกณฑ์ชุมชนดังต่อไปนี้ + explanation: + delete_statuses: มีการพบว่าบางโพสต์ของคุณละเมิดหนึ่งหลักเกณฑ์ชุมชนหรือมากกว่าและได้รับการเอาออกโดยผู้ควบคุมของ %{instance} ในเวลาต่อมา + disable: คุณไม่สามารถใช้บัญชีของคุณได้อีกต่อไป แต่โปรไฟล์และข้อมูลอื่น ๆ ของคุณยังคงอยู่ในสภาพเดิม คุณสามารถขอข้อมูลสำรองของข้อมูลของคุณ เปลี่ยนการตั้งค่าบัญชี หรือลบบัญชีของคุณ + mark_statuses_as_sensitive: ทำเครื่องหมายบางโพสต์ของคุณว่าละเอียดอ่อนโดยผู้ควบคุมของ %{instance} แล้ว นี่หมายความว่าผู้คนจะต้องแตะสื่อในโพสต์ก่อนที่จะแสดงตัวอย่าง คุณสามารถทำเครื่องหมายสื่อว่าละเอียดอ่อนด้วยตัวคุณเองเมื่อโพสต์ในอนาคต + sensitive: จากนี้ไป จะทำเครื่องหมายไฟล์สื่อที่อัปโหลดทั้งหมดของคุณว่าละเอียดอ่อนและซ่อนอยู่หลังการคลิกไปยังคำเตือน + silence: คุณยังคงสามารถใช้บัญชีของคุณแต่เฉพาะผู้คนที่กำลังติดตามคุณอยู่แล้วเท่านั้นที่จะเห็นโพสต์ของคุณในเซิร์ฟเวอร์นี้ และอาจแยกคุณออกจากคุณลักษณะการค้นพบต่าง ๆ อย่างไรก็ตาม ผู้อื่นอาจยังติดตามคุณด้วยตนเอง reason: 'เหตุผล:' statuses: 'โพสต์ที่อ้างถึง:' subject: diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 6e6477b92..47a55326b 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -490,6 +490,7 @@ tr: other: "%{count} farklı gün başarısız girişim." no_failures_recorded: Kayıtlı başarısızlık yok. title: Ulaşılabilirlik + warning: Bu sunucuya önceki bağlanma denemesi başarısız olmuştu back_to_all: Tümü back_to_limited: Sınırlı back_to_warning: Uyarı diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 6561a5716..6341b4eed 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -479,6 +479,7 @@ zh-CN: other: 在 %{count} 天中尝试失败。 no_failures_recorded: 没有失败记录。 title: 可用性 + warning: 上一次连接到此服务器的尝试失败了 back_to_all: 全部 back_to_limited: 受限 back_to_warning: 警告 diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 43a71a5dd..1b64f9893 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -479,6 +479,7 @@ zh-TW: other: 錯誤嘗試於 %{count} 天。 no_failures_recorded: 報告中沒有錯誤。 title: 可用狀態 + warning: 上一次嘗試連線至本伺服器失敗 back_to_all: 所有 back_to_limited: 受限制的 back_to_warning: 警告 -- cgit From b58db8f12eb19787ee3bd1ec8abab21027b3d4ef Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 25 Mar 2022 19:31:35 +0100 Subject: Add workaround for YouTube Shorts links (#17869) * Add workaround for YouTube Shorts links * Update link_details_extractor_spec.rb --- app/lib/link_details_extractor.rb | 2 +- spec/lib/link_details_extractor_spec.rb | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/lib/link_details_extractor.rb b/app/lib/link_details_extractor.rb index fabbd244d..b0c4e4f42 100644 --- a/app/lib/link_details_extractor.rb +++ b/app/lib/link_details_extractor.rb @@ -208,7 +208,7 @@ class LinkDetailsExtractor end def valid_url_or_nil(str, same_origin_only: false) - return if str.blank? + return if str.blank? || str == 'null' url = @original_url + Addressable::URI.parse(str) diff --git a/spec/lib/link_details_extractor_spec.rb b/spec/lib/link_details_extractor_spec.rb index 84bb4579c..7ea867c61 100644 --- a/spec/lib/link_details_extractor_spec.rb +++ b/spec/lib/link_details_extractor_spec.rb @@ -25,6 +25,14 @@ RSpec.describe LinkDetailsExtractor do expect(subject.canonical_url).to eq 'https://foo.com/article' end end + + context 'when canonical URL is set to "null"' do + let(:html) { '' } + + it 'ignores the canonical URLs' do + expect(subject.canonical_url).to eq original_url + end + end end context 'when structured data is present' do -- cgit From f65eaa5aae8a71431bdcfb9c49c869cbdbc4da3f Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 25 Mar 2022 21:00:59 +0100 Subject: Add admin dashboard checks for Elasticsearch version (#17863) --- app/lib/admin/system_check.rb | 1 + app/lib/admin/system_check/elasticsearch_check.rb | 39 +++++++++++++++++++++++ config/locales/en.yml | 5 +++ 3 files changed, 45 insertions(+) create mode 100644 app/lib/admin/system_check/elasticsearch_check.rb diff --git a/app/lib/admin/system_check.rb b/app/lib/admin/system_check.rb index afb20cb47..877a42ef6 100644 --- a/app/lib/admin/system_check.rb +++ b/app/lib/admin/system_check.rb @@ -5,6 +5,7 @@ class Admin::SystemCheck Admin::SystemCheck::DatabaseSchemaCheck, Admin::SystemCheck::SidekiqProcessCheck, Admin::SystemCheck::RulesCheck, + Admin::SystemCheck::ElasticsearchCheck, ].freeze def self.perform diff --git a/app/lib/admin/system_check/elasticsearch_check.rb b/app/lib/admin/system_check/elasticsearch_check.rb new file mode 100644 index 000000000..1b48a5415 --- /dev/null +++ b/app/lib/admin/system_check/elasticsearch_check.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +class Admin::SystemCheck::ElasticsearchCheck < Admin::SystemCheck::BaseCheck + def pass? + return true unless Chewy.enabled? + + running_version.present? && compatible_version? + end + + def message + if running_version.present? + Admin::SystemCheck::Message.new(:elasticsearch_version_check, I18n.t('admin.system_checks.elasticsearch_version_check.version_comparison', running_version: running_version, required_version: required_version)) + else + Admin::SystemCheck::Message.new(:elasticsearch_running_check) + end + end + + private + + def running_version + @running_version ||= begin + Chewy.client.info['version']['number'] + rescue Faraday::ConnectionFailed + nil + end + end + + def required_version + '7.x' + end + + def compatible_version? + Gem::Version.new(running_version) >= Gem::Version.new(required_version) + end + + def missing_queues + @missing_queues ||= Sidekiq::ProcessSet.new.reduce(SIDEKIQ_QUEUES) { |queues, process| queues - process['queues'] } + end +end diff --git a/config/locales/en.yml b/config/locales/en.yml index a6ded38f7..db29922fa 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -780,6 +780,11 @@ en: 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 + elasticsearch_running_check: + message_html: Could not connect to Elasticsearch. Please check that it is running, or disable full-text search + elasticsearch_version_check: + message_html: "Incompatible Elasticsearch version: %{value}" + version_comparison: "Elasticsearch %{running_version} is running while %{required_version} is required" tags: review: Review status updated_msg: Hashtag settings updated successfully -- cgit From f572a68a0cec49551948858dc0957bc7703e580d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 25 Mar 2022 21:41:17 +0100 Subject: Chore: i18n-tasks normalize (#17873) --- config/locales/en.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index db29922fa..5fa3c012e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -775,16 +775,16 @@ en: system_checks: database_schema_check: message_html: There are pending database migrations. Please run them to ensure the application behaves as expected + elasticsearch_running_check: + message_html: Could not connect to Elasticsearch. Please check that it is running, or disable full-text search + elasticsearch_version_check: + message_html: 'Incompatible Elasticsearch version: %{value}' + version_comparison: Elasticsearch %{running_version} is running while %{required_version} is required rules_check: action: Manage server rules 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 - elasticsearch_running_check: - message_html: Could not connect to Elasticsearch. Please check that it is running, or disable full-text search - elasticsearch_version_check: - message_html: "Incompatible Elasticsearch version: %{value}" - version_comparison: "Elasticsearch %{running_version} is running while %{required_version} is required" tags: review: Review status updated_msg: Hashtag settings updated successfully -- cgit From e3a220306181f9aeda41940bfb11e4350d113e77 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 26 Mar 2022 00:26:50 +0100 Subject: Add offset pagination to trends in REST API (#17872) --- app/controllers/api/v1/trends/links_controller.rb | 26 +++++++++++++++++++++- .../api/v1/trends/statuses_controller.rb | 24 +++++++++++++++++++- app/controllers/api/v1/trends/tags_controller.rb | 26 +++++++++++++++++++++- app/models/trends/query.rb | 4 ++-- 4 files changed, 75 insertions(+), 5 deletions(-) diff --git a/app/controllers/api/v1/trends/links_controller.rb b/app/controllers/api/v1/trends/links_controller.rb index ad20e7f8b..b1cde5a4b 100644 --- a/app/controllers/api/v1/trends/links_controller.rb +++ b/app/controllers/api/v1/trends/links_controller.rb @@ -3,6 +3,10 @@ class Api::V1::Trends::LinksController < Api::BaseController before_action :set_links + after_action :insert_pagination_headers + + DEFAULT_LINKS_LIMIT = 10 + def index render json: @links, each_serializer: REST::Trends::LinkSerializer end @@ -20,6 +24,26 @@ class Api::V1::Trends::LinksController < Api::BaseController end def links_from_trends - Trends.links.query.allowed.in_locale(content_locale).limit(limit_param(10)) + Trends.links.query.allowed.in_locale(content_locale).offset(offset_param).limit(limit_param(DEFAULT_LINKS_LIMIT)) + end + + def insert_pagination_headers + set_pagination_headers(next_path, prev_path) + end + + def pagination_params(core_params) + params.slice(:limit).permit(:limit).merge(core_params) + end + + def next_path + api_v1_trends_links_url pagination_params(offset: offset_param + limit_param(DEFAULT_LINKS_LIMIT)) + end + + def prev_path + api_v1_trends_links_url pagination_params(offset: offset_param - limit_param(DEFAULT_LINKS_LIMIT)) if offset_param > limit_param(DEFAULT_LINKS_LIMIT) + end + + def offset_param + params[:offset].to_i end end diff --git a/app/controllers/api/v1/trends/statuses_controller.rb b/app/controllers/api/v1/trends/statuses_controller.rb index d4ec97ae5..4977803fb 100644 --- a/app/controllers/api/v1/trends/statuses_controller.rb +++ b/app/controllers/api/v1/trends/statuses_controller.rb @@ -3,6 +3,8 @@ class Api::V1::Trends::StatusesController < Api::BaseController before_action :set_statuses + after_action :insert_pagination_headers + def index render json: @statuses, each_serializer: REST::StatusSerializer end @@ -22,6 +24,26 @@ class Api::V1::Trends::StatusesController < Api::BaseController def statuses_from_trends scope = Trends.statuses.query.allowed.in_locale(content_locale) scope = scope.filtered_for(current_account) if user_signed_in? - scope.limit(limit_param(DEFAULT_STATUSES_LIMIT)) + scope.offset(offset_param).limit(limit_param(DEFAULT_STATUSES_LIMIT)) + end + + def insert_pagination_headers + set_pagination_headers(next_path, prev_path) + end + + def pagination_params(core_params) + params.slice(:limit).permit(:limit).merge(core_params) + end + + def next_path + api_v1_trends_statuses_url pagination_params(offset: offset_param + limit_param(DEFAULT_STATUSES_LIMIT)) + end + + def prev_path + api_v1_trends_statuses_url pagination_params(offset: offset_param - limit_param(DEFAULT_STATUSES_LIMIT)) if offset_param > limit_param(DEFAULT_STATUSES_LIMIT) + end + + def offset_param + params[:offset].to_i end end diff --git a/app/controllers/api/v1/trends/tags_controller.rb b/app/controllers/api/v1/trends/tags_controller.rb index 1334b72d2..d77857871 100644 --- a/app/controllers/api/v1/trends/tags_controller.rb +++ b/app/controllers/api/v1/trends/tags_controller.rb @@ -3,6 +3,10 @@ class Api::V1::Trends::TagsController < Api::BaseController before_action :set_tags + after_action :insert_pagination_headers + + DEFAULT_TAGS_LIMIT = 10 + def index render json: @tags, each_serializer: REST::TagSerializer end @@ -12,10 +16,30 @@ class Api::V1::Trends::TagsController < Api::BaseController def set_tags @tags = begin if Setting.trends - Trends.tags.query.allowed.limit(limit_param(10)) + Trends.tags.query.allowed.limit(limit_param(DEFAULT_TAGS_LIMIT)) else [] end end end + + def insert_pagination_headers + set_pagination_headers(next_path, prev_path) + end + + def pagination_params(core_params) + params.slice(:limit).permit(:limit).merge(core_params) + end + + def next_path + api_v1_trends_tags_url pagination_params(offset: offset_param + limit_param(DEFAULT_TAGS_LIMIT)) + end + + def prev_path + api_v1_trends_tags_url pagination_params(offset: offset_param - limit_param(DEFAULT_TAGS_LIMIT)) if offset_param > limit_param(DEFAULT_TAGS_LIMIT) + end + + def offset_param + params[:offset].to_i + end end diff --git a/app/models/trends/query.rb b/app/models/trends/query.rb index 64a4c0c1f..231b65228 100644 --- a/app/models/trends/query.rb +++ b/app/models/trends/query.rb @@ -37,7 +37,7 @@ class Trends::Query end def offset!(value) - @offset = value + @offset = value.to_i self end @@ -46,7 +46,7 @@ class Trends::Query end def limit!(value) - @limit = value + @limit = value.to_i self end -- cgit From 71f2b95106b2e75d3efb40040b29c216c2d99ee6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 26 Mar 2022 00:38:44 +0100 Subject: Fix edits with no actual changes being allowed (#17843) * Fix edits with no actual changes being allowed locally * Fix edits with no actual changes being allowed through ActivityPub * Fix false positive changes caused by description processing in model * Fix not recording poll expiration update * Fix test * Revert changes to ProcessStatusUpdateService * Various fixes and improvements * Fix code style issues * Various changes and improvements * Add guard clause --- .../activitypub/parser/media_attachment_parser.rb | 4 ++- app/models/concerns/status_snapshot_concern.rb | 35 ++++++++++++++++++++++ app/models/media_attachment.rb | 7 +---- app/models/status.rb | 21 +------------ .../activitypub/process_status_update_service.rb | 22 +++++++------- app/services/update_status_service.rb | 28 ++++++++++++++--- spec/models/media_attachment_spec.rb | 8 ----- .../process_status_update_service_spec.rb | 31 +++++++++++++++++-- spec/services/update_status_service_spec.rb | 17 +++++++++++ 9 files changed, 121 insertions(+), 52 deletions(-) create mode 100644 app/models/concerns/status_snapshot_concern.rb diff --git a/app/lib/activitypub/parser/media_attachment_parser.rb b/app/lib/activitypub/parser/media_attachment_parser.rb index 1798e58a4..30bea1f0e 100644 --- a/app/lib/activitypub/parser/media_attachment_parser.rb +++ b/app/lib/activitypub/parser/media_attachment_parser.rb @@ -27,7 +27,9 @@ class ActivityPub::Parser::MediaAttachmentParser end def description - @json['summary'].presence || @json['name'].presence + str = @json['summary'].presence || @json['name'].presence + str = str.strip[0...MediaAttachment::MAX_DESCRIPTION_LENGTH] if str.present? + str end def focus diff --git a/app/models/concerns/status_snapshot_concern.rb b/app/models/concerns/status_snapshot_concern.rb new file mode 100644 index 000000000..9741b9aeb --- /dev/null +++ b/app/models/concerns/status_snapshot_concern.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module StatusSnapshotConcern + extend ActiveSupport::Concern + + included do + has_many :edits, class_name: 'StatusEdit', inverse_of: :status, dependent: :destroy + end + + def edited? + edited_at.present? + end + + def build_snapshot(account_id: nil, at_time: nil, rate_limit: true) + # We don't use `edits#new` here to avoid it having saved when the + # status is saved, since we want to control that manually + + StatusEdit.new( + status_id: id, + text: text, + spoiler_text: spoiler_text, + sensitive: sensitive, + ordered_media_attachment_ids: ordered_media_attachment_ids&.dup || media_attachments.pluck(:id), + media_descriptions: ordered_media_attachments.map(&:description), + poll_options: preloadable_poll&.options&.dup, + account_id: account_id || self.account_id, + created_at: at_time || edited_at, + rate_limit: rate_limit + ) + end + + def snapshot!(**options) + build_snapshot(**options).save! + end +end diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb index a3115637e..21c663e47 100644 --- a/app/models/media_attachment.rb +++ b/app/models/media_attachment.rb @@ -185,7 +185,7 @@ class MediaAttachment < ApplicationRecord remotable_attachment :thumbnail, IMAGE_LIMIT, suppress_errors: true, download_on_assign: false validates :account, presence: true - validates :description, length: { maximum: MAX_DESCRIPTION_LENGTH }, if: :local? + validates :description, length: { maximum: MAX_DESCRIPTION_LENGTH } validates :file, presence: true, if: :local? validates :thumbnail, absence: true, if: -> { local? && !audio_or_video? } @@ -258,7 +258,6 @@ class MediaAttachment < ApplicationRecord after_commit :enqueue_processing, on: :create after_commit :reset_parent_cache, on: :update - before_create :prepare_description, unless: :local? before_create :set_unknown_type before_create :set_processing @@ -306,10 +305,6 @@ class MediaAttachment < ApplicationRecord self.type = :unknown if file.blank? && !type_changed? end - def prepare_description - self.description = description.strip[0...MAX_DESCRIPTION_LENGTH] unless description.nil? - end - def set_type_and_extension self.type = begin if VIDEO_MIME_TYPES.include?(file_content_type) diff --git a/app/models/status.rb b/app/models/status.rb index 5b984543e..bf5a49b7f 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -35,6 +35,7 @@ class Status < ApplicationRecord include Paginable include Cacheable include StatusThreadingConcern + include StatusSnapshotConcern include RateLimitable rate_limit by: :account, family: :statuses @@ -59,8 +60,6 @@ class Status < ApplicationRecord belongs_to :thread, foreign_key: 'in_reply_to_id', class_name: 'Status', inverse_of: :replies, optional: true belongs_to :reblog, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblogs, optional: true - has_many :edits, class_name: 'StatusEdit', inverse_of: :status, dependent: :destroy - has_many :favourites, inverse_of: :status, dependent: :destroy has_many :bookmarks, inverse_of: :status, dependent: :destroy has_many :reblogs, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblog, dependent: :destroy @@ -212,24 +211,6 @@ class Status < ApplicationRecord public_visibility? || unlisted_visibility? end - def snapshot!(account_id: nil, at_time: nil, rate_limit: true) - edits.create!( - text: text, - spoiler_text: spoiler_text, - sensitive: sensitive, - ordered_media_attachment_ids: ordered_media_attachment_ids || media_attachments.pluck(:id), - media_descriptions: ordered_media_attachments.map(&:description), - poll_options: preloadable_poll&.options, - account_id: account_id || self.account_id, - created_at: at_time || edited_at, - rate_limit: rate_limit - ) - end - - def edited? - edited_at.present? - end - alias sign? distributable? def with_media? diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb index 47a788c30..6dc14d8c2 100644 --- a/app/services/activitypub/process_status_update_service.rb +++ b/app/services/activitypub/process_status_update_service.rb @@ -4,6 +4,8 @@ class ActivityPub::ProcessStatusUpdateService < BaseService include JsonLdHelper def call(status, json) + raise ArgumentError, 'Status has unsaved changes' if status.changed? + @json = json @status_parser = ActivityPub::Parser::StatusParser.new(@json) @uri = @status_parser.uri @@ -17,16 +19,19 @@ class ActivityPub::ProcessStatusUpdateService < BaseService last_edit_date = status.edited_at.presence || status.created_at + # Since we rely on tracking of previous changes, ensure clean slate + status.clear_changes_information + # Only allow processing one create/update per status at a time RedisLock.acquire(lock_options) do |lock| if lock.acquired? Status.transaction do - create_previous_edit! + record_previous_edit! update_media_attachments! update_poll! update_immediate_attributes! update_metadata! - create_edit! + create_edits! end queue_poll_notifications! @@ -216,19 +221,14 @@ class ActivityPub::ProcessStatusUpdateService < BaseService { redis: Redis.current, key: "create:#{@uri}", autorelease: 15.minutes.seconds } end - def create_previous_edit! - # We only need to create a previous edit when no previous edits exist, e.g. - # when the status has never been edited. For other cases, we always create - # an edit, so the step can be skipped - - return if @status.edits.any? - - @status.snapshot!(at_time: @status.created_at, rate_limit: false) + def record_previous_edit! + @previous_edit = @status.build_snapshot(at_time: @status.created_at, rate_limit: false) if @status.edits.empty? end - def create_edit! + def create_edits! return unless significant_changes? + @previous_edit&.save! @status.snapshot!(account_id: @account.id, rate_limit: false) end diff --git a/app/services/update_status_service.rb b/app/services/update_status_service.rb index 055e5968d..c4c934976 100644 --- a/app/services/update_status_service.rb +++ b/app/services/update_status_service.rb @@ -4,6 +4,8 @@ class UpdateStatusService < BaseService include Redisable include LanguagesHelper + class NoChangesSubmittedError < StandardError; end + # @param [Status] status # @param [Integer] account_id # @param [Hash] options @@ -17,6 +19,8 @@ class UpdateStatusService < BaseService @status = status @options = options @account_id = account_id + @media_attachments_changed = false + @poll_changed = false Status.transaction do create_previous_edit! @@ -32,18 +36,24 @@ class UpdateStatusService < BaseService broadcast_updates! @status + rescue NoChangesSubmittedError + # For calls that result in no changes, swallow the error + # but get back to the original state + + @status.reload end private def update_media_attachments! - previous_media_attachments = @status.media_attachments.to_a + previous_media_attachments = @status.ordered_media_attachments.to_a next_media_attachments = validate_media! added_media_attachments = next_media_attachments - previous_media_attachments MediaAttachment.where(id: added_media_attachments.map(&:id)).update_all(status_id: @status.id) @status.ordered_media_attachment_ids = (@options[:media_ids] || []).map(&:to_i) & next_media_attachments.map(&:id) + @media_attachments_changed = previous_media_attachments.map(&:id) != @status.ordered_media_attachment_ids @status.media_attachments.reload end @@ -69,20 +79,23 @@ class UpdateStatusService < BaseService # If for some reasons the options were changed, it invalidates all previous # votes, so we need to remove them - poll_changed = true if @options[:poll][:options] != poll.options || ActiveModel::Type::Boolean.new.cast(@options[:poll][:multiple]) != poll.multiple + @poll_changed = true if @options[:poll][:options] != poll.options || ActiveModel::Type::Boolean.new.cast(@options[:poll][:multiple]) != poll.multiple poll.options = @options[:poll][:options] poll.hide_totals = @options[:poll][:hide_totals] || false poll.multiple = @options[:poll][:multiple] || false poll.expires_in = @options[:poll][:expires_in] - poll.reset_votes! if poll_changed + poll.reset_votes! if @poll_changed poll.save! @status.poll_id = poll.id elsif previous_poll.present? previous_poll.destroy + @poll_changed = true @status.poll_id = nil end + + @poll_changed = true if @previous_expires_at != @status.preloadable_poll&.expires_at end def update_immediate_attributes! @@ -90,8 +103,11 @@ class UpdateStatusService < BaseService @status.spoiler_text = @options[:spoiler_text] || '' if @options.key?(:spoiler_text) @status.sensitive = @options[:sensitive] || @options[:spoiler_text].present? if @options.key?(:sensitive) || @options.key?(:spoiler_text) @status.language = valid_locale_cascade(@options[:language], @status.language, @status.account.user&.preferred_posting_language, I18n.default_locale) - @status.edited_at = Time.now.utc + # We raise here to rollback the entire transaction + raise NoChangesSubmittedError unless significant_changes? + + @status.edited_at = Time.now.utc @status.save! end @@ -137,4 +153,8 @@ class UpdateStatusService < BaseService def create_edit! @status.snapshot!(account_id: @account_id) end + + def significant_changes? + @status.changed? || @poll_changed || @media_attachments_changed + end end diff --git a/spec/models/media_attachment_spec.rb b/spec/models/media_attachment_spec.rb index 7360b23cf..cbd9a09c5 100644 --- a/spec/models/media_attachment_spec.rb +++ b/spec/models/media_attachment_spec.rb @@ -186,14 +186,6 @@ RSpec.describe MediaAttachment, type: :model do expect(media.valid?).to be false end - describe 'descriptions for remote attachments' do - it 'are cut off at 1500 characters' do - media = Fabricate(:media_attachment, description: 'foo' * 1000, remote_url: 'http://example.com/blah.jpg') - - expect(media.description.size).to be <= 1_500 - end - end - describe 'size limit validation' do it 'rejects video files that are too large' do stub_const 'MediaAttachment::IMAGE_LIMIT', 100.megabytes diff --git a/spec/services/activitypub/process_status_update_service_spec.rb b/spec/services/activitypub/process_status_update_service_spec.rb index 788c7c9d9..f87adcae1 100644 --- a/spec/services/activitypub/process_status_update_service_spec.rb +++ b/spec/services/activitypub/process_status_update_service_spec.rb @@ -46,6 +46,29 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do expect(status.reload.spoiler_text).to eq 'Show more' end + context 'with no changes at all' do + let(:payload) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + id: 'foo', + type: 'Note', + content: 'Hello world', + } + end + + before do + subject.call(status, json) + end + + it 'does not create any edits' do + expect(status.reload.edits).to be_empty + end + + it 'does not mark status as edited' do + expect(status.edited?).to be false + end + end + context 'with no changes and originally with no ordered_media_attachment_ids' do let(:payload) do { @@ -61,8 +84,12 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do subject.call(status, json) end - it 'does not record an update' do - expect(status.reload.edited?).to be false + it 'does not create any edits' do + expect(status.reload.edits).to be_empty + end + + it 'does not mark status as edited' do + expect(status.edited?).to be false end end diff --git a/spec/services/update_status_service_spec.rb b/spec/services/update_status_service_spec.rb index 78cc89cd4..71a73be5b 100644 --- a/spec/services/update_status_service_spec.rb +++ b/spec/services/update_status_service_spec.rb @@ -3,6 +3,23 @@ require 'rails_helper' RSpec.describe UpdateStatusService, type: :service do subject { described_class.new } + context 'when nothing changes' do + let!(:status) { Fabricate(:status, text: 'Foo', language: 'en') } + + before do + allow(ActivityPub::DistributionWorker).to receive(:perform_async) + 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) + end + end + context 'when text changes' do let!(:status) { Fabricate(:status, text: 'Foo') } let(:preview_card) { Fabricate(:preview_card) } -- cgit From 6907605026a5d46acf8a5f3aaf5384807c1d8d3c Mon Sep 17 00:00:00 2001 From: Jeong Arm Date: Sat, 26 Mar 2022 08:39:54 +0900 Subject: Add stop delivery link also for failing instance (#17871) --- app/views/admin/instances/show.html.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/admin/instances/show.html.haml b/app/views/admin/instances/show.html.haml index 70912a4f5..ef4de602d 100644 --- a/app/views/admin/instances/show.html.haml +++ b/app/views/admin/instances/show.html.haml @@ -87,7 +87,8 @@ - else %span.negative-hint = t('admin.instances.availability.failures_recorded', count: @instance.delivery_failure_tracker.days) - = 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.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') -- cgit From 52813830bee5607332b49bee2916956286ec5dc1 Mon Sep 17 00:00:00 2001 From: mayaeh Date: Sat, 26 Mar 2022 10:52:51 +0900 Subject: Add a hashtag public link to the trending hashtag page (#17140) * Add a hashtag public link to the hashtag management page * Add support for element 'target' to Counter.js. Remove 'rel' element. * Update app/javascript/mastodon/components/admin/Counter.js Co-authored-by: Claire Co-authored-by: Eugen Rochko Co-authored-by: Claire --- app/javascript/mastodon/components/admin/Counter.js | 5 +++-- app/views/admin/tags/show.html.haml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/javascript/mastodon/components/admin/Counter.js b/app/javascript/mastodon/components/admin/Counter.js index 6edb7bcfc..5a5b2b869 100644 --- a/app/javascript/mastodon/components/admin/Counter.js +++ b/app/javascript/mastodon/components/admin/Counter.js @@ -33,6 +33,7 @@ export default class Counter extends React.PureComponent { label: PropTypes.string.isRequired, href: PropTypes.string, params: PropTypes.object, + target: PropTypes.string, }; state = { @@ -54,7 +55,7 @@ export default class Counter extends React.PureComponent { } render () { - const { label, href } = this.props; + const { label, href, target } = this.props; const { loading, data } = this.state; let content; @@ -100,7 +101,7 @@ export default class Counter extends React.PureComponent { if (href) { return ( - + {inner} ); diff --git a/app/views/admin/tags/show.html.haml b/app/views/admin/tags/show.html.haml index 007dc005e..df72bd5f5 100644 --- a/app/views/admin/tags/show.html.haml +++ b/app/views/admin/tags/show.html.haml @@ -11,7 +11,7 @@ .dashboard .dashboard__item - = react_admin_component :counter, measure: 'tag_accounts', start_at: @time_period.first, end_at: @time_period.last, params: { id: @tag.id }, label: t('admin.trends.tags.dashboard.tag_accounts_measure') + = react_admin_component :counter, measure: 'tag_accounts', start_at: @time_period.first, end_at: @time_period.last, params: { id: @tag.id }, label: t('admin.trends.tags.dashboard.tag_accounts_measure'), href: tag_url(@tag), target: '_blank' .dashboard__item = react_admin_component :counter, measure: 'tag_uses', start_at: @time_period.first, end_at: @time_period.last, params: { id: @tag.id }, label: t('admin.trends.tags.dashboard.tag_uses_measure') .dashboard__item -- cgit From 2dd30804b62f750c2780b7043318cbe00d137429 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 26 Mar 2022 02:53:13 +0100 Subject: Change how unconfirmed accounts are displayed in admin UI (#17874) Fix #17815 --- app/models/account.rb | 2 +- app/models/user.rb | 6 +++++- app/views/admin/accounts/_account.html.haml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/models/account.rb b/app/models/account.rb index 1717f1605..a8c5df208 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -128,13 +128,13 @@ class Account < ApplicationRecord :approved?, :pending?, :disabled?, + :unconfirmed?, :unconfirmed_or_pending?, :role, :admin?, :moderator?, :staff?, :locale, - :hides_network?, :shows_application?, to: :user, prefix: true, diff --git a/app/models/user.rb b/app/models/user.rb index 146bdcd2a..f2d9c49eb 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -208,8 +208,12 @@ class User < ApplicationRecord confirmed? && approved? && !disabled? && !account.suspended? && !account.memorial? && account.moved_to_account_id.nil? end + def unconfirmed? + !confirmed? + end + def unconfirmed_or_pending? - !(confirmed? && approved?) + unconfirmed? || pending? end def inactive_message diff --git a/app/views/admin/accounts/_account.html.haml b/app/views/admin/accounts/_account.html.haml index 2df91301e..82dd8dfb2 100644 --- a/app/views/admin/accounts/_account.html.haml +++ b/app/views/admin/accounts/_account.html.haml @@ -1,4 +1,4 @@ -.batch-table__row{ class: [!account.suspended? && account.user_pending? && 'batch-table__row--attention', account.suspended? && 'batch-table__row--muted'] } +.batch-table__row{ class: [!account.suspended? && account.user_pending? && 'batch-table__row--attention', (account.suspended? || account.user_unconfirmed?) && 'batch-table__row--muted'] } %label.batch-table__row__select.batch-table__row__select--aligned.batch-checkbox = f.check_box :account_ids, { multiple: true, include_hidden: false }, account.id .batch-table__row__content.batch-table__row__content--unpadded -- cgit From cefa526c6d3a45df2d0fcb7643ced828e2e87dea Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 26 Mar 2022 02:53:34 +0100 Subject: Refactor formatter (#17828) * Refactor formatter * Move custom emoji pre-rendering logic to view helpers * Move more methods out of Formatter * Fix code style issues * Remove Formatter * Add inline poll options to RSS feeds * Remove unused helper method * Fix code style issues * Various fixes and improvements * Fix test --- app/chewy/statuses_index.rb | 2 +- app/controllers/api/web/embeds_controller.rb | 2 +- app/helpers/accounts_helper.rb | 6 +- app/helpers/admin/trends/statuses_helper.rb | 5 +- app/helpers/application_helper.rb | 4 + app/helpers/formatting_helper.rb | 19 + app/helpers/routing_helper.rb | 3 +- app/helpers/statuses_helper.rb | 14 - app/lib/activitypub/activity/create.rb | 4 +- app/lib/emoji_formatter.rb | 98 ++++ app/lib/extractor.rb | 82 +++- app/lib/feed_manager.rb | 3 +- app/lib/formatter.rb | 294 ----------- app/lib/html_aware_formatter.rb | 38 ++ app/lib/plain_text_formatter.rb | 30 ++ app/lib/rss/serializer.rb | 23 +- app/lib/text_formatter.rb | 158 ++++++ app/mailers/application_mailer.rb | 1 + app/serializers/activitypub/actor_serializer.rb | 7 +- app/serializers/activitypub/note_serializer.rb | 6 +- app/serializers/rest/account_serializer.rb | 7 +- app/serializers/rest/announcement_serializer.rb | 4 +- app/serializers/rest/status_edit_serializer.rb | 4 +- app/serializers/rest/status_serializer.rb | 4 +- app/services/fetch_link_card_service.rb | 2 +- app/views/accounts/_bio.html.haml | 6 +- app/views/admin/accounts/show.html.haml | 6 +- app/views/admin/reports/_status.html.haml | 6 +- app/views/admin/reports/show.html.haml | 2 +- app/views/directories/index.html.haml | 2 +- app/views/disputes/strikes/show.html.haml | 2 +- app/views/notification_mailer/_status.html.haml | 4 +- app/views/notification_mailer/_status.text.erb | 2 +- app/views/notification_mailer/digest.text.erb | 2 +- app/views/statuses/_detailed_status.html.haml | 5 +- app/views/statuses/_poll.html.haml | 4 +- app/views/statuses/_simple_status.html.haml | 5 +- app/views/user_mailer/warning.html.haml | 2 +- config/initializers/twitter_regex.rb | 26 - spec/lib/emoji_formatter_spec.rb | 55 +++ spec/lib/formatter_spec.rb | 626 ------------------------ spec/lib/html_aware_formatter.rb | 44 ++ spec/lib/plain_text_formatter_spec.rb | 24 + spec/lib/text_formatter_spec.rb | 313 ++++++++++++ 44 files changed, 932 insertions(+), 1024 deletions(-) create mode 100644 app/helpers/formatting_helper.rb create mode 100644 app/lib/emoji_formatter.rb delete mode 100644 app/lib/formatter.rb create mode 100644 app/lib/html_aware_formatter.rb create mode 100644 app/lib/plain_text_formatter.rb create mode 100644 app/lib/text_formatter.rb create mode 100644 spec/lib/emoji_formatter_spec.rb delete mode 100644 spec/lib/formatter_spec.rb create mode 100644 spec/lib/html_aware_formatter.rb create mode 100644 spec/lib/plain_text_formatter_spec.rb create mode 100644 spec/lib/text_formatter_spec.rb diff --git a/app/chewy/statuses_index.rb b/app/chewy/statuses_index.rb index 65cbb6fcd..d119f7cac 100644 --- a/app/chewy/statuses_index.rb +++ b/app/chewy/statuses_index.rb @@ -57,7 +57,7 @@ class StatusesIndex < Chewy::Index field :id, type: 'long' field :account_id, type: 'long' - field :text, type: 'text', value: ->(status) { [status.spoiler_text, Formatter.instance.plaintext(status)].concat(status.ordered_media_attachments.map(&:description)).concat(status.preloadable_poll ? status.preloadable_poll.options : []).join("\n\n") } do + field :text, type: 'text', value: ->(status) { [status.spoiler_text, PlainTextFormatter.new(status.text, status.local?).to_s].concat(status.ordered_media_attachments.map(&:description)).concat(status.preloadable_poll ? status.preloadable_poll.options : []).join("\n\n") } do field :stemmed, type: 'text', analyzer: 'content' end diff --git a/app/controllers/api/web/embeds_controller.rb b/app/controllers/api/web/embeds_controller.rb index 741ba910f..58f6345e6 100644 --- a/app/controllers/api/web/embeds_controller.rb +++ b/app/controllers/api/web/embeds_controller.rb @@ -15,7 +15,7 @@ class Api::Web::EmbedsController < Api::Web::BaseController return not_found if oembed.nil? begin - oembed[:html] = Formatter.instance.sanitize(oembed[:html], Sanitize::Config::MASTODON_OEMBED) + oembed[:html] = Sanitize.fragment(oembed[:html], Sanitize::Config::MASTODON_OEMBED) rescue ArgumentError return not_found end diff --git a/app/helpers/accounts_helper.rb b/app/helpers/accounts_helper.rb index a33961724..557f60f26 100644 --- a/app/helpers/accounts_helper.rb +++ b/app/helpers/accounts_helper.rb @@ -2,10 +2,12 @@ module AccountsHelper def display_name(account, **options) + str = account.display_name.presence || account.username + if options[:custom_emojify] - Formatter.instance.format_display_name(account, **options) + prerender_custom_emojis(h(str), account.emojis) else - account.display_name.presence || account.username + str end end diff --git a/app/helpers/admin/trends/statuses_helper.rb b/app/helpers/admin/trends/statuses_helper.rb index d16e3dd12..214c1e2a6 100644 --- a/app/helpers/admin/trends/statuses_helper.rb +++ b/app/helpers/admin/trends/statuses_helper.rb @@ -12,9 +12,6 @@ module Admin::Trends::StatusesHelper return '' if text.blank? - html = Formatter.instance.send(:encode, text) - html = Formatter.instance.send(:encode_custom_emojis, html, status.emojis, prefers_autoplay?) - - html.html_safe # rubocop:disable Rails/OutputSafety + prerender_custom_emojis(h(text), status.emojis) end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index e997570b5..651a98a85 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -239,4 +239,8 @@ module ApplicationHelper end end.values end + + def prerender_custom_emojis(html, custom_emojis) + EmojiFormatter.new(html, custom_emojis, animate: prefers_autoplay?).to_s + end end diff --git a/app/helpers/formatting_helper.rb b/app/helpers/formatting_helper.rb new file mode 100644 index 000000000..66e9e1e91 --- /dev/null +++ b/app/helpers/formatting_helper.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module FormattingHelper + def html_aware_format(text, local, options = {}) + HtmlAwareFormatter.new(text, local, options).to_s + end + + def linkify(text, options = {}) + TextFormatter.new(text, options).to_s + end + + def extract_plain_text(text, local) + PlainTextFormatter.new(text, local).to_s + end + + def status_content_format(status) + html_aware_format(status.text, status.local?, preloaded_accounts: [status.account] + (status.respond_to?(:active_mentions) ? status.active_mentions.map(&:account) : [])) + end +end diff --git a/app/helpers/routing_helper.rb b/app/helpers/routing_helper.rb index fb24a1b28..f95f46a56 100644 --- a/app/helpers/routing_helper.rb +++ b/app/helpers/routing_helper.rb @@ -2,6 +2,7 @@ module RoutingHelper extend ActiveSupport::Concern + include Rails.application.routes.url_helpers include ActionView::Helpers::AssetTagHelper include Webpacker::Helper @@ -22,8 +23,6 @@ module RoutingHelper full_asset_url(asset_pack_path(source, **options)) end - private - def use_storage? Rails.configuration.x.use_s3 || Rails.configuration.x.use_swift end diff --git a/app/helpers/statuses_helper.rb b/app/helpers/statuses_helper.rb index d328f89b7..e92b4c839 100644 --- a/app/helpers/statuses_helper.rb +++ b/app/helpers/statuses_helper.rb @@ -113,20 +113,6 @@ module StatusesHelper end end - private - - def simplified_text(text) - text.dup.tap do |new_text| - URI.extract(new_text).each do |url| - new_text.gsub!(url, '') - end - - new_text.gsub!(Account::MENTION_RE, '') - new_text.gsub!(Tag::HASHTAG_RE, '') - new_text.gsub!(/\s+/, '') - end - end - def embedded_view? params[:controller] == EMBEDDED_CONTROLLER && params[:action] == EMBEDDED_ACTION end diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index ea8d146d4..f4f98e29c 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class ActivityPub::Activity::Create < ActivityPub::Activity + include FormattingHelper + def perform dereference_object! @@ -367,7 +369,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity end def converted_text - Formatter.instance.linkify([@status_parser.title.presence, @status_parser.spoiler_text.presence, @status_parser.url || @status_parser.uri].compact.join("\n\n")) + linkify([@status_parser.title.presence, @status_parser.spoiler_text.presence, @status_parser.url || @status_parser.uri].compact.join("\n\n")) end def unsupported_media_type?(mime_type) diff --git a/app/lib/emoji_formatter.rb b/app/lib/emoji_formatter.rb new file mode 100644 index 000000000..f808f3a22 --- /dev/null +++ b/app/lib/emoji_formatter.rb @@ -0,0 +1,98 @@ +# frozen_string_literal: true + +class EmojiFormatter + include RoutingHelper + + DISALLOWED_BOUNDING_REGEX = /[[:alnum:]:]/.freeze + + attr_reader :html, :custom_emojis, :options + + # @param [ActiveSupport::SafeBuffer] html + # @param [Array] custom_emojis + # @param [Hash] options + # @option options [Boolean] :animate + def initialize(html, custom_emojis, options = {}) + raise ArgumentError unless html.html_safe? + + @html = html + @custom_emojis = custom_emojis + @options = options + end + + def to_s + return html if custom_emojis.empty? || html.blank? + + i = -1 + tag_open_index = nil + inside_shortname = false + shortname_start_index = -1 + invisible_depth = 0 + last_index = 0 + result = ''.dup + + while i + 1 < html.size + i += 1 + + if invisible_depth.zero? && inside_shortname && html[i] == ':' + inside_shortname = false + shortcode = html[shortname_start_index + 1..i - 1] + char_after = html[i + 1] + + next unless (char_after.nil? || !DISALLOWED_BOUNDING_REGEX.match?(char_after)) && (emoji = emoji_map[shortcode]) + + result << html[last_index..shortname_start_index - 1] if shortname_start_index.positive? + result << image_for_emoji(shortcode, emoji) + last_index = i + 1 + elsif tag_open_index && html[i] == '>' + tag = html[tag_open_index..i] + tag_open_index = nil + + if invisible_depth.positive? + invisible_depth += count_tag_nesting(tag) + elsif tag == '' - end - end - - context 'given a post containing unlinkable mentions' do - let(:status) { Fabricate(:status, text: '@alice', uri: nil) } - - it 'does not create a mention link' do - is_expected.to include '@alice' - end - end - - context do - subject do - status = Fabricate(:status, text: text, uri: nil) - Formatter.instance.format(status) - end - - include_examples 'encode and link URLs' - end - - context 'given a post with custom_emojify option' do - let!(:emoji) { Fabricate(:custom_emoji) } - let(:status) { Fabricate(:status, account: local_account, text: text) } - - subject { Formatter.instance.format(status, custom_emojify: true) } - - context 'given a post with an emoji shortcode at the start' do - let(:text) { ':coolcat: Beep boop' } - - it 'converts the shortcode to an image tag' do - is_expected.to match(/

:coolcat::coolcat: Beep boop
' } - - it 'converts the shortcode to an image tag' do - is_expected.to match(/

:coolcat:Beep :coolcat: boop

' } - - it 'converts the shortcode to an image tag' do - is_expected.to match(/Beep :coolcat::coolcat::coolcat:

' } - - it 'does not touch the shortcodes' do - is_expected.to match(/

:coolcat::coolcat:<\/p>/) - end - end - - context 'given a post with an emoji shortcode at the end' do - let(:text) { '

Beep boop
:coolcat:

' } - - it 'converts the shortcode to an image tag' do - is_expected.to match(/
:coolcat:alert("Hello")' } - - it 'strips the scripts' do - is_expected.to_not include '' - end - end - - context 'given a post containing malicious classes' do - let(:text) { 'Show more' } - - it 'strips the malicious classes' do - is_expected.to_not include 'status__content__spoiler-link' - end - end - end - - describe '#plaintext' do - subject { Formatter.instance.plaintext(status) } - - context 'given a post with local status' do - let(:status) { Fabricate(:status, text: '

a text by a nerd who uses an HTML tag in text

', uri: nil) } - - it 'returns the raw text' do - is_expected.to eq '

a text by a nerd who uses an HTML tag in text

' - end - end - - context 'given a post with remote status' do - let(:status) { Fabricate(:status, account: remote_account, text: '') } - - it 'returns tag-stripped text' do - is_expected.to eq '' - end - end - end - - describe '#simplified_format' do - subject { Formatter.instance.simplified_format(account) } - - context 'given a post with local status' do - let(:account) { Fabricate(:account, domain: nil, note: text) } - - context 'given a post containing linkable mentions for local accounts' do - let(:text) { '@alice' } - - before { local_account } - - it 'creates a mention link' do - is_expected.to eq '

@alice

' - end - end - - context 'given a post containing linkable mentions for remote accounts' do - let(:text) { '@bob@remote.test' } - - before { remote_account } - - it 'creates a mention link' do - is_expected.to eq '

@bob

' - end - end - - context 'given a post containing unlinkable mentions' do - let(:text) { '@alice' } - - it 'does not create a mention link' do - is_expected.to eq '

@alice

' - end - end - - context 'given a post with custom_emojify option' do - let!(:emoji) { Fabricate(:custom_emoji) } - - before { account.note = text } - subject { Formatter.instance.simplified_format(account, custom_emojify: true) } - - context 'given a post with an emoji shortcode at the start' do - let(:text) { ':coolcat: Beep boop' } - - it 'converts the shortcode to an image tag' do - is_expected.to match(/

:coolcat:alert("Hello")' } - let(:account) { Fabricate(:account, domain: 'remote', note: text) } - - it 'reformats' do - is_expected.to_not include '' - end - - context 'with custom_emojify option' do - let!(:emoji) { Fabricate(:custom_emoji, domain: remote_account.domain) } - - before { remote_account.note = text } - - subject { Formatter.instance.simplified_format(remote_account, custom_emojify: true) } - - context 'given a post with an emoji shortcode at the start' do - let(:text) { '

:coolcat: Beep boop
' } - - it 'converts shortcode to image tag' do - is_expected.to match(/

:coolcat:Beep :coolcat: boop

' } - - it 'converts shortcode to image tag' do - is_expected.to match(/Beep :coolcat::coolcat::coolcat:

' } - - it 'does not touch the shortcodes' do - is_expected.to match(/

:coolcat::coolcat:<\/p>/) - end - end - - context 'given a post with an emoji shortcode at the end' do - let(:text) { '

Beep boop
:coolcat:

' } - - it 'converts shortcode to image tag' do - is_expected.to match(/
:coolcat:alert("Hello")' } - - subject { Formatter.instance.sanitize(html, Sanitize::Config::MASTODON_STRICT) } - - it 'sanitizes' do - is_expected.to eq '' - end - end -end diff --git a/spec/lib/html_aware_formatter.rb b/spec/lib/html_aware_formatter.rb new file mode 100644 index 000000000..18d23abf5 --- /dev/null +++ b/spec/lib/html_aware_formatter.rb @@ -0,0 +1,44 @@ +require 'rails_helper' + +RSpec.describe HtmlAwareFormatter do + describe '#to_s' do + subject { described_class.new(text, local).to_s } + + context 'when local' do + let(:local) { true } + let(:text) { 'Foo bar' } + + it 'returns formatted text' do + is_expected.to eq '

Foo bar

' + end + end + + context 'when remote' do + let(:local) { false } + + context 'given plain text' do + let(:text) { 'Beep boop' } + + it 'keeps the plain text' do + is_expected.to include 'Beep boop' + end + end + + context 'given text containing script tags' do + let(:text) { '' } + + it 'strips the scripts' do + is_expected.to_not include '' + end + end + + context 'given text containing malicious classes' do + let(:text) { 'Show more' } + + it 'strips the malicious classes' do + is_expected.to_not include 'status__content__spoiler-link' + end + end + end + end +end diff --git a/spec/lib/plain_text_formatter_spec.rb b/spec/lib/plain_text_formatter_spec.rb new file mode 100644 index 000000000..c3d0ee630 --- /dev/null +++ b/spec/lib/plain_text_formatter_spec.rb @@ -0,0 +1,24 @@ +require 'rails_helper' + +RSpec.describe PlainTextFormatter do + describe '#to_s' do + subject { described_class.new(status.text, status.local?).to_s } + + context 'given a post with local status' do + let(:status) { Fabricate(:status, text: '

a text by a nerd who uses an HTML tag in text

', uri: nil) } + + it 'returns the raw text' do + is_expected.to eq '

a text by a nerd who uses an HTML tag in text

' + end + end + + context 'given a post with remote status' do + let(:remote_account) { Fabricate(:account, domain: 'remote.test', username: 'bob', url: 'https://remote.test/') } + let(:status) { Fabricate(:status, account: remote_account, text: '

Hello

') } + + it 'returns tag-stripped text' do + is_expected.to eq 'Hello' + end + end + end +end diff --git a/spec/lib/text_formatter_spec.rb b/spec/lib/text_formatter_spec.rb new file mode 100644 index 000000000..52a9d2498 --- /dev/null +++ b/spec/lib/text_formatter_spec.rb @@ -0,0 +1,313 @@ +require 'rails_helper' + +RSpec.describe TextFormatter do + describe '#to_s' do + let(:preloaded_accounts) { nil } + + subject { described_class.new(text, preloaded_accounts: preloaded_accounts).to_s } + + context 'given text containing plain text' do + let(:text) { 'text' } + + it 'paragraphizes the text' do + is_expected.to eq '

text

' + end + end + + context 'given text containing line feeds' do + let(:text) { "line\nfeed" } + + it 'removes line feeds' do + is_expected.not_to include "\n" + end + end + + context 'given text containing linkable mentions' do + let(:preloaded_accounts) { [Fabricate(:account, username: 'alice')] } + let(:text) { '@alice' } + + it 'creates a mention link' do + is_expected.to include '@alice' + end + end + + context 'given text containing unlinkable mentions' do + let(:preloaded_accounts) { [] } + let(:text) { '@alice' } + + it 'does not create a mention link' do + is_expected.to include '@alice' + end + end + + context 'given a stand-alone medium URL' do + let(:text) { 'https://hackernoon.com/the-power-to-build-communities-a-response-to-mark-zuckerberg-3f2cac9148a4' } + + it 'matches the full URL' do + is_expected.to include 'href="https://hackernoon.com/the-power-to-build-communities-a-response-to-mark-zuckerberg-3f2cac9148a4"' + end + end + + context 'given a stand-alone google URL' do + let(:text) { 'http://google.com' } + + it 'matches the full URL' do + is_expected.to include 'href="http://google.com"' + end + end + + context 'given a stand-alone URL with a newer TLD' do + let(:text) { 'http://example.gay' } + + it 'matches the full URL' do + is_expected.to include 'href="http://example.gay"' + end + end + + context 'given a stand-alone IDN URL' do + let(:text) { 'https://nic.みんな/' } + + it 'matches the full URL' do + is_expected.to include 'href="https://nic.みんな/"' + end + + it 'has display URL' do + is_expected.to include 'nic.みんな/' + end + end + + context 'given a URL with a trailing period' do + let(:text) { 'http://www.mcmansionhell.com/post/156408871451/50-states-of-mcmansion-hell-scottsdale-arizona. ' } + + it 'matches the full URL but not the period' do + is_expected.to include 'href="http://www.mcmansionhell.com/post/156408871451/50-states-of-mcmansion-hell-scottsdale-arizona"' + end + end + + context 'given a URL enclosed with parentheses' do + let(:text) { '(http://google.com/)' } + + it 'matches the full URL but not the parentheses' do + is_expected.to include 'href="http://google.com/"' + end + end + + context 'given a URL with a trailing exclamation point' do + let(:text) { 'http://www.google.com!' } + + it 'matches the full URL but not the exclamation point' do + is_expected.to include 'href="http://www.google.com"' + end + end + + context 'given a URL with a trailing single quote' do + let(:text) { "http://www.google.com'" } + + it 'matches the full URL but not the single quote' do + is_expected.to include 'href="http://www.google.com"' + end + end + + context 'given a URL with a trailing angle bracket' do + let(:text) { 'http://www.google.com>' } + + it 'matches the full URL but not the angle bracket' do + is_expected.to include 'href="http://www.google.com"' + end + end + + context 'given a URL with a query string' do + context 'with escaped unicode character' do + let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&q=autolink' } + + it 'matches the full URL' do + is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&q=autolink"' + end + end + + context 'with unicode character' do + let(:text) { 'https://www.ruby-toolbox.com/search?utf8=✓&q=autolink' } + + it 'matches the full URL' do + is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=✓&q=autolink"' + end + end + + context 'with unicode character at the end' do + let(:text) { 'https://www.ruby-toolbox.com/search?utf8=✓' } + + it 'matches the full URL' do + is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=✓"' + end + end + + context 'with escaped and not escaped unicode characters' do + let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&utf81=✓&q=autolink' } + + it 'preserves escaped unicode characters' do + is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&utf81=✓&q=autolink"' + end + end + end + + context 'given a URL with parentheses in it' do + let(:text) { 'https://en.wikipedia.org/wiki/Diaspora_(software)' } + + it 'matches the full URL' do + is_expected.to include 'href="https://en.wikipedia.org/wiki/Diaspora_(software)"' + end + end + + context 'given a URL in quotation marks' do + let(:text) { '"https://example.com/"' } + + it 'does not match the quotation marks' do + is_expected.to include 'href="https://example.com/"' + end + end + + context 'given a URL in angle brackets' do + let(:text) { '' } + + it 'does not match the angle brackets' do + is_expected.to include 'href="https://example.com/"' + end + end + + context 'given a URL with Japanese path string' do + let(:text) { 'https://ja.wikipedia.org/wiki/日本' } + + it 'matches the full URL' do + is_expected.to include 'href="https://ja.wikipedia.org/wiki/日本"' + end + end + + context 'given a URL with Korean path string' do + let(:text) { 'https://ko.wikipedia.org/wiki/대한민국' } + + it 'matches the full URL' do + is_expected.to include 'href="https://ko.wikipedia.org/wiki/대한민국"' + end + end + + context 'given a URL with a full-width space' do + let(:text) { 'https://example.com/ abc123' } + + it 'does not match the full-width space' do + is_expected.to include 'href="https://example.com/"' + end + end + + context 'given a URL in Japanese quotation marks' do + let(:text) { '「[https://example.org/」' } + + it 'does not match the quotation marks' do + is_expected.to include 'href="https://example.org/"' + end + end + + context 'given a URL with Simplified Chinese path string' do + let(:text) { 'https://baike.baidu.com/item/中华人民共和国' } + + it 'matches the full URL' do + is_expected.to include 'href="https://baike.baidu.com/item/中华人民共和国"' + end + end + + context 'given a URL with Traditional Chinese path string' do + let(:text) { 'https://zh.wikipedia.org/wiki/臺灣' } + + it 'matches the full URL' do + is_expected.to include 'href="https://zh.wikipedia.org/wiki/臺灣"' + end + end + + context 'given a URL containing unsafe code (XSS attack, visible part)' do + let(:text) { %q{http://example.com/bb} } + + it 'does not include the HTML in the URL' do + is_expected.to include '"http://example.com/b"' + end + + it 'escapes the HTML' do + is_expected.to include '<del>b</del>' + end + end + + context 'given a URL containing unsafe code (XSS attack, invisible part)' do + let(:text) { %q{http://example.com/blahblahblahblah/a} } + + it 'does not include the HTML in the URL' do + is_expected.to include '"http://example.com/blahblahblahblah/a"' + end + + it 'escapes the HTML' do + is_expected.to include '<script>alert("Hello")</script>' + end + end + + context 'given text containing HTML code (script tag)' do + let(:text) { '' } + + it 'escapes the HTML' do + is_expected.to include '

<script>alert("Hello")</script>

' + end + end + + context 'given text containing HTML (XSS attack)' do + let(:text) { %q{} } + + it 'escapes the HTML' do + is_expected.to include '

<img src="javascript:alert('XSS');">

' + end + end + + context 'given an invalid URL' do + let(:text) { 'http://www\.google\.com' } + + it 'outputs the raw URL' do + is_expected.to eq '

http://www\.google\.com

' + end + end + + context 'given text containing a hashtag' do + let(:text) { '#hashtag' } + + it 'creates a hashtag link' do + is_expected.to include '/tags/hashtag" class="mention hashtag" rel="tag">#hashtag' + end + end + + context 'given text containing a hashtag with Unicode chars' do + let(:text) { '#hashtagタグ' } + + it 'creates a hashtag link' do + is_expected.to include '/tags/hashtag%E3%82%BF%E3%82%B0" class="mention hashtag" rel="tag">#hashtagタグ' + end + end + + context 'given text with a stand-alone xmpp: URI' do + let(:text) { 'xmpp:user@instance.com' } + + it 'matches the full URI' do + is_expected.to include 'href="xmpp:user@instance.com"' + end + end + + context 'given text with an xmpp: URI with a query-string' do + let(:text) { 'please join xmpp:muc@instance.com?join right now' } + + it 'matches the full URI' do + is_expected.to include 'href="xmpp:muc@instance.com?join"' + end + end + + context 'given text containing a magnet: URI' do + let(:text) { 'wikipedia gives this example of a magnet uri: magnet:?xt=urn:btih:c12fe1c06bba254a9dc9f519b335aa7c1367a88a' } + + it 'matches the full URI' do + is_expected.to include 'href="magnet:?xt=urn:btih:c12fe1c06bba254a9dc9f519b335aa7c1367a88a"' + end + end + end +end -- cgit From 07f8b4d1b19f734d04e69daeb4c3421ef9767aac Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 26 Mar 2022 02:54:11 +0100 Subject: Bump version to 3.5.0rc2 (#17855) --- CHANGELOG.md | 6 ++++++ lib/mastodon/version.rb | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52a62a213..f0305d148 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -81,6 +81,7 @@ All notable changes to this project will be documented in this file. - Add lazy loading for emoji picker in web UI ([mashirozx](https://github.com/mastodon/mastodon/pull/16907), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17011)) - Add single option votes tooltip in polls in web UI ([Brawaru](https://github.com/mastodon/mastodon/pull/16849)) - Add confirmation modal when closing media edit modal with unsaved changes in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/16518)) +- Add hint about missing media attachment description in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/17845)) - Add support for fetching Create and Announce activities by URI in ActivityPub ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/16383)) - Add `S3_FORCE_SINGLE_REQUEST` environment variable ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/16866)) - Add `OMNIAUTH_ONLY` environment variable ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17288), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17345)) @@ -130,6 +131,11 @@ All notable changes to this project will be documented in this file. ### Fixed +- Fix IDN domains not being rendered correctly in a few left-over places ([Gargron](https://github.com/mastodon/mastodon/pull/17848)) +- Fix Sanskrit translation not being used in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17820)) +- Fix Kurdish languages having the wrong language codes ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17812)) +- Fix pghero making database schema suggestions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17807)) +- Fix encoding glitch in the OpenGraph description of a profile page ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17821)) - Fix web manifest not permitting PWA usage from alternate domains ([HolgerHuo](https://github.com/mastodon/mastodon/pull/16714)) - Fix not being able to edit media attachments for scheduled posts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17690)) - Fix subscribed relay activities being recorded as boosts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17571)) diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index f6e437d3a..acaa978bb 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -17,7 +17,7 @@ module Mastodon end def flags - 'rc1' + 'rc2' end def suffix -- cgit From 24e78969ae97501aad18595eb3af8c7338a1cb7c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 26 Mar 2022 04:02:19 +0100 Subject: Fix typo (#17875) --- app/serializers/activitypub/actor_serializer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb index bd1648348..30f86aae3 100644 --- a/app/serializers/activitypub/actor_serializer.rb +++ b/app/serializers/activitypub/actor_serializer.rb @@ -195,7 +195,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer end def value - html_aware_format(object.value, object.account.value?, with_rel_me: true, with_domains: true, multiline: false) + html_aware_format(object.value, object.account.local?, with_rel_me: true, with_domains: true, multiline: false) end end -- cgit From d7d049aab7578028492e73671769f0a350e34203 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 26 Mar 2022 04:29:36 +0100 Subject: Bump version to 3.5.0rc3 (#17876) --- lib/mastodon/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index acaa978bb..b1bd692a5 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -17,7 +17,7 @@ module Mastodon end def flags - 'rc2' + 'rc3' end def suffix -- cgit From a4e1830b5f15118bf2532401005376a0c6e896e6 Mon Sep 17 00:00:00 2001 From: mayaeh Date: Sat, 26 Mar 2022 10:52:51 +0900 Subject: [Glitch] Add a hashtag public link to the trending hashtag page Port 52813830bee5607332b49bee2916956286ec5dc1 to glitch-soc Co-authored-by: Claire Co-authored-by: Eugen Rochko Co-authored-by: Claire Signed-off-by: Claire --- app/javascript/flavours/glitch/components/admin/Counter.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/javascript/flavours/glitch/components/admin/Counter.js b/app/javascript/flavours/glitch/components/admin/Counter.js index ecb242950..a4d6cef41 100644 --- a/app/javascript/flavours/glitch/components/admin/Counter.js +++ b/app/javascript/flavours/glitch/components/admin/Counter.js @@ -33,6 +33,7 @@ export default class Counter extends React.PureComponent { label: PropTypes.string.isRequired, href: PropTypes.string, params: PropTypes.object, + target: PropTypes.string, }; state = { @@ -54,7 +55,7 @@ export default class Counter extends React.PureComponent { } render () { - const { label, href } = this.props; + const { label, href, target } = this.props; const { loading, data } = this.state; let content; @@ -100,7 +101,7 @@ export default class Counter extends React.PureComponent { if (href) { return ( - + {inner} ); -- cgit From e6a159a64869927cca5535943cdf3a280aeb5394 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 28 Mar 2022 01:16:02 +0200 Subject: Fix extra “zero” key in some plural translation strings (#17883) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/locales/en.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 5fa3c012e..829cd61d0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -168,7 +168,6 @@ en: previous_strikes_description_html: one: This account has one strike. other: This account has %{count} strikes. - zero: This account is in good standing. promote: Promote protocol: Protocol public: Public @@ -530,7 +529,6 @@ en: known_accounts: one: "%{count} known account" other: "%{count} known accounts" - zero: No known account moderation: all: All limited: Limited @@ -802,7 +800,6 @@ en: shared_by_over_week: one: Shared by one person over the last week other: Shared by %{count} people over the last week - zero: Shared by noone over the last week title: Trending links usage_comparison: Shared %{today} times today, compared to %{yesterday} yesterday pending_review: Pending review @@ -845,7 +842,6 @@ en: used_by_over_week: one: Used by one person over the last week other: Used by %{count} people over the last week - zero: Used by noone over the last week title: Trends warning_presets: add_new: Add new -- cgit From 2c45859ca9076c0b9916922e0be21ff83fc3b143 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 28 Mar 2022 01:17:17 +0200 Subject: Refactor account and status formatting (#17877) * Refactor status formatting * Add account formatting helpers * Remove StatusFormatter * Fixup * Fix copied typo --- app/chewy/statuses_index.rb | 4 +++- app/helpers/formatting_helper.rb | 12 ++++++++++-- app/lib/feed_manager.rb | 2 +- app/serializers/activitypub/actor_serializer.rb | 4 ++-- app/serializers/rest/account_serializer.rb | 4 ++-- app/views/accounts/_bio.html.haml | 4 ++-- app/views/admin/accounts/show.html.haml | 4 ++-- app/views/admin/reports/show.html.haml | 2 +- app/views/directories/index.html.haml | 2 +- app/views/notification_mailer/_status.text.erb | 2 +- app/views/notification_mailer/digest.text.erb | 2 +- 11 files changed, 26 insertions(+), 16 deletions(-) diff --git a/app/chewy/statuses_index.rb b/app/chewy/statuses_index.rb index d119f7cac..bfd61a048 100644 --- a/app/chewy/statuses_index.rb +++ b/app/chewy/statuses_index.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class StatusesIndex < Chewy::Index + include FormattingHelper + settings index: { refresh_interval: '15m' }, analysis: { filter: { english_stop: { @@ -57,7 +59,7 @@ class StatusesIndex < Chewy::Index field :id, type: 'long' field :account_id, type: 'long' - field :text, type: 'text', value: ->(status) { [status.spoiler_text, PlainTextFormatter.new(status.text, status.local?).to_s].concat(status.ordered_media_attachments.map(&:description)).concat(status.preloadable_poll ? status.preloadable_poll.options : []).join("\n\n") } do + field :text, type: 'text', value: ->(status) { [status.spoiler_text, extract_status_plain_text(status)].concat(status.ordered_media_attachments.map(&:description)).concat(status.preloadable_poll ? status.preloadable_poll.options : []).join("\n\n") } do field :stemmed, type: 'text', analyzer: 'content' end diff --git a/app/helpers/formatting_helper.rb b/app/helpers/formatting_helper.rb index 66e9e1e91..e11156999 100644 --- a/app/helpers/formatting_helper.rb +++ b/app/helpers/formatting_helper.rb @@ -9,11 +9,19 @@ module FormattingHelper TextFormatter.new(text, options).to_s end - def extract_plain_text(text, local) - PlainTextFormatter.new(text, local).to_s + def extract_status_plain_text(status) + PlainTextFormatter.new(status.text, status.local?).to_s end def status_content_format(status) html_aware_format(status.text, status.local?, preloaded_accounts: [status.account] + (status.respond_to?(:active_mentions) ? status.active_mentions.map(&:account) : [])) end + + def account_bio_format(account) + html_aware_format(account.note, account.local?) + end + + def account_field_value_format(field, with_rel_me: true) + html_aware_format(field.value, field.account.local?, with_rel_me: with_rel_me, with_domains: true, multiline: false) + end end diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 53d1390d4..709450080 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -446,7 +446,7 @@ class FeedManager status = status.reblog if status.reblog? combined_text = [ - extract_plain_text(status.text, status.local?), + extract_status_plain_text(status), status.spoiler_text, status.preloadable_poll ? status.preloadable_poll.options.join("\n\n") : nil, status.ordered_media_attachments.map(&:description).join("\n\n"), diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb index 30f86aae3..e6dd8040e 100644 --- a/app/serializers/activitypub/actor_serializer.rb +++ b/app/serializers/activitypub/actor_serializer.rb @@ -103,7 +103,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer end def summary - object.suspended? ? '' : html_aware_format(object.note, object.local?) + object.suspended? ? '' : account_bio_format(object) end def icon @@ -195,7 +195,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer end def value - html_aware_format(object.value, object.account.local?, with_rel_me: true, with_domains: true, multiline: false) + account_field_value_format(object) end end diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb index 2f67e06b2..4cf7b253f 100644 --- a/app/serializers/rest/account_serializer.rb +++ b/app/serializers/rest/account_serializer.rb @@ -20,7 +20,7 @@ class REST::AccountSerializer < ActiveModel::Serializer attributes :name, :value, :verified_at def value - html_aware_format(object.value, object.account.local?, with_rel_me: true, with_domains: true, multiline: false) + account_field_value_format(object) end end @@ -35,7 +35,7 @@ class REST::AccountSerializer < ActiveModel::Serializer end def note - object.suspended? ? '' : html_aware_format(object.note, object.local?) + object.suspended? ? '' : account_bio_format(object) end def url diff --git a/app/views/accounts/_bio.html.haml b/app/views/accounts/_bio.html.haml index df4f9bdb8..e2539b1d4 100644 --- a/app/views/accounts/_bio.html.haml +++ b/app/views/accounts/_bio.html.haml @@ -10,12 +10,12 @@ - if field.verified? %span.verified__mark{ title: t('accounts.link_verified_on', date: l(field.verified_at)) } = fa_icon 'check' - = prerender_custom_emojis(html_aware_format(field.value, account.local?, with_rel_me: true, with_domains: true, multiline: false), account.emojis) + = prerender_custom_emojis(account_field_value_format(field), account.emojis) = account_badge(account) - if account.note.present? - .account__header__content.emojify= prerender_custom_emojis(html_aware_format(account.note, account.local?), account.emojis) + .account__header__content.emojify= prerender_custom_emojis(account_bio_format(account), account.emojis) .public-account-bio__extra = t 'accounts.joined', date: l(account.created_at, format: :month) diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index b252f3eac..1230294fe 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -21,11 +21,11 @@ - if field.verified? %span.verified__mark{ title: t('accounts.link_verified_on', date: l(field.verified_at)) } = fa_icon 'check' - = prerender_custom_emojis(html_aware_format(field.value, account.local?, with_rel_me: true, with_domains: true, multiline: false), account.emojis) + = prerender_custom_emojis(account_field_value_format(field, with_rel_me: false), account.emojis) - if account.note.present? %div - .account__header__content.emojify= prerender_custom_emojis(html_aware_format(account.note, account.local?), account.emojis) + .account__header__content.emojify= prerender_custom_emojis(account_bio_format(account), account.emojis) .dashboard__counters.admin-account-counters %div diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml index 41fed2efb..cf960565f 100644 --- a/app/views/admin/reports/show.html.haml +++ b/app/views/admin/reports/show.html.haml @@ -27,7 +27,7 @@ = fa_icon('lock') if @report.target_account.locked? - if @report.target_account.note.present? .account-card__bio.emojify - = prerender_custom_emojis(html_aware_format(@report.target_account.note, @report.target_account.local?), @report.target_account.emojis) + = prerender_custom_emojis(account_bio_format(@report.target_account), @report.target_account.emojis) .account-card__actions .account-card__counters .account-card__counters__item diff --git a/app/views/directories/index.html.haml b/app/views/directories/index.html.haml index a032ddb8d..48f8c4bc2 100644 --- a/app/views/directories/index.html.haml +++ b/app/views/directories/index.html.haml @@ -34,7 +34,7 @@ = fa_icon('lock') if account.locked? - if account.note.present? .account-card__bio.emojify - = prerender_custom_emojis(html_aware_format(account.note, account.local?), account.emojis) + = prerender_custom_emojis(account_bio_format(account), account.emojis) - else .flex-spacer .account-card__actions diff --git a/app/views/notification_mailer/_status.text.erb b/app/views/notification_mailer/_status.text.erb index bf6d2b620..1dc8de739 100644 --- a/app/views/notification_mailer/_status.text.erb +++ b/app/views/notification_mailer/_status.text.erb @@ -3,6 +3,6 @@ > ---- > <% end %> -> <%= raw word_wrap(extract_plain_text(status.text, status.local?), break_sequence: "\n> ") %> +> <%= raw word_wrap(extract_status_plain_text(status), break_sequence: "\n> ") %> <%= raw t('application_mailer.view')%> <%= web_url("statuses/#{status.id}") %> diff --git a/app/views/notification_mailer/digest.text.erb b/app/views/notification_mailer/digest.text.erb index b767eb9c4..0f84a4ef0 100644 --- a/app/views/notification_mailer/digest.text.erb +++ b/app/views/notification_mailer/digest.text.erb @@ -5,7 +5,7 @@ * <%= raw t('notification_mailer.digest.mention', name: notification.from_account.pretty_acct) %> - <%= raw extract_plain_text(notification.target_status.text, notification.target_status.local?) %> + <%= raw extract_status_plain_text(notification.target_status) %> <%= raw t('application_mailer.view')%> <%= web_url("statuses/#{notification.target_status.id}") %> <% end %> -- cgit From 56edc6552f71a1f58fd8ca5ea2f0603015be0c2c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 28 Mar 2022 09:39:31 +0200 Subject: Add `SMTP_RETURN_PATH` environment variable to set bounce domain (#17886) --- config/environments/production.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/config/environments/production.rb b/config/environments/production.rb index 7fe381040..b003cce9e 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -91,11 +91,13 @@ Rails.application.configure do # E-mails outgoing_email_address = ENV.fetch('SMTP_FROM_ADDRESS', 'notifications@localhost') - outgoing_mail_domain = Mail::Address.new(outgoing_email_address).domain + outgoing_email_domain = Mail::Address.new(outgoing_email_address).domain + config.action_mailer.default_options = { from: outgoing_email_address, reply_to: ENV['SMTP_REPLY_TO'], - 'Message-ID': -> { "<#{Mail.random_tag}@#{outgoing_mail_domain}>" }, + return_path: ENV['SMTP_RETURN_PATH'], + message_id: -> { "<#{Mail.random_tag}@#{outgoing_email_domain}>" }, } config.action_mailer.smtp_settings = { -- cgit From 30658924a80434e6a2bceb61267b911ea8d37898 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 28 Mar 2022 12:43:58 +0200 Subject: Fix test-related issues (#17888) * Remove obsolete RSS::Serializer test Since #17828, RSS::Serializer no longer has specific code for deleted statuses, but it is never called on deleted statuses anyway. * Rename erroneously-named test files * Fix failing test * Fix test deprecation warnings * Update CircleCI Ruby orb 1.4.0 has a bug that does not match all the test files due to incorrect globbing --- .circleci/config.yml | 2 +- spec/controllers/admin/accounts_controller_spec.rb | 10 ++--- .../settings/exports/bookmarks_controller_spec.rb | 22 +++++++++++ .../settings/exports/bookmarks_controller_specs.rb | 17 -------- spec/lib/html_aware_formatter.rb | 44 --------------------- spec/lib/html_aware_formatter_spec.rb | 44 +++++++++++++++++++++ spec/lib/rss/serializer_spec.rb | 7 ---- spec/services/after_block_service_spec.rb | 8 ++-- spec/services/delete_account_service_spec.rb | 14 +++---- spec/services/mute_service_spec.rb | 22 ++++------- spec/services/notify_service_spec.rb | 46 +++++++++++----------- spec/services/suspend_account_service_spec.rb | 12 +++--- spec/services/unsuspend_account_service_spec.rb | 26 ++++++------ 13 files changed, 127 insertions(+), 147 deletions(-) create mode 100644 spec/controllers/settings/exports/bookmarks_controller_spec.rb delete mode 100644 spec/controllers/settings/exports/bookmarks_controller_specs.rb delete mode 100644 spec/lib/html_aware_formatter.rb create mode 100644 spec/lib/html_aware_formatter_spec.rb diff --git a/.circleci/config.yml b/.circleci/config.yml index 4fcc8c618..b9228f996 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,7 +1,7 @@ version: 2.1 orbs: - ruby: circleci/ruby@1.4.0 + ruby: circleci/ruby@1.4.1 node: circleci/node@5.0.1 executors: diff --git a/spec/controllers/admin/accounts_controller_spec.rb b/spec/controllers/admin/accounts_controller_spec.rb index 0f71d697c..1779fb7c0 100644 --- a/spec/controllers/admin/accounts_controller_spec.rb +++ b/spec/controllers/admin/accounts_controller_spec.rb @@ -194,9 +194,7 @@ RSpec.describe Admin::AccountsController, type: :controller do end describe 'POST #unblock_email' do - subject do - -> { post :unblock_email, params: { id: account.id } } - end + subject { post :unblock_email, params: { id: account.id } } let(:current_user) { Fabricate(:user, admin: admin) } let(:account) { Fabricate(:account, suspended: true) } @@ -206,11 +204,11 @@ RSpec.describe Admin::AccountsController, type: :controller do let(:admin) { true } it 'succeeds in removing email blocks' do - is_expected.to change { CanonicalEmailBlock.where(reference_account: account).count }.from(1).to(0) + expect { subject }.to change { CanonicalEmailBlock.where(reference_account: account).count }.from(1).to(0) end it 'redirects to admin account path' do - subject.call + subject expect(response).to redirect_to admin_account_path(account.id) end end @@ -219,7 +217,7 @@ RSpec.describe Admin::AccountsController, type: :controller do let(:admin) { false } it 'fails to remove avatar' do - subject.call + subject expect(response).to have_http_status :forbidden end end diff --git a/spec/controllers/settings/exports/bookmarks_controller_spec.rb b/spec/controllers/settings/exports/bookmarks_controller_spec.rb new file mode 100644 index 000000000..a06c02e0c --- /dev/null +++ b/spec/controllers/settings/exports/bookmarks_controller_spec.rb @@ -0,0 +1,22 @@ +require 'rails_helper' + +describe Settings::Exports::BookmarksController do + render_views + + let(:user) { Fabricate(:user) } + let(:account) { Fabricate(:account, domain: 'foo.bar') } + let(:status) { Fabricate(:status, account: account, uri: 'https://foo.bar/statuses/1312') } + + describe 'GET #index' do + before do + user.account.bookmarks.create!(status: status) + end + + it 'returns a csv of the bookmarked toots' do + sign_in user, scope: :user + get :index, format: :csv + + expect(response.body).to eq "https://foo.bar/statuses/1312\n" + end + end +end diff --git a/spec/controllers/settings/exports/bookmarks_controller_specs.rb b/spec/controllers/settings/exports/bookmarks_controller_specs.rb deleted file mode 100644 index 85761577b..000000000 --- a/spec/controllers/settings/exports/bookmarks_controller_specs.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'rails_helper' - -describe Settings::Exports::BookmarksController do - render_views - - describe 'GET #index' do - it 'returns a csv of the bookmarked toots' do - user = Fabricate(:user) - user.account.bookmarks.create!(status: Fabricate(:status, uri: 'https://foo.bar/statuses/1312')) - - sign_in user, scope: :user - get :index, format: :csv - - expect(response.body).to eq "https://foo.bar/statuses/1312\n" - end - end -end diff --git a/spec/lib/html_aware_formatter.rb b/spec/lib/html_aware_formatter.rb deleted file mode 100644 index 18d23abf5..000000000 --- a/spec/lib/html_aware_formatter.rb +++ /dev/null @@ -1,44 +0,0 @@ -require 'rails_helper' - -RSpec.describe HtmlAwareFormatter do - describe '#to_s' do - subject { described_class.new(text, local).to_s } - - context 'when local' do - let(:local) { true } - let(:text) { 'Foo bar' } - - it 'returns formatted text' do - is_expected.to eq '

Foo bar

' - end - end - - context 'when remote' do - let(:local) { false } - - context 'given plain text' do - let(:text) { 'Beep boop' } - - it 'keeps the plain text' do - is_expected.to include 'Beep boop' - end - end - - context 'given text containing script tags' do - let(:text) { '' } - - it 'strips the scripts' do - is_expected.to_not include '' - end - end - - context 'given text containing malicious classes' do - let(:text) { 'Show more' } - - it 'strips the malicious classes' do - is_expected.to_not include 'status__content__spoiler-link' - end - end - end - end -end diff --git a/spec/lib/html_aware_formatter_spec.rb b/spec/lib/html_aware_formatter_spec.rb new file mode 100644 index 000000000..18d23abf5 --- /dev/null +++ b/spec/lib/html_aware_formatter_spec.rb @@ -0,0 +1,44 @@ +require 'rails_helper' + +RSpec.describe HtmlAwareFormatter do + describe '#to_s' do + subject { described_class.new(text, local).to_s } + + context 'when local' do + let(:local) { true } + let(:text) { 'Foo bar' } + + it 'returns formatted text' do + is_expected.to eq '

Foo bar

' + end + end + + context 'when remote' do + let(:local) { false } + + context 'given plain text' do + let(:text) { 'Beep boop' } + + it 'keeps the plain text' do + is_expected.to include 'Beep boop' + end + end + + context 'given text containing script tags' do + let(:text) { '' } + + it 'strips the scripts' do + is_expected.to_not include '' + end + end + + context 'given text containing malicious classes' do + let(:text) { 'Show more' } + + it 'strips the malicious classes' do + is_expected.to_not include 'status__content__spoiler-link' + end + end + end + end +end diff --git a/spec/lib/rss/serializer_spec.rb b/spec/lib/rss/serializer_spec.rb index 0364d13de..1da45d302 100644 --- a/spec/lib/rss/serializer_spec.rb +++ b/spec/lib/rss/serializer_spec.rb @@ -13,13 +13,6 @@ describe RSS::Serializer do subject { RSS::Serializer.new.send(:status_title, status) } - context 'if destroyed?' do - it 'returns "#{account.acct} deleted status"' do - status.destroy! - expect(subject).to eq "#{account.acct} deleted status" - end - end - context 'on a toot with long text' do let(:text) { "This toot's text is longer than the allowed number of characters" } diff --git a/spec/services/after_block_service_spec.rb b/spec/services/after_block_service_spec.rb index fe5b26b2b..c09425d7c 100644 --- a/spec/services/after_block_service_spec.rb +++ b/spec/services/after_block_service_spec.rb @@ -1,9 +1,7 @@ require 'rails_helper' RSpec.describe AfterBlockService, type: :service do - subject do - -> { described_class.new.call(account, target_account) } - end + subject { described_class.new.call(account, target_account) } let(:account) { Fabricate(:account) } let(:target_account) { Fabricate(:account) } @@ -24,7 +22,7 @@ RSpec.describe AfterBlockService, type: :service do FeedManager.instance.push_to_home(account, other_account_status) FeedManager.instance.push_to_home(account, other_account_reblog) - is_expected.to change { + expect { subject }.to change { Redis.current.zrange(home_timeline_key, 0, -1) }.from([status.id.to_s, other_account_status.id.to_s, other_account_reblog.id.to_s]).to([other_account_status.id.to_s]) end @@ -43,7 +41,7 @@ RSpec.describe AfterBlockService, type: :service do FeedManager.instance.push_to_list(list, other_account_status) FeedManager.instance.push_to_list(list, other_account_reblog) - is_expected.to change { + expect { subject }.to change { Redis.current.zrange(list_timeline_key, 0, -1) }.from([status.id.to_s, other_account_status.id.to_s, other_account_reblog.id.to_s]).to([other_account_status.id.to_s]) end diff --git a/spec/services/delete_account_service_spec.rb b/spec/services/delete_account_service_spec.rb index 9c785fc17..1fbe4d07c 100644 --- a/spec/services/delete_account_service_spec.rb +++ b/spec/services/delete_account_service_spec.rb @@ -23,12 +23,10 @@ RSpec.describe DeleteAccountService, type: :service do let!(:account_note) { Fabricate(:account_note, account: account) } - subject do - -> { described_class.new.call(account) } - end + subject { described_class.new.call(account) } it 'deletes associated owned records' do - is_expected.to change { + expect { subject }.to change { [ account.statuses, account.media_attachments, @@ -43,7 +41,7 @@ RSpec.describe DeleteAccountService, type: :service do end it 'deletes associated target records' do - is_expected.to change { + expect { subject }.to change { [ AccountPin.where(target_account: account), ].map(&:count) @@ -51,7 +49,7 @@ RSpec.describe DeleteAccountService, type: :service do end it 'deletes associated target notifications' do - is_expected.to change { + expect { subject }.to change { [ 'poll', 'favourite', 'status', 'mention', 'follow' ].map { |type| Notification.where(type: type).count } @@ -73,7 +71,7 @@ RSpec.describe DeleteAccountService, type: :service do let!(:local_follower) { Fabricate(:account) } it 'sends a delete actor activity to all known inboxes' do - subject.call + subject expect(a_request(:post, "https://alice.com/inbox")).to have_been_made.once expect(a_request(:post, "https://bob.com/inbox")).to have_been_made.once end @@ -91,7 +89,7 @@ RSpec.describe DeleteAccountService, type: :service do let!(:local_follower) { Fabricate(:account) } it 'sends a reject follow to follower inboxes' do - subject.call + subject expect(a_request(:post, account.inbox_url)).to have_been_made.once end end diff --git a/spec/services/mute_service_spec.rb b/spec/services/mute_service_spec.rb index 4bb839b8d..bdec1c67b 100644 --- a/spec/services/mute_service_spec.rb +++ b/spec/services/mute_service_spec.rb @@ -1,9 +1,7 @@ require 'rails_helper' RSpec.describe MuteService, type: :service do - subject do - -> { described_class.new.call(account, target_account) } - end + subject { described_class.new.call(account, target_account) } let(:account) { Fabricate(:account) } let(:target_account) { Fabricate(:account) } @@ -21,45 +19,41 @@ RSpec.describe MuteService, type: :service do FeedManager.instance.push_to_home(account, status) FeedManager.instance.push_to_home(account, other_account_status) - is_expected.to change { + expect { subject }.to change { Redis.current.zrange(home_timeline_key, 0, -1) }.from([status.id.to_s, other_account_status.id.to_s]).to([other_account_status.id.to_s]) end end it 'mutes account' do - is_expected.to change { + expect { subject }.to change { account.muting?(target_account) }.from(false).to(true) end context 'without specifying a notifications parameter' do it 'mutes notifications from the account' do - is_expected.to change { + expect { subject }.to change { account.muting_notifications?(target_account) }.from(false).to(true) end end context 'with a true notifications parameter' do - subject do - -> { described_class.new.call(account, target_account, notifications: true) } - end + subject { described_class.new.call(account, target_account, notifications: true) } it 'mutes notifications from the account' do - is_expected.to change { + expect { subject }.to change { account.muting_notifications?(target_account) }.from(false).to(true) end end context 'with a false notifications parameter' do - subject do - -> { described_class.new.call(account, target_account, notifications: false) } - end + subject { described_class.new.call(account, target_account, notifications: false) } it 'does not mute notifications from the account' do - is_expected.to_not change { + expect { subject }.to_not change { account.muting_notifications?(target_account) }.from(false) end diff --git a/spec/services/notify_service_spec.rb b/spec/services/notify_service_spec.rb index 7433866b7..294c31b04 100644 --- a/spec/services/notify_service_spec.rb +++ b/spec/services/notify_service_spec.rb @@ -1,9 +1,7 @@ require 'rails_helper' RSpec.describe NotifyService, type: :service do - subject do - -> { described_class.new.call(recipient, type, activity) } - end + subject { described_class.new.call(recipient, type, activity) } let(:user) { Fabricate(:user) } let(:recipient) { user.account } @@ -11,42 +9,42 @@ RSpec.describe NotifyService, type: :service do let(:activity) { Fabricate(:follow, account: sender, target_account: recipient) } let(:type) { :follow } - it { is_expected.to change(Notification, :count).by(1) } + it { expect { subject }.to change(Notification, :count).by(1) } it 'does not notify when sender is blocked' do recipient.block!(sender) - is_expected.to_not change(Notification, :count) + expect { subject }.to_not change(Notification, :count) end it 'does not notify when sender is muted with hide_notifications' do recipient.mute!(sender, notifications: true) - is_expected.to_not change(Notification, :count) + expect { subject }.to_not change(Notification, :count) end it 'does notify when sender is muted without hide_notifications' do recipient.mute!(sender, notifications: false) - is_expected.to change(Notification, :count) + expect { subject }.to change(Notification, :count) end it 'does not notify when sender\'s domain is blocked' do recipient.block_domain!(sender.domain) - is_expected.to_not change(Notification, :count) + expect { subject }.to_not change(Notification, :count) end it 'does still notify when sender\'s domain is blocked but sender is followed' do recipient.block_domain!(sender.domain) recipient.follow!(sender) - is_expected.to change(Notification, :count) + expect { subject }.to change(Notification, :count) end it 'does not notify when sender is silenced and not followed' do sender.silence! - is_expected.to_not change(Notification, :count) + expect { subject }.to_not change(Notification, :count) end it 'does not notify when recipient is suspended' do recipient.suspend! - is_expected.to_not change(Notification, :count) + expect { subject }.to_not change(Notification, :count) end context 'for direct messages' do @@ -61,7 +59,7 @@ RSpec.describe NotifyService, type: :service do let(:enabled) { true } it 'does not notify' do - is_expected.to_not change(Notification, :count) + expect { subject }.to_not change(Notification, :count) end context 'if the message chain is initiated by recipient, but is not direct message' do @@ -70,7 +68,7 @@ RSpec.describe NotifyService, type: :service do let(:activity) { Fabricate(:mention, account: recipient, status: Fabricate(:status, account: sender, visibility: :direct, thread: reply_to)) } it 'does not notify' do - is_expected.to_not change(Notification, :count) + expect { subject }.to_not change(Notification, :count) end end @@ -81,7 +79,7 @@ RSpec.describe NotifyService, type: :service do let(:activity) { Fabricate(:mention, account: recipient, status: Fabricate(:status, account: sender, visibility: :direct, thread: dummy_reply)) } it 'does not notify' do - is_expected.to_not change(Notification, :count) + expect { subject }.to_not change(Notification, :count) end end @@ -91,7 +89,7 @@ RSpec.describe NotifyService, type: :service do let(:activity) { Fabricate(:mention, account: recipient, status: Fabricate(:status, account: sender, visibility: :direct, thread: reply_to)) } it 'does notify' do - is_expected.to change(Notification, :count) + expect { subject }.to change(Notification, :count) end end end @@ -100,7 +98,7 @@ RSpec.describe NotifyService, type: :service do let(:enabled) { false } it 'does notify' do - is_expected.to change(Notification, :count) + expect { subject }.to change(Notification, :count) end end end @@ -112,17 +110,17 @@ RSpec.describe NotifyService, type: :service do it 'shows reblogs by default' do recipient.follow!(sender) - is_expected.to change(Notification, :count) + expect { subject }.to change(Notification, :count) end it 'shows reblogs when explicitly enabled' do recipient.follow!(sender, reblogs: true) - is_expected.to change(Notification, :count) + expect { subject }.to change(Notification, :count) end it 'shows reblogs when disabled' do recipient.follow!(sender, reblogs: false) - is_expected.to change(Notification, :count) + expect { subject }.to change(Notification, :count) end end @@ -134,12 +132,12 @@ RSpec.describe NotifyService, type: :service do it 'does not notify when conversation is muted' do recipient.mute_conversation!(activity.status.conversation) - is_expected.to_not change(Notification, :count) + expect { subject }.to_not change(Notification, :count) end it 'does not notify when it is a reply to a blocked user' do recipient.block!(asshole) - is_expected.to_not change(Notification, :count) + expect { subject }.to_not change(Notification, :count) end end @@ -147,7 +145,7 @@ RSpec.describe NotifyService, type: :service do let(:sender) { recipient } it 'does not notify when recipient is the sender' do - is_expected.to_not change(Notification, :count) + expect { subject }.to_not change(Notification, :count) end end @@ -163,7 +161,7 @@ RSpec.describe NotifyService, type: :service do let(:enabled) { true } it 'sends email' do - is_expected.to change(ActionMailer::Base.deliveries, :count).by(1) + expect { subject }.to change(ActionMailer::Base.deliveries, :count).by(1) end end @@ -171,7 +169,7 @@ RSpec.describe NotifyService, type: :service do let(:enabled) { false } it "doesn't send email" do - is_expected.to_not change(ActionMailer::Base.deliveries, :count).from(0) + expect { subject }.to_not change(ActionMailer::Base.deliveries, :count).from(0) end end end diff --git a/spec/services/suspend_account_service_spec.rb b/spec/services/suspend_account_service_spec.rb index cf7eb257a..5d45e4ffd 100644 --- a/spec/services/suspend_account_service_spec.rb +++ b/spec/services/suspend_account_service_spec.rb @@ -5,9 +5,7 @@ RSpec.describe SuspendAccountService, type: :service do let!(:local_follower) { Fabricate(:user, current_sign_in_at: 1.hour.ago).account } let!(:list) { Fabricate(:list, account: local_follower) } - subject do - -> { described_class.new.call(account) } - end + subject { described_class.new.call(account) } before do allow(FeedManager.instance).to receive(:unmerge_from_home).and_return(nil) @@ -18,13 +16,13 @@ RSpec.describe SuspendAccountService, type: :service do end it "unmerges from local followers' feeds" do - subject.call + subject expect(FeedManager.instance).to have_received(:unmerge_from_home).with(account, local_follower) expect(FeedManager.instance).to have_received(:unmerge_from_list).with(account, list) end it 'marks account as suspended' do - is_expected.to change { account.suspended? }.from(false).to(true) + expect { subject }.to change { account.suspended? }.from(false).to(true) end end @@ -51,7 +49,7 @@ RSpec.describe SuspendAccountService, type: :service do end it 'sends an update actor to followers and reporters' do - subject.call + subject expect(a_request(:post, remote_follower.inbox_url).with { |req| match_update_actor_request(req, account) }).to have_been_made.once expect(a_request(:post, remote_reporter.inbox_url).with { |req| match_update_actor_request(req, account) }).to have_been_made.once end @@ -77,7 +75,7 @@ RSpec.describe SuspendAccountService, type: :service do end it 'sends a reject follow' do - subject.call + subject expect(a_request(:post, account.inbox_url).with { |req| match_reject_follow_request(req, account, local_followee) }).to have_been_made.once end end diff --git a/spec/services/unsuspend_account_service_spec.rb b/spec/services/unsuspend_account_service_spec.rb index 0593beb6f..3ac4cc085 100644 --- a/spec/services/unsuspend_account_service_spec.rb +++ b/spec/services/unsuspend_account_service_spec.rb @@ -5,9 +5,7 @@ RSpec.describe UnsuspendAccountService, type: :service do let!(:local_follower) { Fabricate(:user, current_sign_in_at: 1.hour.ago).account } let!(:list) { Fabricate(:list, account: local_follower) } - subject do - -> { described_class.new.call(account) } - end + subject { described_class.new.call(account) } before do allow(FeedManager.instance).to receive(:merge_into_home).and_return(nil) @@ -33,7 +31,7 @@ RSpec.describe UnsuspendAccountService, type: :service do end it 'marks account as unsuspended' do - is_expected.to change { account.suspended? }.from(true).to(false) + expect { subject }.to change { account.suspended? }.from(true).to(false) end include_examples 'common behavior' do @@ -47,13 +45,13 @@ RSpec.describe UnsuspendAccountService, type: :service do end it "merges back into local followers' feeds" do - subject.call + subject expect(FeedManager.instance).to have_received(:merge_into_home).with(account, local_follower) expect(FeedManager.instance).to have_received(:merge_into_list).with(account, list) end it 'sends an update actor to followers and reporters' do - subject.call + subject expect(a_request(:post, remote_follower.inbox_url).with { |req| match_update_actor_request(req, account) }).to have_been_made.once expect(a_request(:post, remote_reporter.inbox_url).with { |req| match_update_actor_request(req, account) }).to have_been_made.once end @@ -75,18 +73,18 @@ RSpec.describe UnsuspendAccountService, type: :service do end it 're-fetches the account' do - subject.call + subject expect(resolve_account_service).to have_received(:call).with(account) end it "merges back into local followers' feeds" do - subject.call + subject expect(FeedManager.instance).to have_received(:merge_into_home).with(account, local_follower) expect(FeedManager.instance).to have_received(:merge_into_list).with(account, list) end it 'marks account as unsuspended' do - is_expected.to change { account.suspended? }.from(true).to(false) + expect { subject }.to change { account.suspended? }.from(true).to(false) end end @@ -99,18 +97,18 @@ RSpec.describe UnsuspendAccountService, type: :service do end it 're-fetches the account' do - subject.call + subject expect(resolve_account_service).to have_received(:call).with(account) end it "does not merge back into local followers' feeds" do - subject.call + subject expect(FeedManager.instance).to_not have_received(:merge_into_home).with(account, local_follower) expect(FeedManager.instance).to_not have_received(:merge_into_list).with(account, list) end it 'does not mark the account as unsuspended' do - is_expected.not_to change { account.suspended? } + expect { subject }.not_to change { account.suspended? } end end @@ -120,12 +118,12 @@ RSpec.describe UnsuspendAccountService, type: :service do end it 're-fetches the account' do - subject.call + subject expect(resolve_account_service).to have_received(:call).with(account) end it "does not merge back into local followers' feeds" do - subject.call + subject expect(FeedManager.instance).to_not have_received(:merge_into_home).with(account, local_follower) expect(FeedManager.instance).to_not have_received(:merge_into_list).with(account, list) end -- cgit From 61cefbebf717326bd6ec3923e67e3702a24a0b24 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 28 Mar 2022 20:51:51 +0200 Subject: Add advanced text formatting back into glitch-soc --- app/helpers/formatting_helper.rb | 2 +- app/lib/advanced_text_formatter.rb | 131 +++++++++++++++ app/lib/html_aware_formatter.rb | 6 +- lib/sanitize_ext/sanitize_config.rb | 57 +++++-- spec/lib/advanced_text_formatter_spec.rb | 274 +++++++++++++++++++++++++++++++ spec/lib/sanitize_config_spec.rb | 18 +- 6 files changed, 459 insertions(+), 29 deletions(-) create mode 100644 app/lib/advanced_text_formatter.rb create mode 100644 spec/lib/advanced_text_formatter_spec.rb diff --git a/app/helpers/formatting_helper.rb b/app/helpers/formatting_helper.rb index e11156999..2a622ae0b 100644 --- a/app/helpers/formatting_helper.rb +++ b/app/helpers/formatting_helper.rb @@ -14,7 +14,7 @@ module FormattingHelper end def status_content_format(status) - html_aware_format(status.text, status.local?, preloaded_accounts: [status.account] + (status.respond_to?(:active_mentions) ? status.active_mentions.map(&:account) : [])) + html_aware_format(status.text, status.local?, preloaded_accounts: [status.account] + (status.respond_to?(:active_mentions) ? status.active_mentions.map(&:account) : []), content_type: status.content_type) end def account_bio_format(account) diff --git a/app/lib/advanced_text_formatter.rb b/app/lib/advanced_text_formatter.rb new file mode 100644 index 000000000..5ce87d306 --- /dev/null +++ b/app/lib/advanced_text_formatter.rb @@ -0,0 +1,131 @@ +# frozen_string_literal: true + +class AdvancedTextFormatter < TextFormatter + class HTMLRenderer < Redcarpet::Render::HTML + def initialize(options, &block) + super(options) + @format_link = block + end + + def block_code(code, _language) + <<~HTML.squish +
#{h(code).gsub("\n", '
')}
+ HTML + end + + def autolink(link, link_type) + return link if link_type == :email + @format_link.call(link) + end + end + + # @param [String] text + # @param [Hash] options + # @option options [Boolean] :multiline + # @option options [Boolean] :with_domains + # @option options [Boolean] :with_rel_me + # @option options [Array] :preloaded_accounts + # @option options [String] :content_type + def initialize(text, options = {}) + content_type = options.delete(:content_type) + super(text, options) + + @text = format_markdown(text) if content_type == 'text/markdown' + end + + # Differs from TextFormatter by not messing with newline after parsing + def to_s + return ''.html_safe if text.blank? + + html = rewrite do |entity| + if entity[:url] + link_to_url(entity) + elsif entity[:hashtag] + link_to_hashtag(entity) + elsif entity[:screen_name] + link_to_mention(entity) + end + end + + html.html_safe # rubocop:disable Rails/OutputSafety + end + + # Differs from `TextFormatter` by skipping HTML tags and entities + def entities + @entities ||= begin + gaps = [] + total_offset = 0 + + escaped = text.gsub(/<[^>]*>|&#[0-9]+;/) do |match| + total_offset += match.length - 1 + end_offset = Regexp.last_match.end(0) + gaps << [end_offset - total_offset, total_offset] + ' ' + end + + Extractor.extract_entities_with_indices(escaped, extract_url_without_protocol: false).map do |entity| + start_pos, end_pos = entity[:indices] + offset_idx = gaps.rindex { |gap| gap.first <= start_pos } + offset = offset_idx.nil? ? 0 : gaps[offset_idx].last + entity.merge(indices: [start_pos + offset, end_pos + offset]) + end + end + end + + private + + # Differs from `TextFormatter` in that it keeps HTML; but it sanitizes at the end to remain safe + def rewrite + entities.sort_by! do |entity| + entity[:indices].first + end + + result = ''.dup + + last_index = entities.reduce(0) do |index, entity| + indices = entity[:indices] + result << text[index...indices.first] + result << yield(entity) + indices.last + end + + result << text[last_index..-1] + + Sanitize.fragment(result, Sanitize::Config::MASTODON_OUTGOING) + end + + def format_markdown(html) + html = markdown_formatter.render(html) + html.delete("\r").delete("\n") + end + + def markdown_formatter + extensions = { + autolink: true, + no_intra_emphasis: true, + fenced_code_blocks: true, + disable_indented_code_blocks: true, + strikethrough: true, + lax_spacing: true, + space_after_headers: true, + superscript: true, + underline: true, + highlight: true, + footnotes: false, + } + + renderer = HTMLRenderer.new({ + filter_html: false, + escape_html: false, + no_images: true, + no_styles: true, + safe_links_only: true, + hard_wrap: true, + link_attributes: { target: '_blank', rel: 'nofollow noopener' }, + }) do |url| + link_to_url({ url: url }) + end + + Redcarpet::Markdown.new(renderer, extensions) + end +end diff --git a/app/lib/html_aware_formatter.rb b/app/lib/html_aware_formatter.rb index 64edba09b..7a1cd0340 100644 --- a/app/lib/html_aware_formatter.rb +++ b/app/lib/html_aware_formatter.rb @@ -33,6 +33,10 @@ class HtmlAwareFormatter end def linkify - TextFormatter.new(text, options).to_s + if %w(text/markdown text/html).include?(@options[:content_type]) + AdvancedTextFormatter.new(text, options).to_s + else + TextFormatter.new(text, options).to_s + end end end diff --git a/lib/sanitize_ext/sanitize_config.rb b/lib/sanitize_ext/sanitize_config.rb index ecaec2f84..935e1f4f6 100644 --- a/lib/sanitize_ext/sanitize_config.rb +++ b/lib/sanitize_ext/sanitize_config.rb @@ -55,18 +55,6 @@ class Sanitize end end - LINK_REL_TRANSFORMER = lambda do |env| - return unless env[:node_name] == 'a' and env[:node]['href'] - - node = env[:node] - - rel = (node['rel'] || '').split(' ') & ['tag'] - unless env[:config][:outgoing] && TagManager.instance.local_url?(node['href']) - rel += ['nofollow', 'noopener', 'noreferrer'] - end - node['rel'] = rel.join(' ') - end - UNSUPPORTED_HREF_TRANSFORMER = lambda do |env| return unless env[:node_name] == 'a' @@ -97,6 +85,7 @@ class Sanitize add_attributes: { 'a' => { + 'rel' => 'nofollow noopener noreferrer', 'target' => '_blank', }, }, @@ -110,7 +99,6 @@ class Sanitize CLASS_WHITELIST_TRANSFORMER, IMG_TAG_TRANSFORMER, UNSUPPORTED_HREF_TRANSFORMER, - LINK_REL_TRANSFORMER, ] ) @@ -135,5 +123,48 @@ class Sanitize 'source' => { 'src' => HTTP_PROTOCOLS } ) ) + + LINK_REL_TRANSFORMER = lambda do |env| + return unless env[:node_name] == 'a' && env[:node]['href'] + + node = env[:node] + + rel = (node['rel'] || '').split(' ') & ['tag'] + rel += ['nofollow', 'noopener', 'noreferrer'] unless TagManager.instance.local_url?(node['href']) + + if rel.empty? + node['rel']&.delete + else + node['rel'] = rel.join(' ') + end + end + + LINK_TARGET_TRANSFORMER = lambda do |env| + return unless env[:node_name] == 'a' && env[:node]['href'] + + node = env[:node] + if node['target'] != '_blank' && TagManager.instance.local_url?(node['href']) + node['target']&.delete + else + node['target'] = '_blank' + end + end + + MASTODON_OUTGOING ||= freeze_config MASTODON_STRICT.merge( + attributes: merge( + MASTODON_STRICT[:attributes], + 'a' => %w(href rel class title target) + ), + + add_attributes: {}, + + transformers: [ + CLASS_WHITELIST_TRANSFORMER, + IMG_TAG_TRANSFORMER, + UNSUPPORTED_HREF_TRANSFORMER, + LINK_REL_TRANSFORMER, + LINK_TARGET_TRANSFORMER, + ] + ) end end diff --git a/spec/lib/advanced_text_formatter_spec.rb b/spec/lib/advanced_text_formatter_spec.rb new file mode 100644 index 000000000..c097b86e1 --- /dev/null +++ b/spec/lib/advanced_text_formatter_spec.rb @@ -0,0 +1,274 @@ +require 'rails_helper' + +RSpec.describe AdvancedTextFormatter do + describe '#to_s' do + let(:preloaded_accounts) { nil } + let(:content_type) { 'text/markdown' } + + subject { described_class.new(text, preloaded_accounts: preloaded_accounts, content_type: content_type).to_s } + + context 'given a markdown source' do + let(:content_type) { 'text/markdown' } + + context 'given text containing plain text' do + let(:text) { 'text' } + + it 'paragraphizes the text' do + is_expected.to eq '

text

' + end + end + + context 'given text containing line feeds' do + let(:text) { "line\nfeed" } + + it 'removes line feeds' do + is_expected.not_to include "\n" + end + end + + context 'given some inline code using backticks' do + let(:text) { 'test `foo` bar' } + + it 'formats code using ' do + is_expected.to include 'test foo bar' + end + end + + context 'given some quote' do + let(:text) { "> foo\n\nbar" } + + it 'formats code using ' do + is_expected.to include '

foo

' + end + end + + context 'given text containing linkable mentions' do + let(:preloaded_accounts) { [Fabricate(:account, username: 'alice')] } + let(:text) { '@alice' } + + it 'creates a mention link' do + is_expected.to include '@alice' + end + end + + context 'given text containing unlinkable mentions' do + let(:preloaded_accounts) { [] } + let(:text) { '@alice' } + + it 'does not create a mention link' do + is_expected.to include '@alice' + end + end + + context 'given a stand-alone medium URL' do + let(:text) { 'https://hackernoon.com/the-power-to-build-communities-a-response-to-mark-zuckerberg-3f2cac9148a4' } + + it 'matches the full URL' do + is_expected.to include 'href="https://hackernoon.com/the-power-to-build-communities-a-response-to-mark-zuckerberg-3f2cac9148a4"' + end + end + + context 'given a stand-alone google URL' do + let(:text) { 'http://google.com' } + + it 'matches the full URL' do + is_expected.to include 'href="http://google.com"' + end + end + + context 'given a stand-alone URL with a newer TLD' do + let(:text) { 'http://example.gay' } + + it 'matches the full URL' do + is_expected.to include 'href="http://example.gay"' + end + end + + context 'given a stand-alone IDN URL' do + let(:text) { 'https://nic.みんな/' } + + it 'matches the full URL' do + is_expected.to include 'href="https://nic.みんな/"' + end + + it 'has display URL' do + is_expected.to include 'nic.みんな/' + end + end + + context 'given a URL with a trailing period' do + let(:text) { 'http://www.mcmansionhell.com/post/156408871451/50-states-of-mcmansion-hell-scottsdale-arizona. ' } + + it 'matches the full URL but not the period' do + is_expected.to include 'href="http://www.mcmansionhell.com/post/156408871451/50-states-of-mcmansion-hell-scottsdale-arizona"' + end + end + + context 'given a URL enclosed with parentheses' do + let(:text) { '(http://google.com/)' } + + it 'matches the full URL but not the parentheses' do + is_expected.to include 'href="http://google.com/"' + end + end + + context 'given a URL with a trailing exclamation point' do + let(:text) { 'http://www.google.com!' } + + it 'matches the full URL but not the exclamation point' do + is_expected.to include 'href="http://www.google.com"' + end + end + + context 'given a URL with a trailing single quote' do + let(:text) { "http://www.google.com'" } + + it 'matches the full URL but not the single quote' do + is_expected.to include 'href="http://www.google.com"' + end + end + end + + context 'given a URL with a trailing angle bracket' do + let(:text) { 'http://www.google.com>' } + + it 'matches the full URL but not the angle bracket' do + is_expected.to include 'href="http://www.google.com"' + end + end + + context 'given a URL with a query string' do + context 'with escaped unicode character' do + let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&q=autolink' } + + it 'matches the full URL' do + is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&q=autolink"' + end + end + + context 'with unicode character' do + let(:text) { 'https://www.ruby-toolbox.com/search?utf8=✓&q=autolink' } + + it 'matches the full URL' do + is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=✓&q=autolink"' + end + end + + context 'with unicode character at the end' do + let(:text) { 'https://www.ruby-toolbox.com/search?utf8=✓' } + + it 'matches the full URL' do + is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=✓"' + end + end + + context 'with escaped and not escaped unicode characters' do + let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&utf81=✓&q=autolink' } + + it 'preserves escaped unicode characters' do + is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&utf81=✓&q=autolink"' + end + end + + context 'given a URL with parentheses in it' do + let(:text) { 'https://en.wikipedia.org/wiki/Diaspora_(software)' } + + it 'matches the full URL' do + is_expected.to include 'href="https://en.wikipedia.org/wiki/Diaspora_(software)"' + end + end + + context 'given a URL in quotation marks' do + let(:text) { '"https://example.com/"' } + + it 'does not match the quotation marks' do + is_expected.to include 'href="https://example.com/"' + end + end + + context 'given a URL in angle brackets' do + let(:text) { '' } + + it 'does not match the angle brackets' do + is_expected.to include 'href="https://example.com/"' + end + end + + context 'given a URL containing unsafe code (XSS attack, invisible part)' do + let(:text) { %q{http://example.com/blahblahblahblah/a} } + + it 'does not include the HTML in the URL' do + is_expected.to include '"http://example.com/blahblahblahblah/a"' + end + + it 'does not include a script tag' do + is_expected.to_not include '' } + + it 'does not include a script tag' do + is_expected.to_not include '