From 828299e71c127d4406de3add93afa5b28bdb116a Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 17 Apr 2024 05:19:02 -0400 Subject: [PATCH 01/13] Enable AR Encryption (#29831) --- .env.development | 4 +++ .env.test | 5 ++++ .github/workflows/test-ruby.yml | 3 +++ .gitignore | 1 - Dockerfile | 7 ++++- .../initializers/active_record_encryption.rb | 26 +++++++++++++++++++ lib/tasks/mastodon.rake | 9 +++++++ 7 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 .env.development create mode 100644 config/initializers/active_record_encryption.rb diff --git a/.env.development b/.env.development new file mode 100644 index 0000000000..0330da8377 --- /dev/null +++ b/.env.development @@ -0,0 +1,4 @@ +# Required by ActiveRecord encryption feature +ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=fkSxKD2bF396kdQbrP1EJ7WbU7ZgNokR +ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=r0hvVmzBVsjxC7AMlwhOzmtc36ZCOS1E +ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=PhdFyyfy5xJ7WVd2lWBpcPScRQHzRTNr diff --git a/.env.test b/.env.test index 2f8c1afd6e..9e6abea5c9 100644 --- a/.env.test +++ b/.env.test @@ -3,3 +3,8 @@ NODE_ENV=production # Federation LOCAL_DOMAIN=cb6e6126.ngrok.io LOCAL_HTTPS=true + +# Required by ActiveRecord encryption feature +ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=fkSxKD2bF396kdQbrP1EJ7WbU7ZgNokR +ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=r0hvVmzBVsjxC7AMlwhOzmtc36ZCOS1E +ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=PhdFyyfy5xJ7WVd2lWBpcPScRQHzRTNr diff --git a/.github/workflows/test-ruby.yml b/.github/workflows/test-ruby.yml index 172b5271d8..3a78f8b43d 100644 --- a/.github/workflows/test-ruby.yml +++ b/.github/workflows/test-ruby.yml @@ -28,6 +28,9 @@ jobs: env: RAILS_ENV: ${{ matrix.mode }} BUNDLE_WITH: ${{ matrix.mode }} + ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY: precompile_placeholder + ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT: precompile_placeholder + ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY: precompile_placeholder OTP_SECRET: precompile_placeholder SECRET_KEY_BASE: precompile_placeholder diff --git a/.gitignore b/.gitignore index c5af8eb67f..2f94b751ab 100644 --- a/.gitignore +++ b/.gitignore @@ -24,7 +24,6 @@ /public/packs-test .env .env.production -.env.development /node_modules/ /build/ diff --git a/Dockerfile b/Dockerfile index 1b007930eb..43bc24295d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -205,7 +205,12 @@ ARG TARGETPLATFORM RUN \ # Use Ruby on Rails to create Mastodon assets - OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder bundle exec rails assets:precompile; \ + ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=precompile_placeholder \ + ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=precompile_placeholder \ + ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=precompile_placeholder \ + OTP_SECRET=precompile_placeholder \ + SECRET_KEY_BASE=precompile_placeholder \ + bundle exec rails assets:precompile; \ # Cleanup temporary files rm -fr /opt/mastodon/tmp; diff --git a/config/initializers/active_record_encryption.rb b/config/initializers/active_record_encryption.rb new file mode 100644 index 0000000000..f99585b4ad --- /dev/null +++ b/config/initializers/active_record_encryption.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +%w( + ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY + ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT + ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY +).each do |key| + ENV.fetch(key) do + raise <<~MESSAGE + + The ActiveRecord encryption feature requires that these variables are set: + + - ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY + - ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT + - ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY + + Run `bin/rails db:encryption:init` to generate values and then assign the environment variables. + MESSAGE + end +end + +Rails.application.configure do + config.active_record.encryption.deterministic_key = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY') + config.active_record.encryption.key_derivation_salt = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT') + config.active_record.encryption.primary_key = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY') +end diff --git a/lib/tasks/mastodon.rake b/lib/tasks/mastodon.rake index cb364b3021..2822f2eeb1 100644 --- a/lib/tasks/mastodon.rake +++ b/lib/tasks/mastodon.rake @@ -36,6 +36,15 @@ namespace :mastodon do env[key] = SecureRandom.hex(64) end + # Required by ActiveRecord encryption feature + %w( + ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY + ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT + ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY + ).each do |key| + env[key] = SecureRandom.alphanumeric(32) + end + vapid_key = Webpush.generate_key env['VAPID_PRIVATE_KEY'] = vapid_key.private_key From 1d3ecd3fbaf15450890c1ece7955846fba82a58d Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 17 Apr 2024 05:22:45 -0400 Subject: [PATCH 02/13] Add `API::Pagination` concern (#28826) --- app/controllers/api/base_controller.rb | 28 +---------------- app/controllers/concerns/api/pagination.rb | 36 ++++++++++++++++++++++ 2 files changed, 37 insertions(+), 27 deletions(-) create mode 100644 app/controllers/concerns/api/pagination.rb diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb index f87d596ce3..c1a5e43f88 100644 --- a/app/controllers/api/base_controller.rb +++ b/app/controllers/api/base_controller.rb @@ -9,6 +9,7 @@ class Api::BaseController < ApplicationController include Api::CachingConcern include Api::ContentSecurityPolicy include Api::ErrorHandling + include Api::Pagination skip_before_action :require_functional!, unless: :limited_federation_mode? @@ -29,21 +30,6 @@ class Api::BaseController < ApplicationController protected - def pagination_max_id - pagination_collection.last.id - end - - def pagination_since_id - pagination_collection.first.id - end - - def set_pagination_headers(next_path = nil, prev_path = nil) - links = [] - links << [next_path, [%w(rel next)]] if next_path - links << [prev_path, [%w(rel prev)]] if prev_path - response.headers['Link'] = LinkHeader.new(links) unless links.empty? - end - def limit_param(default_limit) return default_limit unless params[:limit] @@ -72,10 +58,6 @@ class Api::BaseController < ApplicationController render json: { error: 'Your login is currently disabled' }, status: 403 if current_user&.account&.unavailable? end - def require_valid_pagination_options! - render json: { error: 'Pagination values for `offset` and `limit` must be positive' }, status: 400 if pagination_options_invalid? - end - def require_user! if !current_user render json: { error: 'This method requires an authenticated user' }, status: 422 @@ -104,14 +86,6 @@ class Api::BaseController < ApplicationController private - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - - def pagination_options_invalid? - params.slice(:limit, :offset).values.map(&:to_i).any?(&:negative?) - end - def respond_with_error(code) render json: { error: Rack::Utils::HTTP_STATUS_CODES[code] }, status: code end diff --git a/app/controllers/concerns/api/pagination.rb b/app/controllers/concerns/api/pagination.rb new file mode 100644 index 0000000000..d84a1d99f7 --- /dev/null +++ b/app/controllers/concerns/api/pagination.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Api::Pagination + extend ActiveSupport::Concern + + protected + + def pagination_max_id + pagination_collection.last.id + end + + def pagination_since_id + pagination_collection.first.id + end + + def set_pagination_headers(next_path = nil, prev_path = nil) + links = [] + links << [next_path, [%w(rel next)]] if next_path + links << [prev_path, [%w(rel prev)]] if prev_path + response.headers['Link'] = LinkHeader.new(links) unless links.empty? + end + + def require_valid_pagination_options! + render json: { error: 'Pagination values for `offset` and `limit` must be positive' }, status: 400 if pagination_options_invalid? + end + + private + + def insert_pagination_headers + set_pagination_headers(next_path, prev_path) + end + + def pagination_options_invalid? + params.slice(:limit, :offset).values.map(&:to_i).any?(&:negative?) + end +end From 650c548c31b993990f38c9a29570bf7c82e4b15e Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 17 Apr 2024 06:05:38 -0400 Subject: [PATCH 03/13] Add `not_featured_by` scope to Tag (#28815) --- .../featured_tags/suggestions_controller.rb | 6 +----- .../settings/featured_tags_controller.rb | 2 +- app/models/tag.rb | 2 ++ spec/models/tag_spec.rb | 19 +++++++++++++++++++ 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/v1/featured_tags/suggestions_controller.rb b/app/controllers/api/v1/featured_tags/suggestions_controller.rb index 4f732ed2d5..9c72e4380d 100644 --- a/app/controllers/api/v1/featured_tags/suggestions_controller.rb +++ b/app/controllers/api/v1/featured_tags/suggestions_controller.rb @@ -12,10 +12,6 @@ class Api::V1::FeaturedTags::SuggestionsController < Api::BaseController private def set_recently_used_tags - @recently_used_tags = Tag.recently_used(current_account).where.not(id: featured_tag_ids).limit(10) - end - - def featured_tag_ids - current_account.featured_tags.pluck(:tag_id) + @recently_used_tags = Tag.suggestions_for_account(current_account).limit(10) end end diff --git a/app/controllers/settings/featured_tags_controller.rb b/app/controllers/settings/featured_tags_controller.rb index c384402650..90c112e219 100644 --- a/app/controllers/settings/featured_tags_controller.rb +++ b/app/controllers/settings/featured_tags_controller.rb @@ -38,7 +38,7 @@ class Settings::FeaturedTagsController < Settings::BaseController end def set_recently_used_tags - @recently_used_tags = Tag.recently_used(current_account).where.not(id: @featured_tags.map(&:id)).limit(10) + @recently_used_tags = Tag.suggestions_for_account(current_account).limit(10) end def featured_tag_params diff --git a/app/models/tag.rb b/app/models/tag.rb index f2168ae904..58baa48c05 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -53,6 +53,8 @@ class Tag < ApplicationRecord scope :listable, -> { where(listable: [true, nil]) } scope :trendable, -> { Setting.trendable_by_default ? where(trendable: [true, nil]) : where(trendable: true) } scope :not_trendable, -> { where(trendable: false) } + scope :suggestions_for_account, ->(account) { recently_used(account).not_featured_by(account) } + scope :not_featured_by, ->(account) { where.not(id: account.featured_tags.select(:tag_id)) } scope :recently_used, lambda { |account| joins(:statuses) .where(statuses: { id: account.statuses.select(:id).limit(RECENT_STATUS_LIMIT) }) diff --git a/spec/models/tag_spec.rb b/spec/models/tag_spec.rb index 5a1d620884..4c2bdd52f4 100644 --- a/spec/models/tag_spec.rb +++ b/spec/models/tag_spec.rb @@ -142,6 +142,25 @@ RSpec.describe Tag do end end + describe '.not_featured_by' do + let!(:account) { Fabricate(:account) } + let!(:fun) { Fabricate(:tag, name: 'fun') } + let!(:games) { Fabricate(:tag, name: 'games') } + + before do + Fabricate :featured_tag, account: account, name: 'games' + Fabricate :featured_tag, name: 'fun' + end + + it 'returns tags not featured by the account' do + results = described_class.not_featured_by(account) + + expect(results) + .to include(fun) + .and not_include(games) + end + end + describe '.matches_name' do it 'returns tags for multibyte case-insensitive names' do upcase_string = 'abcABCabcABCやゆよ' From 013671f29f3ebe791078d9e1ea92950a608d0ecb Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 17 Apr 2024 06:23:07 -0400 Subject: [PATCH 04/13] Rename JS testing section in GH Actions config (#29931) --- .github/workflows/test-js.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-js.yml b/.github/workflows/test-js.yml index 79622b6c1f..481afdba30 100644 --- a/.github/workflows/test-js.yml +++ b/.github/workflows/test-js.yml @@ -38,5 +38,5 @@ jobs: - name: Set up Javascript environment uses: ./.github/actions/setup-javascript - - name: Jest testing + - name: JavaScript testing run: yarn jest --reporters github-actions summary From 8bece467f821e587208284188d8c517118cd87b0 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 17 Apr 2024 13:13:52 +0200 Subject: [PATCH 05/13] Change `have_enqueued_sidekiq_job` usage to always make argument expectations explicit (#29974) --- spec/services/create_featured_tag_service_spec.rb | 2 +- spec/services/unmute_service_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/services/create_featured_tag_service_spec.rb b/spec/services/create_featured_tag_service_spec.rb index 29a7c5b309..f057bc8538 100644 --- a/spec/services/create_featured_tag_service_spec.rb +++ b/spec/services/create_featured_tag_service_spec.rb @@ -24,7 +24,7 @@ RSpec.describe CreateFeaturedTagService do expect { subject.call(account, tag) } .to change(FeaturedTag, :count).by(1) expect(ActivityPub::AccountRawDistributionWorker) - .to_not have_enqueued_sidekiq_job + .to_not have_enqueued_sidekiq_job(any_args) end end end diff --git a/spec/services/unmute_service_spec.rb b/spec/services/unmute_service_spec.rb index 00135b5ac0..92c7a70d65 100644 --- a/spec/services/unmute_service_spec.rb +++ b/spec/services/unmute_service_spec.rb @@ -24,7 +24,7 @@ RSpec.describe UnmuteService do it 'removes the account mute and does not create a merge' do expect { subject.call(account, target_account) } .to remove_account_mute - expect(MergeWorker).to_not have_enqueued_sidekiq_job + expect(MergeWorker).to_not have_enqueued_sidekiq_job(any_args) end end @@ -39,7 +39,7 @@ RSpec.describe UnmuteService do it 'does nothing and returns' do expect { subject.call(account, target_account) } .to_not(change { account.reload.muting?(target_account) }) - expect(MergeWorker).to_not have_enqueued_sidekiq_job + expect(MergeWorker).to_not have_enqueued_sidekiq_job(any_args) end end end From 1ad119941ff672b93f2b04dc29f82443349bb69c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Apr 2024 13:14:09 +0200 Subject: [PATCH 06/13] Update dependency rspec-sidekiq to v4.2.0 (#29964) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index ffeeebe9d3..752d4e05e0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -640,7 +640,7 @@ GEM rspec-expectations (~> 3.13) rspec-mocks (~> 3.13) rspec-support (~> 3.13) - rspec-sidekiq (4.1.0) + rspec-sidekiq (4.2.0) rspec-core (~> 3.0) rspec-expectations (~> 3.0) rspec-mocks (~> 3.0) From 630572323f95b382c552d18fa8bba23898cbd9c3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Apr 2024 23:52:26 +0200 Subject: [PATCH 07/13] Update dependency ioredis to v5.4.1 (#29977) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e2f741c5b3..bf217a074f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9589,8 +9589,8 @@ __metadata: linkType: hard "ioredis@npm:^5.3.2": - version: 5.4.0 - resolution: "ioredis@npm:5.4.0" + version: 5.4.1 + resolution: "ioredis@npm:5.4.1" dependencies: "@ioredis/commands": "npm:^1.1.1" cluster-key-slot: "npm:^1.1.0" @@ -9601,7 +9601,7 @@ __metadata: redis-errors: "npm:^1.2.0" redis-parser: "npm:^3.0.0" standard-as-callback: "npm:^2.1.0" - checksum: 10c0/a0214a004928cd35f7103179c8d236a8df609265994d554046fd130446b9989125b7133177936015a31925190f66c90bec4de7303819fe81383dc4576d947d47 + checksum: 10c0/5d28b7c89a3cab5b76d75923d7d4ce79172b3a1ca9be690133f6e8e393a7a4b4ffd55513e618bbb5504fed80d9e1395c9d9531a7c5c5c84aa4c4e765cca75456 languageName: node linkType: hard From 11e0049b08c721eb98d8220405c2ffc16041ed17 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 18 Apr 2024 06:13:35 -0400 Subject: [PATCH 08/13] Use enum-generated scopes/queries for `BulkImport` (#29975) --- app/controllers/settings/imports_controller.rb | 4 ++-- app/lib/vacuum/imports_vacuum.rb | 2 +- app/models/bulk_import.rb | 2 +- app/views/settings/imports/index.html.haml | 4 ++-- spec/models/form/import_spec.rb | 2 +- spec/services/bulk_import_service_spec.rb | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/controllers/settings/imports_controller.rb b/app/controllers/settings/imports_controller.rb index 983caf22fa..569aa07c53 100644 --- a/app/controllers/settings/imports_controller.rb +++ b/app/controllers/settings/imports_controller.rb @@ -31,7 +31,7 @@ class Settings::ImportsController < Settings::BaseController def show; end def failures - @bulk_import = current_account.bulk_imports.where(state: :finished).find(params[:id]) + @bulk_import = current_account.bulk_imports.state_finished.find(params[:id]) respond_to do |format| format.csv do @@ -92,7 +92,7 @@ class Settings::ImportsController < Settings::BaseController end def set_bulk_import - @bulk_import = current_account.bulk_imports.where(state: :unconfirmed).find(params[:id]) + @bulk_import = current_account.bulk_imports.state_unconfirmed.find(params[:id]) end def set_recent_imports diff --git a/app/lib/vacuum/imports_vacuum.rb b/app/lib/vacuum/imports_vacuum.rb index ffb9449a42..8c8bb783ac 100644 --- a/app/lib/vacuum/imports_vacuum.rb +++ b/app/lib/vacuum/imports_vacuum.rb @@ -9,7 +9,7 @@ class Vacuum::ImportsVacuum private def clean_unconfirmed_imports! - BulkImport.where(state: :unconfirmed).where('created_at <= ?', 10.minutes.ago).reorder(nil).in_batches.delete_all + BulkImport.state_unconfirmed.where('created_at <= ?', 10.minutes.ago).reorder(nil).in_batches.delete_all end def clean_old_imports! diff --git a/app/models/bulk_import.rb b/app/models/bulk_import.rb index 4cd228705a..9b3f4c8a3a 100644 --- a/app/models/bulk_import.rb +++ b/app/models/bulk_import.rb @@ -38,7 +38,7 @@ class BulkImport < ApplicationRecord scheduled: 1, in_progress: 2, finished: 3, - } + }, prefix: true validates :type, presence: true diff --git a/app/views/settings/imports/index.html.haml b/app/views/settings/imports/index.html.haml index d5ca252dc1..ca815720fd 100644 --- a/app/views/settings/imports/index.html.haml +++ b/app/views/settings/imports/index.html.haml @@ -49,7 +49,7 @@ %tr %td= t("imports.types.#{import.type}") %td - - if import.unconfirmed? + - if import.state_unconfirmed? = link_to t("imports.states.#{import.state}"), settings_import_path(import) - else = t("imports.states.#{import.state}") @@ -59,7 +59,7 @@ %td - num_failed = import.processed_items - import.imported_items - if num_failed.positive? - - if import.finished? + - if import.state_finished? = link_to num_failed, failures_settings_import_path(import, format: 'csv') - else = num_failed diff --git a/spec/models/form/import_spec.rb b/spec/models/form/import_spec.rb index c2f41d442c..22ffdfd877 100644 --- a/spec/models/form/import_spec.rb +++ b/spec/models/form/import_spec.rb @@ -281,7 +281,7 @@ RSpec.describe Form::Import do end it 'defaults to unconfirmed true' do - expect(bulk_import.unconfirmed?).to be true + expect(bulk_import.state_unconfirmed?).to be true end end end diff --git a/spec/services/bulk_import_service_spec.rb b/spec/services/bulk_import_service_spec.rb index c3a7160580..e8bec96c85 100644 --- a/spec/services/bulk_import_service_spec.rb +++ b/spec/services/bulk_import_service_spec.rb @@ -291,7 +291,7 @@ RSpec.describe BulkImportService do it 'marks the import as finished' do subject.call(import) - expect(import.reload.finished?).to be true + expect(import.reload.state_finished?).to be true end end @@ -319,7 +319,7 @@ RSpec.describe BulkImportService do it 'marks the import as finished' do subject.call(import) - expect(import.reload.finished?).to be true + expect(import.reload.state_finished?).to be true end end From 443186ff405112520e95836916eb2731b6a64c03 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 18 Apr 2024 13:18:39 +0200 Subject: [PATCH 09/13] New Crowdin Translations (automated) (#29980) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/en-GB.json | 50 ++++++++++++ app/javascript/mastodon/locales/es-MX.json | 1 + app/javascript/mastodon/locales/es.json | 1 + app/javascript/mastodon/locales/ia.json | 91 ++++++++++++++++++++++ config/locales/cs.yml | 56 +++++++++++++ config/locales/eu.yml | 4 +- config/locales/simple_form.cs.yml | 2 + 7 files changed, 203 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/locales/en-GB.json b/app/javascript/mastodon/locales/en-GB.json index 80a3479b46..6c24d5a261 100644 --- a/app/javascript/mastodon/locales/en-GB.json +++ b/app/javascript/mastodon/locales/en-GB.json @@ -209,6 +209,27 @@ "dismissable_banner.explore_statuses": "These are posts from across the social web that are gaining traction today. Newer posts with more boosts and favourites are ranked higher.", "dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralised network right now.", "dismissable_banner.public_timeline": "These are the most recent public posts from people on the social web that people on {domain} follow.", + "domain_block_modal.block": "Block server", + "domain_block_modal.block_account_instead": "Block @{name} instead", + "domain_block_modal.they_can_interact_with_old_posts": "People from this server can interact with your old posts.", + "domain_block_modal.they_cant_follow": "Nobody from this server can follow you.", + "domain_block_modal.they_wont_know": "They won't know they've been blocked.", + "domain_block_modal.title": "Block domain?", + "domain_block_modal.you_will_lose_followers": "All your followers from this server will be removed.", + "domain_block_modal.you_wont_see_posts": "You won't see posts or notifications from users on this server.", + "domain_pill.activitypub_lets_connect": "It lets you connect and interact with people not just on Mastodon, but across different social apps too.", + "domain_pill.activitypub_like_language": "ActivityPub is like the language Mastodon speaks with other social networks.", + "domain_pill.server": "Server", + "domain_pill.their_handle": "Their handle:", + "domain_pill.their_server": "Their digital home, where all of their posts live.", + "domain_pill.their_username": "Their unique identifier on their server. It’s possible to find users with the same username on different servers.", + "domain_pill.username": "Username", + "domain_pill.whats_in_a_handle": "What's in a handle?", + "domain_pill.who_they_are": "Since handles say who someone is and where they are, you can interact with people across the social web of .", + "domain_pill.who_you_are": "Because your handle says who you are and where you are, people can interact with you across the social web of .", + "domain_pill.your_handle": "Your handle:", + "domain_pill.your_server": "Your digital home, where all of your posts live. Don’t like this one? Transfer servers at any time and bring your followers, too.", + "domain_pill.your_username": "Your unique identifier on this server. It’s possible to find users with the same username on different servers.", "embed.instructions": "Embed this post on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activity", @@ -245,6 +266,7 @@ "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.", "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.", "empty_column.mutes": "You haven't muted any users yet.", + "empty_column.notification_requests": "All clear! There is nothing here. When you receive new notifications, they will appear here according to your settings.", "empty_column.notifications": "You don't have any notifications yet. When other people interact with you, you will see it here.", "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up", "error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.", @@ -275,13 +297,22 @@ "filter_modal.select_filter.subtitle": "Use an existing category or create a new one", "filter_modal.select_filter.title": "Filter this post", "filter_modal.title.status": "Filter a post", + "filtered_notifications_banner.mentions": "{count, plural, one {mention} other {mentions}}", + "filtered_notifications_banner.pending_requests": "Notifications from {count, plural, =0 {no one} one {one person} other {# people}} you may know", + "filtered_notifications_banner.title": "Filtered notifications", "firehose.all": "All", "firehose.local": "This server", "firehose.remote": "Other servers", "follow_request.authorize": "Authorise", "follow_request.reject": "Reject", "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.", + "follow_suggestions.curated_suggestion": "Staff pick", "follow_suggestions.dismiss": "Don't show again", + "follow_suggestions.hints.featured": "This profile has been hand-picked by the {domain} team.", + "follow_suggestions.hints.friends_of_friends": "This profile is popular among the people you follow.", + "follow_suggestions.hints.most_followed": "This profile is one of the most followed on {domain}.", + "follow_suggestions.hints.most_interactions": "This profile has been recently getting a lot of attention on {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "This profile is similar to the profiles you have most recently followed.", "follow_suggestions.personalized_suggestion": "Personalised suggestion", "follow_suggestions.popular_suggestion": "Popular suggestion", "follow_suggestions.view_all": "View all", @@ -397,6 +428,15 @@ "loading_indicator.label": "Loading…", "media_gallery.toggle_visible": "{number, plural, one {Hide image} other {Hide images}}", "moved_to_account_banner.text": "Your account {disabledAccount} is currently disabled because you moved to {movedToAccount}.", + "mute_modal.hide_from_notifications": "Hide from notifications", + "mute_modal.hide_options": "Hide options", + "mute_modal.indefinite": "Until I unmute them", + "mute_modal.show_options": "Show options", + "mute_modal.they_can_mention_and_follow": "They can mention and follow you, but you won't see them.", + "mute_modal.they_wont_know": "They won't know they've been muted.", + "mute_modal.title": "Mute user?", + "mute_modal.you_wont_see_mentions": "You won't see posts that mention them.", + "mute_modal.you_wont_see_posts": "They can still see your posts, but you won't see theirs.", "navigation_bar.about": "About", "navigation_bar.advanced_interface": "Open in advanced web interface", "navigation_bar.blocks": "Blocked users", @@ -432,14 +472,24 @@ "notification.own_poll": "Your poll has ended", "notification.poll": "A poll you have voted in has ended", "notification.reblog": "{name} boosted your status", + "notification.relationships_severance_event": "Lost connections with {name}", + "notification.relationships_severance_event.account_suspension": "An admin from {from} has suspended {target}, which means you can no longer receive updates from them or interact with them.", + "notification.relationships_severance_event.domain_block": "An admin from {from} has blocked {target}, including {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.", + "notification.relationships_severance_event.learn_more": "Learn more", + "notification.relationships_severance_event.user_domain_block": "You have blocked {target}, removing {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.", "notification.status": "{name} just posted", "notification.update": "{name} edited a post", + "notification_requests.accept": "Accept", + "notification_requests.dismiss": "Dismiss", + "notification_requests.notifications_from": "Notifications from {name}", + "notification_requests.title": "Filtered notifications", "notifications.clear": "Clear notifications", "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?", "notifications.column_settings.admin.report": "New reports:", "notifications.column_settings.admin.sign_up": "New sign-ups:", "notifications.column_settings.alert": "Desktop notifications", "notifications.column_settings.favourite": "Favourites:", + "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json index fd32d9d903..1d8d4cedf8 100644 --- a/app/javascript/mastodon/locales/es-MX.json +++ b/app/javascript/mastodon/locales/es-MX.json @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Usar una categoría existente o crear una nueva", "filter_modal.select_filter.title": "Filtrar esta publicación", "filter_modal.title.status": "Filtrar una publicación", + "filtered_notifications_banner.mentions": "{count, plural, one {mención} other {menciones}}", "filtered_notifications_banner.pending_requests": "Notificaciones de {count, plural, =0 {nadie} one {una persona} other {# personas}} que podrías conocer", "filtered_notifications_banner.title": "Notificaciones filtradas", "firehose.all": "Todas", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index 9c15a3cae4..68e5349a57 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Usar una categoría existente o crear una nueva", "filter_modal.select_filter.title": "Filtrar esta publicación", "filter_modal.title.status": "Filtrar una publicación", + "filtered_notifications_banner.mentions": "{count, plural, one {mención} other {menciones}}", "filtered_notifications_banner.pending_requests": "Notificaciones de {count, plural, =0 {nadie} one {una persona} other {# personas}} que podrías conocer", "filtered_notifications_banner.title": "Notificaciones filtradas", "firehose.all": "Todas", diff --git a/app/javascript/mastodon/locales/ia.json b/app/javascript/mastodon/locales/ia.json index af28f9ce37..e0ae8b58c6 100644 --- a/app/javascript/mastodon/locales/ia.json +++ b/app/javascript/mastodon/locales/ia.json @@ -42,6 +42,7 @@ "account.go_to_profile": "Vader al profilo", "account.hide_reblogs": "Celar impulsos de @{name}", "account.in_memoriam": "In memoriam.", + "account.joined_short": "Inscribite", "account.languages": "Cambiar le linguas subscribite", "account.link_verified_on": "Le proprietate de iste ligamine ha essite verificate le {date}", "account.locked_info": "Le stato de confidentialitate de iste conto es definite como serrate. Le proprietario determina manualmente qui pote sequer le.", @@ -52,10 +53,12 @@ "account.mute_notifications_short": "Silentiar le notificationes", "account.mute_short": "Silentiar", "account.muted": "Silentiate", + "account.mutual": "Mutue", "account.no_bio": "Nulle description fornite.", "account.open_original_page": "Aperir le pagina original", "account.posts": "Messages", "account.posts_with_replies": "Messages e responsas", + "account.report": "Signalar @{name}", "account.requested": "Attendente le approbation. Clicca pro cancellar le requesta de sequer", "account.requested_follow": "{name} ha requestate de sequer te", "account.share": "Compartir profilo de @{name}", @@ -70,29 +73,48 @@ "account.unmute_notifications_short": "Non plus silentiar le notificationes", "account.unmute_short": "Non plus silentiar", "account_note.placeholder": "Clicca pro adder un nota", + "admin.dashboard.daily_retention": "Retention de usatores per die post inscription", + "admin.dashboard.monthly_retention": "Retention de usatores per mense post inscription", "admin.dashboard.retention.average": "Media", + "admin.dashboard.retention.cohort": "Mense de inscription", "admin.dashboard.retention.cohort_size": "Nove usatores", + "admin.impact_report.instance_accounts": "Numero de contos que isto delerea", "admin.impact_report.instance_followers": "Sequitores que nostre usatores perderea", "admin.impact_report.instance_follows": "Sequitores que lor usatores perderea", + "admin.impact_report.title": "Summario de impacto", "alert.rate_limited.message": "Per favor retenta post {retry_time, time, medium}.", + "alert.rate_limited.title": "Excesso de requestas", "alert.unexpected.message": "Un error inexpectate ha occurrite.", + "alert.unexpected.title": "Ups!", "announcement.announcement": "Annuncio", + "attachments_list.unprocessed": "(non processate)", "audio.hide": "Celar audio", "block_modal.remote_users_caveat": "Nos demandera al servitor {domain} de respectar tu decision. Nonobstante, le conformitate non es garantite perque alcun servitores pote tractar le blocadas de maniera differente. Le messages public pote esser totevia visibile pro le usatores non authenticate.", "block_modal.show_less": "Monstrar minus", "block_modal.show_more": "Monstrar plus", + "block_modal.they_cant_mention": "Le persona non pote mentionar te o sequer te.", "block_modal.they_cant_see_posts": "Iste persona non potera vider tu messages e tu non videra le sues.", + "block_modal.they_will_know": "Le persona pote saper de esser blocate.", "block_modal.title": "Blocar usator?", "block_modal.you_wont_see_mentions": "Tu non videra le messages que mentiona iste persona.", "boost_modal.combo": "Tu pote premer {combo} pro saltar isto le proxime vice", + "bundle_column_error.copy_stacktrace": "Copiar reporto de error", + "bundle_column_error.error.body": "Le pagina requestate non pote esser visualisate. Pote esser a causa de un defecto in nostre codice o de un problema de compatibilitate del navigator.", "bundle_column_error.error.title": "Oh, no!", + "bundle_column_error.network.body": "Un error ha occurrite durante le cargamento de iste pagina. Isto pote esser a causa de un problema temporari con tu connexion a internet o con iste servitor.", "bundle_column_error.network.title": "Error de rete", "bundle_column_error.retry": "Tentar novemente", "bundle_column_error.return": "Retornar al initio", + "bundle_column_error.routing.body": "Le pagina requestate non pote esser trovate. Es tu secur que le URL in le barra de adresse es correcte?", + "bundle_column_error.routing.title": "404", "bundle_modal_error.close": "Clauder", + "bundle_modal_error.message": "Un error ha occurrite durante le cargamento de iste componente.", "bundle_modal_error.retry": "Tentar novemente", + "closed_registrations.other_server_instructions": "Perque Mastodon es decentralisate, tu pote crear un conto sur un altere servitor e totevia interager con iste servitor.", "closed_registrations_modal.description": "Crear un conto in {domain} actualmente non es possibile, ma considera que non es necessari haber un conto specificamente sur {domain} pro usar Mastodon.", "closed_registrations_modal.find_another_server": "Cercar un altere servitor", + "closed_registrations_modal.preamble": "Mastodon es decentralisate, dunque, non importa ubi tu crea tu conto, tu pote sequer e communicar con omne persona sur iste servitor. Tu pote mesmo hospitar tu proprie servitor!", + "closed_registrations_modal.title": "Crear un conto sur Mastodon", "column.about": "A proposito", "column.blocks": "Usatores blocate", "column.bookmarks": "Marcapaginas", @@ -102,6 +124,7 @@ "column.domain_blocks": "Dominios blocate", "column.favourites": "Favoritos", "column.firehose": "Fluxos in directo", + "column.follow_requests": "Requestas de sequimento", "column.home": "Initio", "column.lists": "Listas", "column.mutes": "Usatores silentiate", @@ -112,10 +135,13 @@ "column_header.hide_settings": "Celar le parametros", "column_header.moveLeft_settings": "Mover columna al sinistra", "column_header.moveRight_settings": "Mover columna al dextra", + "column_header.pin": "Fixar", "column_header.show_settings": "Monstrar le parametros", + "column_header.unpin": "Disfixar", "column_subheading.settings": "Parametros", "community.column_settings.local_only": "Solmente local", "community.column_settings.media_only": "Solmente multimedia", + "community.column_settings.remote_only": "A distantia solmente", "compose.language.change": "Cambiar le lingua", "compose.language.search": "Cercar linguas...", "compose.published.body": "Message publicate.", @@ -126,6 +152,7 @@ "compose_form.hashtag_warning": "Iste message non essera listate sub alcun hashtag perque illo non es public. Solmente le messages public pote esser cercate per hashtag.", "compose_form.lock_disclaimer": "Tu conto non es {locked}. Quicunque pote sequer te pro vider tu messages solo pro sequitores.", "compose_form.lock_disclaimer.lock": "serrate", + "compose_form.placeholder": "Que ha tu in mente?", "compose_form.poll.duration": "Durata del sondage", "compose_form.poll.multiple": "Selection multiple", "compose_form.poll.option_placeholder": "Option {number}", @@ -148,13 +175,19 @@ "confirmations.delete.message": "Es tu secur que tu vole deler iste message?", "confirmations.delete_list.confirm": "Deler", "confirmations.delete_list.message": "Es tu secur que tu vole deler permanentemente iste lista?", + "confirmations.discard_edit_media.confirm": "Abandonar", + "confirmations.discard_edit_media.message": "Tu ha cambiamentos non salvate in le description o previsualisation del objecto multimedial. Abandonar los?", "confirmations.domain_block.confirm": "Blocar le servitor", + "confirmations.domain_block.message": "Es tu realmente, absolutemente secur de voler blocar tote le dominio {domain}? In le major parte del casos es preferibile blocar o silentiar alcun personas specific. Si tu bloca tote le dominio, tu non videra alcun contento de ille dominio in alcun chronologia public o in tu notificationes, e tu sequitores de ille dominio essera removite.", "confirmations.edit.confirm": "Modificar", + "confirmations.edit.message": "Si tu modifica isto ora, le message in curso de composition essera perdite. Es tu secur de voler continuar?", "confirmations.logout.confirm": "Clauder session", "confirmations.logout.message": "Es tu secur que tu vole clauder le session?", "confirmations.mute.confirm": "Silentiar", + "confirmations.redraft.confirm": "Deler e rescriber", "confirmations.redraft.message": "Es tu secur de voler deler iste message e rescriber lo? Le favorites e le impulsos essera perdite, e le responsas al message original essera orphanate.", "confirmations.reply.confirm": "Responder", + "confirmations.reply.message": "Si tu responde ora, le message in curso de composition essera perdite. Es tu secur de voler continuar?", "confirmations.unfollow.confirm": "Non plus sequer", "confirmations.unfollow.message": "Es tu secur que tu vole cessar de sequer {name}?", "conversation.delete": "Deler conversation", @@ -174,6 +207,7 @@ "dismissable_banner.dismiss": "Dimitter", "dismissable_banner.explore_links": "Istes es le articulos de novas que se condivide le plus sur le rete social hodie. Le articulos de novas le plus recente, publicate per plus personas differente, se classifica plus in alto.", "dismissable_banner.explore_statuses": "Ecce le messages de tote le rete social que gania popularitate hodie. Le messages plus nove con plus impulsos e favorites se classifica plus in alto.", + "dismissable_banner.explore_tags": "Ecce le hashtags que gania popularitate sur le rete social hodie. Le hashtags usate per plus personas differente se classifica plus in alto.", "dismissable_banner.public_timeline": "Istes es le messages public le plus recente del personas sur le rete social que le gente sur {domain} seque.", "domain_block_modal.block": "Blocar le servitor", "domain_block_modal.block_account_instead": "Blocar @{name} in su loco", @@ -183,10 +217,19 @@ "domain_block_modal.title": "Blocar dominio?", "domain_block_modal.you_will_lose_followers": "Omne sequitores ab iste servitor essera removite.", "domain_block_modal.you_wont_see_posts": "Tu non videra messages e notificationes ab usatores sur iste servitor.", + "domain_pill.activitypub_lets_connect": "Illo te permitte connecter e interager con personas non solmente sur Mastodon, ma tamben sur altere applicationes social.", + "domain_pill.activitypub_like_language": "ActivityPub es como le linguage commun que Mastodon parla con altere retes social.", "domain_pill.server": "Servitor", + "domain_pill.their_handle": "Su pseudonymo:", "domain_pill.their_server": "Su casa digital, ubi vive tote su messages.", + "domain_pill.their_username": "Su identificator unic sur su servitor. Es possibile trovar usatores con le mesme nomine de usator sur servitores differente.", "domain_pill.username": "Nomine de usator", + "domain_pill.whats_in_a_handle": "Que significa un pseudonymo?", + "domain_pill.who_they_are": "Un pseudonymo indica qui un persona es e ubi se trova, de maniera que tu pote interager con personas sur tote le rete social de .", + "domain_pill.who_you_are": "Perque tu pseudonymo indica qui tu es e ubi tu te trova, le gente pote interager con te desde tote le rete social de .", + "domain_pill.your_handle": "Tu pseudonymo:", "domain_pill.your_server": "Tu casa digital, ubi vive tote tu messages. Non te place? Cambia de servitor a omne momento e porta tu sequitores con te.", + "domain_pill.your_username": "Tu identificator unic sur iste servitor. Es possibile trovar usatores con le mesme nomine de usator sur servitores differente.", "embed.instructions": "Incorpora iste message sur tu sito web con le codice sequente.", "embed.preview": "Ecce como illlo parera:", "emoji_button.activity": "Activitate", @@ -196,6 +239,8 @@ "emoji_button.food": "Alimentos e bibitas", "emoji_button.label": "Inserer emoji", "emoji_button.nature": "Natura", + "emoji_button.not_found": "Necun emoji correspondente trovate", + "emoji_button.objects": "Objectos", "emoji_button.people": "Personas", "emoji_button.recent": "Frequentemente usate", "emoji_button.search": "Cercar...", @@ -208,14 +253,27 @@ "empty_column.account_unavailable": "Profilo non disponibile", "empty_column.blocks": "Tu non ha blocate alcun usator ancora.", "empty_column.bookmarked_statuses": "Tu non ha ancora messages in marcapaginas. Quando tu adde un message al marcapaginas, illo apparera hic.", + "empty_column.community": "Le chronologia local es vacue. Scribe qualcosa public pro poner le cosas in marcha!", + "empty_column.direct": "Tu non ha ancora mentiones private. Quando tu invia o recipe un mention, illo apparera hic.", "empty_column.domain_blocks": "Il non ha dominios blocate ancora.", "empty_column.explore_statuses": "Il non ha tendentias in iste momento. Reveni plus tarde!", "empty_column.favourited_statuses": "Tu non ha alcun message favorite ancora. Quando tu marca un message como favorite, illo apparera hic.", "empty_column.favourites": "Necuno ha ancora marcate iste message como favorite. Quando alcuno lo face, ille apparera hic.", + "empty_column.follow_requests": "Tu non ha ancora requestas de sequimento. Quando tu recipe un, illo apparera hic.", "empty_column.followed_tags": "Tu non ha ancora sequite alcun hashtags. Quando tu lo face, illos apparera hic.", "empty_column.hashtag": "Il non ha ancora alcun cosa in iste hashtag.", "empty_column.home": "Tu chronologia de initio es vacue! Seque plus personas pro plenar lo.", "empty_column.list": "Iste lista es ancora vacue. Quando le membros de iste lista publica nove messages, illos apparera hic.", + "empty_column.lists": "Tu non ha ancora listas. Quando tu crea un, illo apparera hic.", + "empty_column.mutes": "Tu non ha ancora silentiate alcun usator.", + "empty_column.notification_requests": "Iste lista es toto vacue! Quando tu recipe notificationes, illos apparera hic como configurate in tu parametros.", + "empty_column.notifications": "Tu non ha ancora notificationes. Quando altere personas interage con te, tu lo videra hic.", + "empty_column.public": "Il ha nihil hic! Scribe qualcosa public, o manualmente seque usatores de altere servitores, pro plenar lo", + "error.unexpected_crash.explanation": "A causa de un defecto in nostre codice o de un problema de compatibilitate del navigator, iste pagina non pote esser visualisate correctemente.", + "error.unexpected_crash.explanation_addons": "Iste pagina non pote esser visualisate correctemente. Iste error es probabilemente causate per un additivo al navigator o per un utensile de traduction automatic.", + "error.unexpected_crash.next_steps": "Tenta refrescar le pagina. Si isto non remedia le problema, es possibile que tu pote totevia usar Mastodon per medio de un altere navigator o application native.", + "error.unexpected_crash.next_steps_addons": "Tenta disactivar istes e refrescar le pagina. Si isto non remedia le problema, es possibile que tu pote totevia usar Mastodon per medio de un altere navigator o application native.", + "errors.unexpected_crash.copy_stacktrace": "Copiar le traciamento del pila al area de transferentia", "errors.unexpected_crash.report_issue": "Signalar un defecto", "explore.search_results": "Resultatos de recerca", "explore.suggested_follows": "Personas", @@ -224,23 +282,42 @@ "explore.trending_statuses": "Messages", "explore.trending_tags": "Hashtags", "filter_modal.added.context_mismatch_explanation": "Iste categoria de filtros non se applica al contexto in le qual tu ha accedite a iste message. Pro filtrar le message in iste contexto tamben, modifica le filtro.", + "filter_modal.added.context_mismatch_title": "Contexto incoherente!", + "filter_modal.added.expired_explanation": "Iste categoria de filtros ha expirate. Tu debe modificar le data de expiration pro applicar lo.", + "filter_modal.added.expired_title": "Filtro expirate!", + "filter_modal.added.review_and_configure": "Pro revider e configurar ulteriormente iste categoria de filtros, visita le {settings_link}.", "filter_modal.added.review_and_configure_title": "Parametros de filtro", "filter_modal.added.settings_link": "pagina de parametros", "filter_modal.added.short_explanation": "Iste message ha essite addite al sequente categoria de filtros: {title}.", "filter_modal.added.title": "Filtro addite!", + "filter_modal.select_filter.context_mismatch": "non se applica a iste contexto", + "filter_modal.select_filter.expired": "expirate", "filter_modal.select_filter.prompt_new": "Nove categoria: {name}", "filter_modal.select_filter.search": "Cercar o crear", + "filter_modal.select_filter.subtitle": "Usa un categoria existente o crea un nove", "filter_modal.select_filter.title": "Filtrar iste message", "filter_modal.title.status": "Filtrar un message", + "filtered_notifications_banner.mentions": "{count, plural, one {mention} other {mentiones}}", "filtered_notifications_banner.pending_requests": "Notificationes ab {count, plural, =0 {nemo} one {un persona} other {# personas}} tu poterea cognoscer", + "filtered_notifications_banner.title": "Notificationes filtrate", "firehose.all": "Toto", "firehose.local": "Iste servitor", "firehose.remote": "Altere servitores", + "follow_request.authorize": "Autorisar", "follow_request.reject": "Rejectar", + "follow_requests.unlocked_explanation": "Benque tu conto non es serrate, le personal de {domain} pensa que es un bon idea que tu revide manualmente le sequente requestas de iste contos.", + "follow_suggestions.curated_suggestion": "Selection del equipa", "follow_suggestions.dismiss": "Non monstrar novemente", + "follow_suggestions.hints.featured": "Iste profilo ha essite seligite manualmente per le equipa de {domain}.", + "follow_suggestions.hints.friends_of_friends": "Iste profilo es popular inter le gente que tu seque.", + "follow_suggestions.hints.most_followed": "Iste profilo es un del plus sequites sur {domain}.", + "follow_suggestions.hints.most_interactions": "Iste profilo ha recentemente recipite multe attention sur {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Iste profilo es similar al profilos que tu ha recentemente sequite.", "follow_suggestions.personalized_suggestion": "Suggestion personalisate", "follow_suggestions.popular_suggestion": "Suggestion personalisate", "follow_suggestions.view_all": "Vider toto", + "follow_suggestions.who_to_follow": "Qui sequer", + "followed_tags": "Hashtags sequite", "footer.about": "A proposito", "footer.directory": "Directorio de profilos", "footer.get_app": "Obtener le application", @@ -256,6 +333,11 @@ "hashtag.column_header.tag_mode.none": "sin {additional}", "hashtag.column_settings.select.no_options_message": "Nulle suggestiones trovate", "hashtag.column_settings.select.placeholder": "Insere hashtags…", + "hashtag.column_settings.tag_mode.all": "Tote istes", + "hashtag.column_settings.tag_mode.any": "Un o plus de istes", + "hashtag.column_settings.tag_mode.none": "Necun de istes", + "hashtag.column_settings.tag_toggle": "Includer etiquettas additional pro iste columna", + "hashtag.counter_by_accounts": "{count, plural, one {{counter} participante} other {{counter} participantes}}", "hashtag.counter_by_uses": "{count, plural, one {{counter} message} other {{counter} messages}}", "hashtag.counter_by_uses_today": "{count, plural, one {{counter} message} other {{counter} messages}} hodie", "hashtag.follow": "Sequer hashtag", @@ -277,13 +359,22 @@ "interaction_modal.no_account_yet": "Non sur Mstodon?", "interaction_modal.on_another_server": "Sur un altere servitor", "interaction_modal.on_this_server": "Sur iste servitor", + "interaction_modal.sign_in": "Tu non es in session sur iste servitor. Sur qual servitor se trova tu conto?", + "interaction_modal.sign_in_hint": "Consilio: Se tracta del sito web ubi tu te ha inscribite. Si tu non te lo rememora, cerca le e-mail de benvenita in tu cassa de entrata. Tu pote etiam inserer tu pseudonymo complete! (p.ex. @Mastodon@mastodon.social)", "interaction_modal.title.favourite": "Marcar le message de {name} como favorite", "interaction_modal.title.follow": "Sequer {name}", "interaction_modal.title.reblog": "Impulsar le message de {name}", "interaction_modal.title.reply": "Responder al message de {name}", + "intervals.full.days": "{number, plural, one {# die} other {# dies}}", + "intervals.full.hours": "{number, plural, one {# hora} other {# horas}}", + "intervals.full.minutes": "{number, plural, one {# minuta} other {# minutas}}", + "keyboard_shortcuts.back": "Navigar retro", "keyboard_shortcuts.blocked": "Aperir lista de usatores blocate", "keyboard_shortcuts.boost": "Impulsar le message", + "keyboard_shortcuts.column": "Focalisar al columna", + "keyboard_shortcuts.compose": "Focalisar al area de composition de texto", "keyboard_shortcuts.description": "Description", + "keyboard_shortcuts.direct": "aperir le columna de mentiones private", "keyboard_shortcuts.enter": "Aperir message", "keyboard_shortcuts.favourite": "Message favorite", "keyboard_shortcuts.favourites": "Aperir lista de favoritos", diff --git a/config/locales/cs.yml b/config/locales/cs.yml index b44b01beee..bccbb75c4d 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -621,6 +621,9 @@ cs: actions_description_html: Rozhodněte, který krok učinit pro vyřešení tohoto hlášení. Pokud podniknete kárný krok proti nahlášenému účtu, bude mu zasláno e-mailové oznámení, s výjimkou případu, kdy je zvolena kategorie Spam. actions_description_remote_html: Rozhodněte, co podniknout pro vyřešení tohoto hlášení. Toto ovlivní pouze to, jak váš server komunikuje s tímto vzdáleným účtem, a zpracuje jeho obsah. add_to_report: Přidat do hlášení další + already_suspended_badges: + local: Již pozastaveno na tomto serveru + remote: Již pozastaveno na jejich serveru are_you_sure: Jste si jisti? assign_to_self: Přidělit ke mně assigned: Přiřazený moderátor @@ -1704,13 +1707,26 @@ cs: import: Import import_and_export: Import a export migrate: Přesun účtu + notifications: E-mailová upozornění preferences: Předvolby profile: Profil relationships: Sledovaní a sledující + severed_relationships: Přerušené vztahy statuses_cleanup: Automatické mazání příspěvků strikes: Moderační prohřešky two_factor_authentication: Dvoufázové ověřování webauthn_authentication: Bezpečnostní klíče + severed_relationships: + download: Stáhnout (%{count}) + event_type: + account_suspension: Pozastavení účtu (%{target_name}) + domain_block: Pozastavení serveru (%{target_name}) + user_domain_block: Zablokovali jste %{target_name} + lost_followers: Ztracení sledující + lost_follows: Ztracená sledování + preamble: Když zablokujete doménu nebo když se moderátoři rozhodnou pozastavit vzdálený server, můžete přijít o sledování a sledující. Když k tomu dojde, budete si moci stáhnout seznamy přerušených vztahů, abyste je mohli zkontrolovat a případně importovat na jiný server. + purged: Informace o tomto serveru byly správci serveru vymazány. + type: Událost statuses: attached: audio: @@ -1816,6 +1832,7 @@ cs: contrast: Mastodon (vysoký kontrast) default: Mastodon (tmavý) mastodon-light: Mastodon (světlý) + system: Automaticky (dle motivu systému) time: formats: default: "%d. %b %Y, %H:%M" @@ -1903,7 +1920,46 @@ cs: silence: Účet omezen suspend: Účet pozastaven welcome: + apps_android_action: Získejte na Google Play + apps_ios_action: Stáhnout z App Store + apps_step: Stáhněte si naše oficiální aplikace. + apps_title: Aplikace Mastodon + checklist_subtitle: 'Začněme na této nové sociální hranici:' + checklist_title: Uvítací kontrolní seznam + edit_profile_action: Přizpůsobit + edit_profile_step: Zlepšete své interakce tím, že si vytvoříte komplexní profil. + edit_profile_title: Přizpůsobte si svůj profil explanation: Zde je pár tipů do začátku + feature_action: Zjistit více + feature_audience: Mastodon vám nabízí jedinečnou možnost správy publika bez prostředníků. Mastodon nasazený na vaší vlastní infrastruktuře vám umožňuje sledovat a být sledován z jakéhokoli jiného Mastodon serveru online a není pod kontrolou nikoho jiného než vás. + feature_audience_title: Vytvořte si svědomě své publikum + feature_control: Sami nejlépe víte, co chcete vidět na svém domovském kanálu. Žádné algoritmy ani reklamy, které by plýtvaly vaším časem. Sledujte kohokoli z libovolného Mastodon serveru z jediného účtu, dostávejte jejich příspěvky v chronologickém pořadí a udělejte si svůj kout internetu trochu více podle sebe. + feature_control_title: Mějte pod kontrolou vlastní časovou osu + feature_creativity: Mastodon podporuje zvukové, video a obrázkové příspěvky, popisy přístupnosti, ankety, upozornění na obsah, animované avatary, vlastní emotikony, ovládání ořezu miniatur a další funkce, které vám pomohou vyjádřit se online. Ať už publikujete své umění, hudbu nebo podcast, Mastodon je tu pro vás. + feature_creativity_title: Bezkonkurenční kreativita + feature_moderation: Mastodon dává rozhodování zpět do vašich rukou. Každý server si vytváří svá vlastní pravidla a předpisy, které jsou prosazovány lokálně, nikoli shora jako v případě firemních sociálních médií, díky čemuž lze nejpružněji reagovat na potřeby různých skupin lidí. Připojte se k serveru s pravidly, se kterými souhlasíte, nebo si založte vlastní. + feature_moderation_title: Moderování způsobem, jakým by to mělo být + follow_action: Sledovat + follow_step: Mastodon je o sledování zajimavých lidí. + follow_title: Přizpůsobte si svůj domovský kanál + follows_subtitle: Sledujte známé účty + follows_title: Koho sledovat + follows_view_more: Zobrazit více lidí ke sledování + hashtags_recent_count: + few: "%{people} osoby v posledních 2 dnech" + many: "%{people} osob v posledních 2 dnech" + one: "%{people} osoba v posledních 2 dnech" + other: "%{people} osob v posledních 2 dnech" + hashtags_subtitle: Prozkoumejte, co je populární od posledních 2 dnů + hashtags_title: Populární hashtagy + hashtags_view_more: Zobrazit více populárních hashtagů + post_action: Sepsat + post_step: Řekněte světu ahoj pomocí textu, fotografií, videí nebo anket. + post_title: Vytvořte svůj první příspěvek + share_action: Sdílet + share_step: Dejte přátelům vědět, jak vás mohou na Mastodonu najít. + share_title: Sdílejte svůj Mastodon profil + sign_in_action: Přihlásit se subject: Vítejte na Mastodonu title: Vítejte na palubě, %{name}! users: diff --git a/config/locales/eu.yml b/config/locales/eu.yml index 523b601978..a05aa3c92f 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -1241,7 +1241,7 @@ eu: add_new: Gehitu berria errors: limit: Gehienezko traola kopurua erakutsi duzu jada - hint_html: "Zer dira nabarmendutako traolak? Zure profilean toki nabarmendu batean agertzen dira eta jendeari traola hau daukaten bidalketa publikoak arakatzea ahalbidetzen diote. Sormen lana edo epe luzerako proiektuak jarraitzeko primerakoak dira." + hint_html: "Zer dira nabarmendutako traolak? Zure profileko toki nabarmendu batean agertzen dira eta jendeari traola haue dituzten bidalketa publikoak arakatzea ahalbidetzen diote. Sormen-lanak edo epe luzerako proiektuak jarraitzeko primerakoak dira." filters: contexts: account: Profilak @@ -1910,7 +1910,7 @@ eu: signed_in_as: 'Saioa honela hasita:' verification: extra_instructions_html: Aholkua: webguneko esteka ikusezina izan daiteke. Muina rel="me" da, erabiltzaileak sortutako edukia duten webguneetan beste inor zure burutzat aurkeztea eragozten duena. a beharrean esteka motako etiketa bat ere erabil dezakezu orriaren goiburuan, baina HTMLak erabilgarri egon behar du JavaScript exekutatu gabe. - here_is_how: Hemen duzu nola + here_is_how: Argibidea hint_html: "Mastodonen nortasun-egiaztapena guztiontzat da. Web estandar irekietan oinarritua, orain eta betiko doan. Behar duzun guztia jendeak ezagutzen duen webgune pertsonal bat da. Mastodon profiletik webgune honetara estekatzen duzunean, webguneak Mastodon profilera estekatzen duela egiaztatuko dugu eta adierazle bat erakutsiko du." instructions_html: Kopiatu eta itsatsi ondoko kodea zure webguneko HTMLan. Ondoren, gehitu zure webgunearen helbidea zure profileko eremu gehigarrietako batean, "Editatu profila" fitxatik eta gorde aldaketak. verification: Egiaztaketa diff --git a/config/locales/simple_form.cs.yml b/config/locales/simple_form.cs.yml index ca8cc49a98..f91f826730 100644 --- a/config/locales/simple_form.cs.yml +++ b/config/locales/simple_form.cs.yml @@ -116,6 +116,7 @@ cs: sign_up_requires_approval: Nové registrace budou vyžadovat schválení severity: Zvolte, jak naložit s požadavky z dané IP rule: + hint: Nepovinné. Uveďte další podrobnosti o pravidle text: Popište pravidlo nebo požadavek uživatelům tohoto serveru. Snažte se ho držet krátký a jednoduchý sessions: otp: 'Zadejte kód pro dvoufázové ověření vygenerovaný vaší mobilní aplikací, nebo použijte jeden z vašich záložních kódů:' @@ -299,6 +300,7 @@ cs: patch: Upozornit na aktualizace chyb trending_tag: Nový trend vyžaduje posouzení rule: + hint: Další informace text: Pravidlo settings: indexable: Zahrnout stránku profilu do vyhledávačů From 75f9c652e21c0fbb76c90820646b66516d12ad9b Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 18 Apr 2024 12:24:22 -0400 Subject: [PATCH 10/13] Fix `Bundler/OrderedGems` cop (#28400) --- .rubocop_todo.yml | 7 ------- Gemfile | 30 +++++++++++++++--------------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 63d9d67574..9ca7ba6f11 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,13 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation, Include. -# Include: **/*.gemfile, **/Gemfile, **/gems.rb -Bundler/OrderedGems: - Exclude: - - 'Gemfile' - Lint/NonLocalExitFromIterator: Exclude: - 'app/helpers/jsonld_helper.rb' diff --git a/Gemfile b/Gemfile index 35e0b29280..3361f2dc33 100644 --- a/Gemfile +++ b/Gemfile @@ -3,26 +3,26 @@ source 'https://rubygems.org' ruby '>= 3.1.0' -gem 'puma', '~> 6.3' -gem 'rails', '~> 7.1.1' gem 'propshaft' -gem 'thor', '~> 1.2' +gem 'puma', '~> 6.3' gem 'rack', '~> 2.2.7' +gem 'rails', '~> 7.1.1' +gem 'thor', '~> 1.2' # For why irb is in the Gemfile, see: https://ruby.social/@st0012/111444685161478182 gem 'irb', '~> 1.8' +gem 'dotenv-rails', '~> 2.8' gem 'haml-rails', '~>2.0' gem 'pg', '~> 1.5' gem 'pghero' -gem 'dotenv-rails', '~> 2.8' gem 'aws-sdk-s3', '~> 1.123', require: false +gem 'blurhash', '~> 0.1' gem 'fog-core', '<= 2.4.0' gem 'fog-openstack', '~> 1.0', require: false gem 'kt-paperclip', '~> 7.2' gem 'md-paperclip-azure', '~> 2.2', require: false -gem 'blurhash', '~> 0.1' gem 'active_model_serializers', '~> 0.10' gem 'addressable', '~> 2.8' @@ -39,11 +39,11 @@ end gem 'net-ldap', '~> 0.18' -gem 'omniauth-cas', '~> 3.0.0.beta.1' -gem 'omniauth-saml', '~> 2.0' -gem 'omniauth_openid_connect', '~> 0.6.1' gem 'omniauth', '~> 2.0' +gem 'omniauth-cas', '~> 3.0.0.beta.1' +gem 'omniauth_openid_connect', '~> 0.6.1' gem 'omniauth-rails_csrf_protection', '~> 1.0' +gem 'omniauth-saml', '~> 2.0' gem 'color_diff', '~> 0.1' gem 'csv', '~> 3.2' @@ -53,7 +53,6 @@ gem 'ed25519', '~> 1.3' gem 'fast_blank', '~> 1.0' gem 'fastimage' gem 'hiredis', '~> 0.6' -gem 'redis-namespace', '~> 1.10' gem 'htmlentities', '~> 4.3' gem 'http', '~> 5.1' gem 'http_accept_language', '~> 2.1' @@ -63,39 +62,40 @@ gem 'idn-ruby', require: 'idn' gem 'inline_svg' gem 'kaminari', '~> 1.2' gem 'link_header', '~> 0.0' +gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock' gem 'mime-types', '~> 3.5.0', require: 'mime/types/columnar' gem 'nokogiri', '~> 1.15' gem 'nsa' gem 'oj', '~> 3.14' gem 'ox', '~> 2.14' gem 'parslet' +gem 'premailer-rails' gem 'public_suffix', '~> 5.0' gem 'pundit', '~> 2.3' -gem 'premailer-rails' gem 'rack-attack', '~> 6.6' gem 'rack-cors', '~> 2.0', require: 'rack/cors' gem 'rails-i18n', '~> 7.0' gem 'redcarpet', '~> 3.6' gem 'redis', '~> 4.5', require: ['redis', 'redis/connection/hiredis'] -gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock' +gem 'redis-namespace', '~> 1.10' gem 'rqrcode', '~> 2.2' gem 'ruby-progressbar', '~> 1.13' gem 'sanitize', '~> 6.0' gem 'scenic', '~> 1.7' gem 'sidekiq', '~> 6.5' +gem 'sidekiq-bulk', '~> 0.2.0' gem 'sidekiq-scheduler', '~> 5.0' gem 'sidekiq-unique-jobs', '~> 7.1' -gem 'sidekiq-bulk', '~> 0.2.0' -gem 'simple-navigation', '~> 4.4' gem 'simple_form', '~> 5.2' +gem 'simple-navigation', '~> 4.4' gem 'stoplight', '~> 4.1' gem 'strong_migrations', '1.8.0' gem 'tty-prompt', '~> 0.23', require: false gem 'twitter-text', '~> 3.1.0' gem 'tzinfo-data', '~> 1.2023' +gem 'webauthn', '~> 3.0' gem 'webpacker', '~> 5.4' gem 'webpush', github: 'ClearlyClaire/webpush', ref: 'f14a4d52e201128b1b00245d11b6de80d6cfdcd9' -gem 'webauthn', '~> 3.0' gem 'json-ld' gem 'json-ld-preloaded', '~> 3.2' @@ -197,10 +197,10 @@ group :production do gem 'lograge', '~> 0.12' end +gem 'cocoon', '~> 1.2' gem 'concurrent-ruby', require: false gem 'connection_pool', require: false gem 'xorcist', '~> 1.1' -gem 'cocoon', '~> 1.2' gem 'net-http', '~> 0.4.0' gem 'rubyzip', '~> 2.3' From e5d5bd7ff114c43babc4ca563112bf31c5fee65a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Apr 2024 18:24:55 +0200 Subject: [PATCH 11/13] Update dependency postcss-preset-env to v9.5.6 (#29983) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index bf217a074f..c0d1e91b62 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6481,14 +6481,14 @@ __metadata: languageName: node linkType: hard -"css-blank-pseudo@npm:^6.0.1": - version: 6.0.1 - resolution: "css-blank-pseudo@npm:6.0.1" +"css-blank-pseudo@npm:^6.0.2": + version: 6.0.2 + resolution: "css-blank-pseudo@npm:6.0.2" dependencies: postcss-selector-parser: "npm:^6.0.13" peerDependencies: postcss: ^8.4 - checksum: 10c0/04f2dc1c39a429cb4958b60a9d00b03e29a78e3e55fe111b3a0660b7c6c478455d5907eda7c7a495cf72dbe83ae3c80b409e0468ca1ba5ccef992e69a8f49df8 + checksum: 10c0/609303551c2a518ca23ed12fed43945ca4f7af04140da68a5536f5dc9d42f33412c13ac3fe5c616d7401a9e13a23d80b4cfa87149a45f94b244d8067bb11f3dd languageName: node linkType: hard @@ -13620,8 +13620,8 @@ __metadata: linkType: hard "postcss-preset-env@npm:^9.5.2": - version: 9.5.5 - resolution: "postcss-preset-env@npm:9.5.5" + version: 9.5.6 + resolution: "postcss-preset-env@npm:9.5.6" dependencies: "@csstools/postcss-cascade-layers": "npm:^4.0.4" "@csstools/postcss-color-function": "npm:^3.0.13" @@ -13654,7 +13654,7 @@ __metadata: "@csstools/postcss-unset-value": "npm:^3.0.1" autoprefixer: "npm:^10.4.19" browserslist: "npm:^4.22.3" - css-blank-pseudo: "npm:^6.0.1" + css-blank-pseudo: "npm:^6.0.2" css-has-pseudo: "npm:^6.0.3" css-prefers-color-scheme: "npm:^9.0.1" cssdb: "npm:^8.0.0" @@ -13685,7 +13685,7 @@ __metadata: postcss-selector-not: "npm:^7.0.2" peerDependencies: postcss: ^8.4 - checksum: 10c0/afc31fb75bc5e8e223d38fd34b81da08ee340818f5e392df1781728f2ff2a9dbc75e458673ce9f52deafefa90bbc99e0bd1453271498f5e02746c785180bad07 + checksum: 10c0/21738ecac400cca9a96841959308538516ed00ca80d4c53beb20e080c7d963120fa77b7435b02e1beefc20043abce666419b81eccf6dacdc4298f540778c111d languageName: node linkType: hard From 4837bfcc6ab38dc86c619167b7c2e260a92a270a Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 19 Apr 2024 09:57:32 -0400 Subject: [PATCH 12/13] Use shared `form` partial for `admin/announcements` views (#29608) --- app/views/admin/announcements/_form.html.haml | 28 +++++++++++++++ app/views/admin/announcements/edit.html.haml | 35 +++--------------- app/views/admin/announcements/new.html.haml | 36 +++---------------- 3 files changed, 38 insertions(+), 61 deletions(-) create mode 100644 app/views/admin/announcements/_form.html.haml diff --git a/app/views/admin/announcements/_form.html.haml b/app/views/admin/announcements/_form.html.haml new file mode 100644 index 0000000000..3a9b371907 --- /dev/null +++ b/app/views/admin/announcements/_form.html.haml @@ -0,0 +1,28 @@ +.fields-group + = form.input :starts_at, + html5: true, + include_blank: true, + input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder }, + wrapper: :with_block_label + = form.input :ends_at, + html5: true, + include_blank: true, + input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder }, + wrapper: :with_block_label + +.fields-group + = form.input :all_day, + as: :boolean, + wrapper: :with_label + +.fields-group + = form.input :text, + wrapper: :with_block_label + +- unless form.object.published? + .fields-group + = form.input :scheduled_at, + html5: true, + include_blank: true, + input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder }, + wrapper: :with_block_label diff --git a/app/views/admin/announcements/edit.html.haml b/app/views/admin/announcements/edit.html.haml index 23c568a885..8cec7d36c2 100644 --- a/app/views/admin/announcements/edit.html.haml +++ b/app/views/admin/announcements/edit.html.haml @@ -1,37 +1,12 @@ - content_for :page_title do = t('.title') -= simple_form_for @announcement, url: admin_announcement_path(@announcement), html: { novalidate: false } do |f| += simple_form_for @announcement, url: admin_announcement_path(@announcement), html: { novalidate: false } do |form| = render 'shared/error_messages', object: @announcement - .fields-group - = f.input :starts_at, - html5: true, - include_blank: true, - input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder }, - wrapper: :with_block_label - = f.input :ends_at, - html5: true, - include_blank: true, - input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder }, - wrapper: :with_block_label - - .fields-group - = f.input :all_day, - as: :boolean, - wrapper: :with_label - - .fields-group - = f.input :text, - wrapper: :with_block_label - - - unless @announcement.published? - .fields-group - = f.input :scheduled_at, - html5: true, - include_blank: true, - input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder }, - wrapper: :with_block_label + = render form .actions - = f.button :button, t('generic.save_changes'), type: :submit + = form.button :button, + t('generic.save_changes'), + type: :submit diff --git a/app/views/admin/announcements/new.html.haml b/app/views/admin/announcements/new.html.haml index a681ed789e..266ca65e80 100644 --- a/app/views/admin/announcements/new.html.haml +++ b/app/views/admin/announcements/new.html.haml @@ -1,38 +1,12 @@ - content_for :page_title do = t('.title') -= simple_form_for @announcement, url: admin_announcements_path, html: { novalidate: false } do |f| += simple_form_for @announcement, url: admin_announcements_path, html: { novalidate: false } do |form| = render 'shared/error_messages', object: @announcement - .fields-group - = f.input :starts_at, - html5: true, - include_blank: true, - input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder }, - wrapper: :with_block_label - = f.input :ends_at, - html5: true, - include_blank: true, - input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder }, - wrapper: :with_block_label - - .fields-group - = f.input :all_day, - as: :boolean, - wrapper: :with_label - - .fields-group - = f.input :text, - wrapper: :with_block_label - - .fields-group - = f.input :scheduled_at, - html5: true, - include_blank: true, - input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder }, - wrapper: :with_block_label + = render form .actions - = f.button :button, - t('.create'), - type: :submit + = form.button :button, + t('.create'), + type: :submit From ec71c02c4b028c3541742f023729aeb295a51559 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 15:57:43 +0200 Subject: [PATCH 13/13] New Crowdin Translations (automated) (#29994) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/cs.json | 29 +++++++++++++++++++++++++ app/javascript/mastodon/locales/th.json | 1 + app/javascript/mastodon/locales/tr.json | 4 ++-- config/locales/fi.yml | 6 ++--- config/locales/ko.yml | 8 +++---- 5 files changed, 39 insertions(+), 9 deletions(-) diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json index f55caf14b5..2fc01f3acc 100644 --- a/app/javascript/mastodon/locales/cs.json +++ b/app/javascript/mastodon/locales/cs.json @@ -297,6 +297,8 @@ "filter_modal.select_filter.subtitle": "Použít existující kategorii nebo vytvořit novou kategorii", "filter_modal.select_filter.title": "Filtrovat tento příspěvek", "filter_modal.title.status": "Filtrovat příspěvek", + "filtered_notifications_banner.mentions": "{count, plural, one {zmínka} few {zmínky} many {zmínek} other {zmínek}}", + "filtered_notifications_banner.pending_requests": "Oznámení od {count, plural, =0 {nikoho} one {jednoho člověka, kterého znáte} few {# lidí, které znáte} many {# lidí, které znáte} other {# lidí, které znáte}}", "filtered_notifications_banner.title": "Filtrovaná oznámení", "firehose.all": "Vše", "firehose.local": "Tento server", @@ -427,7 +429,14 @@ "media_gallery.toggle_visible": "{number, plural, one {Skrýt obrázek} few {Skrýt obrázky} many {Skrýt obrázky} other {Skrýt obrázky}}", "moved_to_account_banner.text": "Váš účet {disabledAccount} je momentálně deaktivován, protože jste se přesunul/a na {movedToAccount}.", "mute_modal.hide_from_notifications": "Skrýt z notifikací", + "mute_modal.hide_options": "Skrýt možnosti", + "mute_modal.indefinite": "Dokud je neodkryju", + "mute_modal.show_options": "Zobrazit možnosti", + "mute_modal.they_can_mention_and_follow": "Mohou vás zmínit a sledovat, ale neuvidíte je.", + "mute_modal.they_wont_know": "Nebudou vědět, že byli skryti.", "mute_modal.title": "Ztlumit uživatele?", + "mute_modal.you_wont_see_mentions": "Neuvidíte příspěvky, které je zmiňují.", + "mute_modal.you_wont_see_posts": "Stále budou moci vidět vaše příspěvky, ale vy jejich neuvidíte.", "navigation_bar.about": "O aplikaci", "navigation_bar.advanced_interface": "Otevřít pokročilé webové rozhraní", "navigation_bar.blocks": "Blokovaní uživatelé", @@ -463,17 +472,25 @@ "notification.own_poll": "Vaše anketa skončila", "notification.poll": "Anketa, ve které jste hlasovali, skončila", "notification.reblog": "Uživatel {name} boostnul váš příspěvek", + "notification.relationships_severance_event": "Kontakt ztracen s {name}", + "notification.relationships_severance_event.account_suspension": "Administrátor z {from} pozastavil {target}, což znamená, že již od nich nemůžete přijímat aktualizace nebo s nimi interagovat.", + "notification.relationships_severance_event.domain_block": "Administrátor z {from} pozastavil {target}, včetně {followersCount} z vašich sledujících a {followingCount, plural, one {# účet, který sledujete} few {# účty, které sledujete} many {# účtů, které sledujete} other {# účtů, které sledujete}}.", "notification.relationships_severance_event.learn_more": "Zjistit více", + "notification.relationships_severance_event.user_domain_block": "Zablokovali jste {target}, čímž jste odebrali {followersCount} z vašich sledujících a {followingCount, plural, one {# účet, který sledujete} few {# účty, které sledujete} many {# účtů, které sledujete} other {# účtů, které sledujete}}.", "notification.status": "Uživatel {name} právě přidal příspěvek", "notification.update": "Uživatel {name} upravil příspěvek", "notification_requests.accept": "Přijmout", "notification_requests.dismiss": "Zamítnout", + "notification_requests.notifications_from": "Oznámení od {name}", + "notification_requests.title": "Vyfiltrovaná oznámení", "notifications.clear": "Vyčistit oznámení", "notifications.clear_confirmation": "Opravdu chcete trvale smazat všechna vaše oznámení?", "notifications.column_settings.admin.report": "Nová hlášení:", "notifications.column_settings.admin.sign_up": "Nové registrace:", "notifications.column_settings.alert": "Oznámení na počítači", "notifications.column_settings.favourite": "Oblíbené:", + "notifications.column_settings.filter_bar.advanced": "Zobrazit všechny kategorie", + "notifications.column_settings.filter_bar.category": "Panel rychlého filtrování", "notifications.column_settings.follow": "Noví sledující:", "notifications.column_settings.follow_request": "Nové žádosti o sledování:", "notifications.column_settings.mention": "Zmínky:", @@ -499,6 +516,15 @@ "notifications.permission_denied": "Oznámení na ploše nejsou k dispozici, protože byla zamítnuta žádost o oprávnění je zobrazovat", "notifications.permission_denied_alert": "Oznámení na ploše není možné zapnout, protože oprávnění bylo v minulosti zamítnuto", "notifications.permission_required": "Oznámení na ploše nejsou k dispozici, protože nebylo uděleno potřebné oprávnění.", + "notifications.policy.filter_new_accounts.hint": "Vytvořeno během {days, plural, one {včerejška} few {posledních # dnů} many {posledních # dní} other {posledních # dní}}", + "notifications.policy.filter_new_accounts_title": "Nové účty", + "notifications.policy.filter_not_followers_hint": "Včetně lidí, kteří vás sledovali méně než {days, plural, one {jeden den} few {# dny} many {# dní} other {# dní}}", + "notifications.policy.filter_not_followers_title": "Lidé, kteří vás nesledují", + "notifications.policy.filter_not_following_hint": "Dokud je ručně neschválíte", + "notifications.policy.filter_not_following_title": "Lidé, které nesledujete", + "notifications.policy.filter_private_mentions_hint": "Vyfiltrováno, pokud to není odpověď na vaši zmínku nebo pokud sledujete odesílatele", + "notifications.policy.filter_private_mentions_title": "Nevyžádané soukromé zmínky", + "notifications.policy.title": "Vyfiltrovat oznámení od…", "notifications_permission_banner.enable": "Povolit oznámení na ploše", "notifications_permission_banner.how_to_control": "Chcete-li dostávat oznámení, i když nemáte Mastodon otevřený, povolte oznámení na ploše. Můžete si zvolit, o kterých druzích interakcí chcete být oznámením na ploše informování pod tlačítkem {icon} výše.", "notifications_permission_banner.title": "Nenechte si nic uniknout", @@ -675,9 +701,11 @@ "status.direct": "Soukromě zmínit @{name}", "status.direct_indicator": "Soukromá zmínka", "status.edit": "Upravit", + "status.edited": "Naposledy upraveno {date}", "status.edited_x_times": "Upraveno {count, plural, one {{count}krát} few {{count}krát} many {{count}krát} other {{count}krát}}", "status.embed": "Vložit na web", "status.favourite": "Oblíbit", + "status.favourites": "{count, plural, one {oblíbený} few {oblíbené} many {oblíbených} other {oblíbených}}", "status.filter": "Filtrovat tento příspěvek", "status.filtered": "Filtrováno", "status.hide": "Skrýt příspěvek", @@ -698,6 +726,7 @@ "status.reblog": "Boostnout", "status.reblog_private": "Boostnout s původní viditelností", "status.reblogged_by": "Uživatel {name} boostnul", + "status.reblogs": "{count, plural, one {boost} few {boosty} many {boostů} other {boostů}}", "status.reblogs.empty": "Tento příspěvek ještě nikdo neboostnul. Pokud to někdo udělá, zobrazí se zde.", "status.redraft": "Smazat a přepsat", "status.remove_bookmark": "Odstranit ze záložek", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index c43bf85814..379aebbb1f 100644 --- a/app/javascript/mastodon/locales/th.json +++ b/app/javascript/mastodon/locales/th.json @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "ใช้หมวดหมู่ที่มีอยู่หรือสร้างหมวดหมู่ใหม่", "filter_modal.select_filter.title": "กรองโพสต์นี้", "filter_modal.title.status": "กรองโพสต์", + "filtered_notifications_banner.mentions": "{count, plural, other {การกล่าวถึง}}", "filtered_notifications_banner.pending_requests": "การแจ้งเตือนจาก {count, plural, =0 {ไม่มีใคร} other {# คน}} ที่คุณอาจรู้จัก", "filtered_notifications_banner.title": "การแจ้งเตือนที่กรองอยู่", "firehose.all": "ทั้งหมด", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 76739fe314..dc07480ef6 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -777,10 +777,10 @@ "upload_form.edit": "Düzenle", "upload_form.thumbnail": "Küçük resmi değiştir", "upload_form.video_description": "İşitme kaybı veya görme engeli olan kişiler için açıklama ekleyiniz", - "upload_modal.analyzing_picture": "Resim analiz ediliyor…", + "upload_modal.analyzing_picture": "Görsel analiz ediliyor…", "upload_modal.apply": "Uygula", "upload_modal.applying": "Uygulanıyor…", - "upload_modal.choose_image": "Resim seç", + "upload_modal.choose_image": "Görsel seç", "upload_modal.description_placeholder": "Pijamalı hasta yağız şoföre çabucak güvendi", "upload_modal.detect_text": "Resimdeki metni algıla", "upload_modal.edit_media": "Medyayı düzenle", diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 155e4473bf..ab92e106a3 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -1765,9 +1765,9 @@ fi: tags: does_not_match_previous_name: ei vastaa edellistä nimeä themes: - contrast: Mastodon (Korkea kontrasti) - default: Mastodon (Tumma) - mastodon-light: Mastodon (Vaalea) + contrast: Mastodon (suuri kontrasti) + default: Mastodon (tumma) + mastodon-light: Mastodon (vaalea) system: Automaattinen (käytä järjestelmän teemaa) time: formats: diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 5ca0324dcc..0e90cc723e 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -979,7 +979,7 @@ ko: new_report: body: "%{reporter} 님이 %{target}를 신고했습니다" body_remote: "%{domain}의 누군가가 %{target}을 신고했습니다" - subject: "%{instance} 에 새 신고 등록됨 (#%{id})" + subject: "%{instance}의 새로운 신고(#%{id})" new_software_updates: body: 새 마스토돈 버전이 릴리스되었습니다. 업데이트 할 수 있습니다! subject: "%{instance}에 대해 새 마스토돈 버전이 사용 가능합니다!" @@ -1118,7 +1118,7 @@ ko: date: formats: default: "%Y-%m-%d" - with_month_name: "%Y년 %f월 %e일" + with_month_name: "%Y년 %B %d일" datetime: distance_in_words: about_x_hours: "%{count}시간" @@ -1742,7 +1742,7 @@ ko: time: formats: default: "%Y-%m-%d %H:%M" - month: "%Y년 %f월" + month: "%Y년 %b" time: "%H:%M" with_time_zone: "%Y-%m-%d %H:%M %Z" translation: @@ -1896,4 +1896,4 @@ ko: not_enabled: 아직 WebAuthn을 활성화 하지 않았습니다. not_supported: 이 브라우저는 보안 키를 지원하지 않습니다 otp_required: 보안 키를 사용하기 위해서는 2단계 인증을 먼저 활성화 해 주세요 - registered_on: "%{date} 에 등록됨" + registered_on: "%{date}에 등록됨"