diff --git a/.env.development b/.env.development new file mode 100644 index 000000000..0330da837 --- /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 2f8c1afd6..9e6abea5c 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/.eslintrc.js b/.eslintrc.js index 502b9cefe..759003b55 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -363,6 +363,7 @@ module.exports = defineConfig({ "message": "Use typed hooks `useAppDispatch` and `useAppSelector` instead." } ], + "@typescript-eslint/restrict-template-expressions": ['warn', { allowNumber: true }], 'jsdoc/require-jsdoc': 'off', // Those rules set stricter rules for TS files diff --git a/.github/workflows/crowdin-download.yml b/.github/workflows/crowdin-download.yml index e3ad7371a..256dcffc7 100644 --- a/.github/workflows/crowdin-download.yml +++ b/.github/workflows/crowdin-download.yml @@ -52,7 +52,7 @@ jobs: # Create or update the pull request - name: Create Pull Request - uses: peter-evans/create-pull-request@v6.0.2 + uses: peter-evans/create-pull-request@v6.0.4 with: commit-message: 'New Crowdin translations' title: 'New Crowdin Translations (automated)' diff --git a/.github/workflows/test-js.yml b/.github/workflows/test-js.yml index 79622b6c1..481afdba3 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 diff --git a/.github/workflows/test-ruby.yml b/.github/workflows/test-ruby.yml index 624c3b7a2..3a78f8b43 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 @@ -111,7 +114,6 @@ jobs: fail-fast: false matrix: ruby-version: - - '3.0' - '3.1' - '.ruby-version' - '3.3' @@ -187,7 +189,6 @@ jobs: fail-fast: false matrix: ruby-version: - - '3.0' - '3.1' - '.ruby-version' - '3.3' @@ -287,7 +288,6 @@ jobs: fail-fast: false matrix: ruby-version: - - '3.0' - '3.1' - '.ruby-version' - '3.3' diff --git a/.gitignore b/.gitignore index c5af8eb67..2f94b751a 100644 --- a/.gitignore +++ b/.gitignore @@ -24,7 +24,6 @@ /public/packs-test .env .env.production -.env.development /node_modules/ /build/ diff --git a/.haml-lint.yml b/.haml-lint.yml index 2b553ca56..74d243a3a 100644 --- a/.haml-lint.yml +++ b/.haml-lint.yml @@ -1,6 +1,5 @@ exclude: - 'vendor/**/*' - - lib/templates/haml/scaffold/_form.html.haml require: - ./lib/linter/haml_middle_dot.rb @@ -11,6 +10,6 @@ linters: MiddleDot: enabled: true LineLength: - max: 320 + max: 300 ViewLength: max: 200 # Override default value of 100 inherited from rubocop diff --git a/.nvmrc b/.nvmrc index a3597ecbd..7795cadb5 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20.11 +20.12 diff --git a/.rubocop.yml b/.rubocop.yml index d968346f6..542e90b5e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -9,12 +9,13 @@ inherit_mode: require: - rubocop-rails - rubocop-rspec + - rubocop-rspec_rails - rubocop-performance - rubocop-capybara - ./lib/linter/rubocop_middle_dot AllCops: - TargetRubyVersion: 3.0 # Set to minimum supported version of CI + TargetRubyVersion: 3.1 # Set to minimum supported version of CI DisplayCopNames: true DisplayStyleGuide: true ExtraDetails: true @@ -39,13 +40,7 @@ Layout/FirstHashElementIndentation: # Reason: Currently disabled in .rubocop_todo.yml # https://docs.rubocop.org/rubocop/cops_layout.html#layoutlinelength Layout/LineLength: - Max: 320 # Default of 120 causes a duplicate entry in generated todo file - -# Reason: -# https://docs.rubocop.org/rubocop/cops_lint.html#lintuselessaccessmodifier -Lint/UselessAccessModifier: - ContextCreatingMethods: - - class_methods + Max: 300 # Default of 120 causes a duplicate entry in generated todo file ## Disable most Metrics/*Length cops # Reason: those are often triggered and force significant refactors when this happend @@ -86,6 +81,11 @@ Metrics/CyclomaticComplexity: Metrics/ParameterLists: CountKeywordArgs: false +# Reason: Prefer seeing a variable name +# https://docs.rubocop.org/rubocop/cops_naming.html#namingblockforwarding +Naming/BlockForwarding: + EnforcedStyle: explicit + # Reason: Prevailing style is argument file paths # https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsfilepath Rails/FilePath: @@ -148,11 +148,6 @@ RSpec/NamedSubject: RSpec/NotToNot: EnforcedStyle: to_not -# Reason: Prevailing style uses numeric status codes, matches Rails/HttpStatus -# https://docs.rubocop.org/rubocop-rspec/cops_rspec_rails.html#rspecrailshttpstatus -RSpec/Rails/HttpStatus: - EnforcedStyle: numeric - # Reason: Match overrides from Rspec/FilePath rule above # https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecspecfilepathformat RSpec/SpecFilePathFormat: @@ -163,6 +158,11 @@ RSpec/SpecFilePathFormat: OEmbedController: oembed_controller OStatus: ostatus +# Reason: Prevailing style uses numeric status codes, matches Rails/HttpStatus +# https://docs.rubocop.org/rubocop-rspec/cops_rspec_rails.html#rspecrailshttpstatus +RSpecRails/HttpStatus: + EnforcedStyle: numeric + # Reason: # https://docs.rubocop.org/rubocop/cops_style.html#styleclassandmodulechildren Style/ClassAndModuleChildren: @@ -182,10 +182,16 @@ Style/FormatStringToken: AllowedMethods: - redirect_with_vary +# Reason: Prevailing style choice +# https://docs.rubocop.org/rubocop/cops_style.html#stylehashaslastarrayitem +Style/HashAsLastArrayItem: + Enabled: false + # Reason: Enforce modern Ruby style # https://docs.rubocop.org/rubocop/cops_style.html#stylehashsyntax Style/HashSyntax: EnforcedStyle: ruby19_no_mixed_keys + EnforcedShorthandSyntax: either # Reason: # https://docs.rubocop.org/rubocop/cops_style.html#stylenumericliterals diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 11ac57083..c2826d718 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,18 +1,11 @@ # This configuration was generated by # `rubocop --auto-gen-config --auto-gen-only-exclude --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp` -# using RuboCop version 1.60.2. +# using RuboCop version 1.62.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # 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' @@ -36,7 +29,7 @@ Metrics/PerceivedComplexity: # Configuration parameters: CountAsOne. RSpec/ExampleLength: - Max: 20 # Override default of 5 + Max: 18 RSpec/MultipleExpectations: Max: 7 @@ -61,15 +54,6 @@ Rails/OutputSafety: Exclude: - 'config/initializers/simple_form.rb' -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/UniqueValidationWithoutIndex: - Exclude: - - 'app/models/account_alias.rb' - - 'app/models/custom_filter_status.rb' - - 'app/models/identity.rb' - - 'app/models/webauthn_credential.rb' - # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AllowedMethods, AllowedPatterns. # AllowedMethods: ==, equal?, eql? @@ -88,7 +72,6 @@ Style/FetchEnvVar: Exclude: - 'app/lib/redis_configuration.rb' - 'app/lib/translation_service.rb' - - 'config/environments/development.rb' - 'config/environments/production.rb' - 'config/initializers/2_limited_federation_mode.rb' - 'config/initializers/3_omniauth.rb' @@ -98,7 +81,6 @@ Style/FetchEnvVar: - 'config/initializers/paperclip.rb' - 'config/initializers/vapid.rb' - 'lib/mastodon/redis_config.rb' - - 'lib/premailer_webpack_strategy.rb' - 'lib/tasks/repo.rake' - 'spec/features/profile_spec.rb' @@ -144,22 +126,8 @@ Style/GuardClause: - 'lib/mastodon/cli/accounts.rb' - 'lib/mastodon/cli/maintenance.rb' - 'lib/mastodon/cli/media.rb' - - 'lib/paperclip/attachment_extensions.rb' - 'lib/tasks/repo.rake' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: braces, no_braces -Style/HashAsLastArrayItem: - Exclude: - - 'app/controllers/admin/statuses_controller.rb' - - 'app/controllers/api/v1/statuses_controller.rb' - - 'app/models/concerns/account/counters.rb' - - 'app/models/concerns/status/threading_concern.rb' - - 'app/models/status.rb' - - 'app/services/batched_remove_status_service.rb' - - 'app/services/notify_service.rb' - # This cop supports unsafe autocorrection (--autocorrect-all). Style/HashTransformValues: Exclude: @@ -207,13 +175,6 @@ Style/OptionalBooleanParameter: - 'app/workers/unfollow_follow_worker.rb' - 'lib/mastodon/redis_config.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: PreferredDelimiters. -Style/PercentLiteralDelimiters: - Exclude: - - 'config/deploy.rb' - - 'config/initializers/doorkeeper.rb' - # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle. # SupportedStyles: short, verbose @@ -252,44 +213,12 @@ Style/SignalException: - 'lib/devise/strategies/two_factor_ldap_authenticatable.rb' - 'lib/devise/strategies/two_factor_pam_authenticatable.rb' -# This cop supports unsafe autocorrection (--autocorrect-all). -Style/SingleArgumentDig: - Exclude: - - 'lib/webpacker/manifest_extensions.rb' - # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: Mode. Style/StringConcatenation: Exclude: - 'config/initializers/paperclip.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. -# SupportedStyles: single_quotes, double_quotes -Style/StringLiterals: - Exclude: - - 'config/environments/production.rb' - - 'config/initializers/backtrace_silencers.rb' - - 'config/initializers/http_client_proxy.rb' - - 'config/initializers/rack_attack.rb' - - 'config/initializers/webauthn.rb' - - 'config/routes.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, no_comma -Style/TrailingCommaInArguments: - Exclude: - - 'config/initializers/paperclip.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, no_comma -Style/TrailingCommaInHashLiteral: - Exclude: - - 'config/environments/production.rb' - - 'config/environments/test.rb' - # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: WordRegex. # SupportedStyles: percent, brackets diff --git a/.ruby-version b/.ruby-version index b347b11ea..351227fca 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.2.3 +3.2.4 diff --git a/Dockerfile b/Dockerfile index 795c20d6c..ccf57a0d0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -# syntax=docker/dockerfile:1.4 +# syntax=docker/dockerfile:1.7 # Please see https://docs.docker.com/engine/reference/builder for information about # the extended buildx capabilities used in this file. @@ -7,15 +7,15 @@ ARG TARGETPLATFORM=${TARGETPLATFORM} ARG BUILDPLATFORM=${BUILDPLATFORM} -# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.2.3"] -ARG RUBY_VERSION="3.2.3" +# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.2.4"] +ARG RUBY_VERSION="3.2.4" # # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"] ARG NODE_MAJOR_VERSION="20" # Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"] ARG DEBIAN_VERSION="bookworm" # Node image to use for base image based on combined variables (ex: 20-bookworm-slim) FROM docker.io/node:${NODE_MAJOR_VERSION}-${DEBIAN_VERSION}-slim as node -# Ruby image to use for base image based on combined variables (ex: 3.2.3-slim-bookworm) +# Ruby image to use for base image based on combined variables (ex: 3.2.4-slim-bookworm) FROM docker.io/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} as ruby # Resulting version string is vX.X.X-MASTODON_VERSION_PRERELEASE+MASTODON_VERSION_METADATA @@ -29,7 +29,7 @@ ARG MASTODON_VERSION_METADATA="prod" # See: https://docs.joinmastodon.org/admin/config/#rails_serve_static_files ARG RAILS_SERVE_STATIC_FILES="true" # Allow to use YJIT compiler -# See: https://github.com/ruby/ruby/blob/v3_2_3/doc/yjit/yjit.md +# See: https://github.com/ruby/ruby/blob/v3_2_4/doc/yjit/yjit.md ARG RUBY_YJIT_ENABLE="1" # Timezone used by the Docker container and runtime, change with [--build-arg TZ=Europe/Berlin] ARG TZ="Etc/UTC" @@ -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; @@ -257,4 +262,4 @@ USER mastodon # Expose default Puma ports EXPOSE 3000 # Set container tini as default entry point -ENTRYPOINT ["/usr/bin/tini", "--"] \ No newline at end of file +ENTRYPOINT ["/usr/bin/tini", "--"] diff --git a/Gemfile b/Gemfile index 35b9ee91d..a10613b30 100644 --- a/Gemfile +++ b/Gemfile @@ -1,28 +1,28 @@ # frozen_string_literal: true source 'https://rubygems.org' -ruby '>= 3.0.0' +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' 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,9 +53,8 @@ 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', '~> 5.2.0' gem 'http_accept_language', '~> 2.1' gem 'httplog', '~> 1.6.2' gem 'i18n', '1.14.1' # TODO: Remove version when resolved: https://github.com/glebm/i18n-tasks/issues/552 / https://github.com/ruby-i18n/i18n/pull/688 @@ -63,40 +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 'posix-spawn' +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 'stoplight', '~> 3.0.1' +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' @@ -198,12 +197,14 @@ 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' gem 'hcaptcha', '~> 7.1' + +gem 'mail', '~> 2.8' diff --git a/Gemfile.lock b/Gemfile.lock index b341ca84b..7068f5dd5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -99,20 +99,20 @@ GEM ast (2.4.2) attr_encrypted (4.0.0) encryptor (~> 3.0.0) - attr_required (1.0.1) + attr_required (1.0.2) awrence (1.2.1) aws-eventstream (1.3.0) - aws-partitions (1.873.0) - aws-sdk-core (3.190.1) + aws-partitions (1.916.0) + aws-sdk-core (3.192.1) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.8) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.75.0) - aws-sdk-core (~> 3, >= 3.188.0) + aws-sdk-kms (1.79.0) + aws-sdk-core (~> 3, >= 3.191.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.142.0) - aws-sdk-core (~> 3, >= 3.189.0) + aws-sdk-s3 (1.147.0) + aws-sdk-core (~> 3, >= 3.192.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.8) aws-sigv4 (1.8.0) @@ -132,7 +132,7 @@ GEM erubi (>= 1.0.0) rack (>= 0.9.0) rouge (>= 1.0.0) - better_html (2.0.2) + better_html (2.1.1) actionview (>= 6.0) activesupport (>= 6.0) ast (~> 2.0) @@ -140,9 +140,9 @@ GEM parser (>= 2.4) smart_properties bigdecimal (3.1.7) - bindata (2.4.15) - binding_of_caller (1.0.0) - debug_inspector (>= 0.0.1) + bindata (2.5.0) + binding_of_caller (1.0.1) + debug_inspector (>= 1.2.0) blurhash (0.1.7) bootsnap (1.18.3) msgpack (~> 1.2) @@ -167,7 +167,7 @@ GEM xpath (~> 3.2) case_transform (0.2) activesupport - cbor (0.5.9.6) + cbor (0.5.9.8) charlock_holmes (0.7.7) chewy (7.5.1) activesupport (>= 5.2) @@ -182,23 +182,23 @@ GEM cose (1.3.0) cbor (~> 0.5.9) openssl-signature_algorithm (~> 1.0) - crack (0.4.6) + crack (1.0.0) bigdecimal rexml crass (1.0.6) - css_parser (1.14.0) + css_parser (1.17.1) addressable - csv (3.2.8) + csv (3.3.0) database_cleaner-active_record (2.1.0) activerecord (>= 5.a) database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) date (3.3.4) - debug (1.9.1) + debug (1.9.2) irb (~> 1.10) reline (>= 0.3.8) - debug_inspector (1.1.0) - devise (4.9.3) + debug_inspector (1.2.0) + devise (4.9.4) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) @@ -217,14 +217,10 @@ GEM discard (1.3.0) activerecord (>= 4.2, < 8) docile (1.4.0) - domain_name (0.5.20190701) - unf (>= 0.0.5, < 1.0.0) + domain_name (0.6.20240107) doorkeeper (5.6.9) railties (>= 5) - dotenv (2.8.1) - dotenv-rails (2.8.1) - dotenv (= 2.8.1) - railties (>= 3.2) + dotenv (3.1.0) drb (2.2.1) ed25519 (1.3.0) elasticsearch (7.13.3) @@ -242,11 +238,11 @@ GEM mail (~> 2.7) encryptor (3.0.0) erubi (1.12.0) - et-orbi (1.2.7) + et-orbi (1.2.11) tzinfo - excon (0.109.0) + excon (0.110.0) fabrication (2.31.0) - faker (3.2.3) + faker (3.3.1) i18n (>= 1.8.11, < 2) faraday (1.10.3) faraday-em_http (~> 1.0) @@ -274,10 +270,10 @@ GEM faraday_middleware (1.2.0) faraday (~> 1.0) fast_blank (1.0.1) - fastimage (2.3.0) - ffi (1.15.5) - ffi-compiler (1.0.1) - ffi (>= 1.0.0) + fastimage (2.3.1) + ffi (1.16.3) + ffi-compiler (1.3.2) + ffi (>= 1.15.5) rake fog-core (2.4.0) builder @@ -291,7 +287,7 @@ GEM fog-core (~> 2.1) fog-json (>= 1.0) formatador (1.1.0) - fugit (1.8.1) + fugit (1.10.1) et-orbi (~> 1, >= 1.2.7) raabro (~> 1.4) fuubar (2.5.1) @@ -318,15 +314,16 @@ GEM hashie (5.0.0) hcaptcha (7.1.0) json - highline (2.1.0) + highline (3.0.1) hiredis (0.6.3) hkdf (0.3.0) htmlentities (4.3.4) - http (5.1.1) + http (5.2.0) addressable (~> 2.8) + base64 (~> 0.1) http-cookie (~> 1.0) http-form_data (~> 2.2) - llhttp-ffi (~> 0.4.0) + llhttp-ffi (~> 0.5.0) http-cookie (1.0.5) domain_name (~> 0.5) http-form_data (2.3.0) @@ -357,7 +354,7 @@ GEM rdoc reline (>= 0.4.2) jmespath (1.6.2) - json (2.7.1) + json (2.7.2) json-canonicalization (1.0.0) json-jwt (1.15.3.1) activesupport (>= 4.2) @@ -374,7 +371,7 @@ GEM json-ld-preloaded (3.3.0) json-ld (~> 3.3) rdf (~> 3.3) - json-schema (4.2.0) + json-schema (4.3.0) addressable (>= 2.8) jsonapi-renderer (0.2.2) jwt (2.7.1) @@ -399,15 +396,15 @@ GEM language_server-protocol (3.17.0.3) launchy (2.5.2) addressable (~> 2.8) - letter_opener (1.8.1) - launchy (>= 2.2, < 3) + letter_opener (1.10.0) + launchy (>= 2.2, < 4) letter_opener_web (2.0.0) actionmailer (>= 5.2) letter_opener (~> 1.7) railties (>= 5.2) rexml link_header (0.0.8) - llhttp-ffi (0.4.0) + llhttp-ffi (0.5.0) ffi-compiler (~> 1.0) rake (~> 13.0) lograge (0.14.0) @@ -423,7 +420,7 @@ GEM net-imap net-pop net-smtp - marcel (1.0.2) + marcel (1.0.4) mario-redis-lock (1.2.1) redis (>= 3.0.5) matrix (0.4.2) @@ -434,13 +431,13 @@ GEM memory_profiler (1.0.1) mime-types (3.5.2) mime-types-data (~> 3.2015) - mime-types-data (3.2023.1205) + mime-types-data (3.2024.0305) mini_mime (1.1.5) - mini_portile2 (2.8.5) + mini_portile2 (2.8.6) minitest (5.22.3) msgpack (1.7.2) multi_json (1.15.0) - multipart-post (2.3.0) + multipart-post (2.4.0) mutex_m (0.2.0) net-http (0.4.1) uri @@ -454,10 +451,10 @@ GEM net-protocol net-protocol (0.2.2) timeout - net-smtp (0.4.0.1) + net-smtp (0.5.0) net-protocol - nio4r (2.5.9) - nokogiri (1.16.3) + nio4r (2.7.1) + nokogiri (1.16.4) mini_portile2 (~> 2.8.2) racc (~> 1.4) nsa (0.3.0) @@ -510,8 +507,7 @@ GEM pg (1.5.6) pghero (3.4.1) activerecord (>= 6) - posix-spawn (0.3.15) - premailer (1.21.0) + premailer (1.23.0) addressable css_parser (>= 1.12.0) htmlentities (>= 4.0.0) @@ -527,7 +523,7 @@ GEM railties (>= 7.0.0) psych (5.1.2) stringio - public_suffix (5.0.4) + public_suffix (5.0.5) puma (6.4.2) nio4r (~> 2.0) pundit (2.3.1) @@ -548,7 +544,7 @@ GEM rack-protection (3.2.0) base64 (>= 0.1.0) rack (~> 2.2, >= 2.2.4) - rack-proxy (0.7.6) + rack-proxy (0.7.7) rack rack-session (1.0.2) rack (< 3) @@ -594,7 +590,7 @@ GEM thor (~> 1.0, >= 1.2.2) zeitwerk (~> 2.6) rainbow (3.1.1) - rake (13.1.0) + rake (13.2.1) rdf (3.3.1) bcp47_spec (~> 0.2) link_header (~> 0.0, >= 0.0.8) @@ -609,16 +605,16 @@ GEM redlock (1.3.2) redis (>= 3.0.0, < 6.0) regexp_parser (2.9.0) - reline (0.4.3) + reline (0.5.2) io-console (~> 0.5) - request_store (1.5.1) + request_store (1.6.0) rack (>= 1.4) responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) rexml (3.2.6) rotp (6.3.0) - rouge (4.1.2) + rouge (4.2.1) rpam2 (4.0.2) rqrcode (2.2.0) chunky_png (~> 1.0) @@ -642,13 +638,13 @@ 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) sidekiq (>= 5, < 8) rspec-support (3.13.1) - rubocop (1.62.1) + rubocop (1.63.3) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -665,21 +661,24 @@ GEM rubocop (~> 1.41) rubocop-factory_bot (2.25.1) rubocop (~> 1.41) - rubocop-performance (1.20.2) + rubocop-performance (1.21.0) rubocop (>= 1.48.1, < 2.0) - rubocop-ast (>= 1.30.0, < 2.0) - rubocop-rails (2.24.0) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rails (2.24.1) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rspec (2.27.1) + rubocop-rspec (2.29.1) rubocop (~> 1.40) rubocop-capybara (~> 2.17) rubocop-factory_bot (~> 2.22) + rubocop-rspec_rails (~> 2.28) + rubocop-rspec_rails (2.28.3) + rubocop (~> 1.40) ruby-prof (1.7.0) ruby-progressbar (1.13.0) - ruby-saml (1.15.0) + ruby-saml (1.16.0) nokogiri (>= 1.13.10) rexml ruby2_keywords (0.0.5) @@ -691,10 +690,10 @@ GEM sanitize (6.1.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) - scenic (1.7.0) + scenic (1.8.0) activerecord (>= 4.0.0) railties (>= 4.0.0) - selenium-webdriver (4.18.1) + selenium-webdriver (4.19.0) base64 (~> 0.2) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) @@ -731,7 +730,7 @@ GEM smart_properties (1.17.0) stackprof (0.2.26) statsd-ruby (1.5.0) - stoplight (3.0.2) + stoplight (4.1.0) redlock (~> 1.0) stringio (3.1.0) strong_migrations (1.8.0) @@ -746,7 +745,7 @@ GEM unicode-display_width (>= 1.1.1, < 3) terrapin (1.0.1) climate_control - test-prof (1.3.2) + test-prof (1.3.3) thor (1.3.1) tilt (2.3.0) timeout (0.4.1) @@ -763,7 +762,7 @@ GEM tty-cursor (~> 0.7) tty-screen (~> 0.8) wisper (~> 2.0) - tty-screen (0.8.1) + tty-screen (0.8.2) twitter-text (3.1.0) idn-ruby unf (~> 0.1.0) @@ -773,9 +772,9 @@ GEM tzinfo (>= 1.0.0) unf (0.1.4) unf_ext - unf_ext (0.0.8.2) + unf_ext (0.0.9.1) unicode-display_width (2.5.0) - uri (0.12.2) + uri (0.13.0) validate_email (0.1.6) activemodel (>= 3.0) mail (>= 2.2.5) @@ -796,7 +795,7 @@ GEM webfinger (1.2.0) activesupport httpclient (>= 2.4) - webmock (3.22.0) + webmock (3.23.0) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -847,7 +846,7 @@ DEPENDENCIES devise_pam_authenticatable2 (~> 9.2) discard (~> 1.2) doorkeeper (~> 5.6) - dotenv-rails (~> 2.8) + dotenv ed25519 (~> 1.3) email_spec fabrication (~> 2.30) @@ -862,7 +861,7 @@ DEPENDENCIES hcaptcha (~> 7.1) hiredis (~> 0.6) htmlentities (~> 4.3) - http (~> 5.1) + http (~> 5.2.0) http_accept_language (~> 2.1) httplog (~> 1.6.2) i18n (= 1.14.1) @@ -879,6 +878,7 @@ DEPENDENCIES letter_opener_web (~> 2.0) link_header (~> 0.0) lograge (~> 0.12) + mail (~> 2.8) mario-redis-lock (~> 1.2) md-paperclip-azure (~> 2.2) memory_profiler @@ -897,7 +897,6 @@ DEPENDENCIES parslet pg (~> 1.5) pghero - posix-spawn premailer-rails private_address_check (~> 0.5) propshaft @@ -939,7 +938,7 @@ DEPENDENCIES simplecov (~> 0.22) simplecov-lcov (~> 0.8) stackprof - stoplight (~> 3.0.1) + stoplight (~> 4.1) strong_migrations (= 1.8.0) test-prof thor (~> 1.2) @@ -953,7 +952,7 @@ DEPENDENCIES xorcist (~> 1.1) RUBY VERSION - ruby 3.2.2p53 + ruby 3.2.3p157 BUNDLED WITH - 2.5.4 + 2.5.9 diff --git a/README.md b/README.md index 7f9b115c4..1d0e75dab 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ Mastodon acts as an OAuth2 provider, so 3rd party apps can use the REST and Stre - **PostgreSQL** 12+ - **Redis** 4+ -- **Ruby** 3.0+ +- **Ruby** 3.1+ - **Node.js** 16+ The repository includes deployment configurations for **Docker and docker-compose** as well as specific platforms like **Heroku**, **Scalingo**, and **Nanobox**. For Helm charts, reference the [mastodon/chart repository](https://github.com/mastodon/chart). The [**standalone** installation guide](https://docs.joinmastodon.org/admin/install/) is available in the documentation. diff --git a/Vagrantfile b/Vagrantfile index 12bd1ba67..8a95e91f3 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -173,6 +173,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| # Otherwise, you can access the site at http://localhost:3000 and http://localhost:4000 , http://localhost:8080 config.vm.network :forwarded_port, guest: 3000, host: 3000 + config.vm.network :forwarded_port, guest: 3035, host: 3035 config.vm.network :forwarded_port, guest: 4000, host: 4000 config.vm.network :forwarded_port, guest: 8080, host: 8080 config.vm.network :forwarded_port, guest: 9200, host: 9200 diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 4e475fe78..32549e151 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -46,7 +46,7 @@ class AccountsController < ApplicationController end def default_statuses - @account.statuses.where(visibility: [:public, :unlisted]) + @account.statuses.distributable_visibility end def only_media_scope diff --git a/app/controllers/activitypub/replies_controller.rb b/app/controllers/activitypub/replies_controller.rb index 3f43e89a5..11aac48c9 100644 --- a/app/controllers/activitypub/replies_controller.rb +++ b/app/controllers/activitypub/replies_controller.rb @@ -31,7 +31,7 @@ class ActivityPub::RepliesController < ActivityPub::BaseController def set_replies @replies = only_other_accounts? ? Status.where.not(account_id: @account.id).joins(:account).merge(Account.without_suspended) : @account.statuses - @replies = @replies.where(in_reply_to_id: @status.id, visibility: [:public, :unlisted]) + @replies = @replies.distributable_visibility.where(in_reply_to_id: @status.id) @replies = @replies.paginate_by_min_id(DESCENDANTS_LIMIT, params[:min_id]) end diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb index f87d596ce..c1a5e43f8 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/api/v1/accounts/credentials_controller.rb b/app/controllers/api/v1/accounts/credentials_controller.rb index 8f31336b9..e8f712457 100644 --- a/app/controllers/api/v1/accounts/credentials_controller.rb +++ b/app/controllers/api/v1/accounts/credentials_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Api::V1::Accounts::CredentialsController < Api::BaseController - before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, except: [:update] + before_action -> { doorkeeper_authorize! :read, :'read:accounts', :'read:me' }, except: [:update] before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:update] before_action :require_user! diff --git a/app/controllers/api/v1/featured_tags/suggestions_controller.rb b/app/controllers/api/v1/featured_tags/suggestions_controller.rb index 4f732ed2d..9c72e4380 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/api/v1/statuses/reblogged_by_accounts_controller.rb b/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb index eaa5ef725..bac96b032 100644 --- a/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb +++ b/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb @@ -23,7 +23,7 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::V1::Statuses::Base end def paginated_statuses - Status.where(reblog_of_id: @status.id).where(visibility: [:public, :unlisted]).paginate_by_max_id( + Status.where(reblog_of_id: @status.id).distributable_visibility.paginate_by_max_id( limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:max_id], params[:since_id] diff --git a/app/controllers/concerns/api/pagination.rb b/app/controllers/concerns/api/pagination.rb new file mode 100644 index 000000000..d84a1d99f --- /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 diff --git a/app/controllers/concerns/cache_concern.rb b/app/controllers/concerns/cache_concern.rb index 62f763fe2..4656539f8 100644 --- a/app/controllers/concerns/cache_concern.rb +++ b/app/controllers/concerns/cache_concern.rb @@ -46,27 +46,19 @@ module CacheConcern end end + # TODO: Rename this method, as it does not perform any caching anymore. def cache_collection(raw, klass) - return raw unless klass.respond_to?(:with_includes) + return raw unless klass.respond_to?(:preload_cacheable_associations) - raw = raw.cache_ids.to_a if raw.is_a?(ActiveRecord::Relation) - return [] if raw.empty? + records = raw.to_a - cached_keys_with_value = Rails.cache.read_multi(*raw).transform_keys(&:id) + klass.preload_cacheable_associations(records) - uncached_ids = raw.map(&:id) - cached_keys_with_value.keys - - klass.reload_stale_associations!(cached_keys_with_value.values) if klass.respond_to?(:reload_stale_associations!) - - unless uncached_ids.empty? - uncached = klass.where(id: uncached_ids).with_includes.index_by(&:id) - Rails.cache.write_multi(uncached.values.to_h { |i| [i, i] }) - end - - raw.filter_map { |item| cached_keys_with_value[item.id] || uncached[item.id] } + records end + # TODO: Rename this method, as it does not perform any caching anymore. def cache_collection_paginated_by_id(raw, klass, limit, options) - cache_collection raw.cache_ids.to_a_paginated_by_id(limit, options), klass + cache_collection raw.to_a_paginated_by_id(limit, options), klass end end diff --git a/app/controllers/concerns/signature_verification.rb b/app/controllers/concerns/signature_verification.rb index 315586627..68f09ee02 100644 --- a/app/controllers/concerns/signature_verification.rb +++ b/app/controllers/concerns/signature_verification.rb @@ -66,7 +66,7 @@ module SignatureVerification compare_signed_string = build_signed_string(include_query_string: false) return actor unless verify_signature(actor, signature, compare_signed_string).nil? - actor = stoplight_wrap_request { actor_refresh_key!(actor) } + actor = stoplight_wrapper.run { actor_refresh_key!(actor) } raise SignatureVerificationError, "Could not refresh public key #{signature_params['keyId']}" if actor.nil? @@ -226,10 +226,10 @@ module SignatureVerification end if key_id.start_with?('acct:') - stoplight_wrap_request { ResolveAccountService.new.call(key_id.delete_prefix('acct:'), suppress_errors: false) } + stoplight_wrapper.run { ResolveAccountService.new.call(key_id.delete_prefix('acct:'), suppress_errors: false) } elsif !ActivityPub::TagManager.instance.local_uri?(key_id) account = ActivityPub::TagManager.instance.uri_to_actor(key_id) - account ||= stoplight_wrap_request { ActivityPub::FetchRemoteKeyService.new.call(key_id, suppress_errors: false) } + account ||= stoplight_wrapper.run { ActivityPub::FetchRemoteKeyService.new.call(key_id, suppress_errors: false) } account end rescue Mastodon::PrivateNetworkAddressError => e @@ -238,12 +238,11 @@ module SignatureVerification raise SignatureVerificationError, e.message end - def stoplight_wrap_request(&block) - Stoplight("source:#{request.remote_ip}", &block) + def stoplight_wrapper + Stoplight("source:#{request.remote_ip}") .with_threshold(1) .with_cool_off_time(5.minutes.seconds) .with_error_handler { |error, handle| error.is_a?(HTTP::Error) || error.is_a?(OpenSSL::SSL::SSLError) ? handle.call(error) : raise(error) } - .run end def actor_refresh_key!(actor) diff --git a/app/controllers/settings/featured_tags_controller.rb b/app/controllers/settings/featured_tags_controller.rb index c38440265..90c112e21 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/controllers/settings/imports_controller.rb b/app/controllers/settings/imports_controller.rb index 983caf22f..569aa07c5 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/helpers/application_helper.rb b/app/helpers/application_helper.rb index 668afe7fd..4cf959f2d 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -113,6 +113,14 @@ module ApplicationHelper content_tag(:i, nil, attributes.merge(class: class_names.join(' '))) end + def material_symbol(icon, attributes = {}) + inline_svg_tag( + "400-24px/#{icon}.svg", + class: %w(icon).concat(attributes[:class].to_s.split), + role: :img + ) + end + def check_icon inline_svg_tag 'check.svg' end diff --git a/app/helpers/branding_helper.rb b/app/helpers/branding_helper.rb index f72d6df5d..8201f36e3 100644 --- a/app/helpers/branding_helper.rb +++ b/app/helpers/branding_helper.rb @@ -19,6 +19,6 @@ module BrandingHelper end def render_logo - image_pack_tag('logo.svg', alt: 'Mastodon', class: 'logo logo--icon') + image_tag(frontend_asset_path('images/logo.svg'), alt: 'Mastodon', class: 'logo logo--icon') end end diff --git a/app/helpers/context_helper.rb b/app/helpers/context_helper.rb index 2d7a4f98f..cbefe0fe5 100644 --- a/app/helpers/context_helper.rb +++ b/app/helpers/context_helper.rb @@ -48,13 +48,11 @@ module ContextHelper end def serialized_context(named_contexts_map, context_extensions_map) - context_array = [] - named_contexts = named_contexts_map.keys context_extensions = context_extensions_map.keys - named_contexts.each do |key| - context_array << NAMED_CONTEXT_MAP[key] + context_array = named_contexts.map do |key| + NAMED_CONTEXT_MAP[key] end extensions = context_extensions.each_with_object({}) do |key, h| diff --git a/app/helpers/theme_helper.rb b/app/helpers/theme_helper.rb new file mode 100644 index 000000000..d15259851 --- /dev/null +++ b/app/helpers/theme_helper.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module ThemeHelper + def theme_style_tags(theme) + if theme == 'system' + stylesheet_pack_tag('mastodon-light', media: 'not all and (prefers-color-scheme: dark)', crossorigin: 'anonymous') + + stylesheet_pack_tag('default', media: '(prefers-color-scheme: dark)', crossorigin: 'anonymous') + else + stylesheet_pack_tag theme, media: 'all', crossorigin: 'anonymous' + end + end + + def theme_color_tags(theme) + if theme == 'system' + tag.meta(name: 'theme-color', content: Themes::THEME_COLORS[:dark], media: '(prefers-color-scheme: dark)') + + tag.meta(name: 'theme-color', content: Themes::THEME_COLORS[:light], media: '(prefers-color-scheme: light)') + else + tag.meta name: 'theme-color', content: theme_color_for(theme) + end + end + + private + + def theme_color_for(theme) + theme == 'mastodon-light' ? Themes::THEME_COLORS[:light] : Themes::THEME_COLORS[:dark] + end +end diff --git a/app/javascript/packs/admin.tsx b/app/javascript/entrypoints/admin.tsx similarity index 99% rename from app/javascript/packs/admin.tsx rename to app/javascript/entrypoints/admin.tsx index 9fee56056..225cb1633 100644 --- a/app/javascript/packs/admin.tsx +++ b/app/javascript/entrypoints/admin.tsx @@ -363,6 +363,6 @@ ready(() => { document.querySelectorAll('[data-admin-component]').forEach((element) => { void mountReactComponent(element); }); -}).catch((reason) => { +}).catch((reason: unknown) => { throw reason; }); diff --git a/app/javascript/packs/application.js b/app/javascript/entrypoints/application.js similarity index 100% rename from app/javascript/packs/application.js rename to app/javascript/entrypoints/application.js diff --git a/app/javascript/packs/error.js b/app/javascript/entrypoints/error.js similarity index 100% rename from app/javascript/packs/error.js rename to app/javascript/entrypoints/error.js diff --git a/app/javascript/packs/inert.js b/app/javascript/entrypoints/inert.js similarity index 100% rename from app/javascript/packs/inert.js rename to app/javascript/entrypoints/inert.js diff --git a/app/javascript/packs/mailer.js b/app/javascript/entrypoints/mailer.js similarity index 100% rename from app/javascript/packs/mailer.js rename to app/javascript/entrypoints/mailer.js diff --git a/app/javascript/packs/public-path.js b/app/javascript/entrypoints/public-path.js similarity index 100% rename from app/javascript/packs/public-path.js rename to app/javascript/entrypoints/public-path.js diff --git a/app/javascript/packs/public.tsx b/app/javascript/entrypoints/public.tsx similarity index 98% rename from app/javascript/packs/public.tsx rename to app/javascript/entrypoints/public.tsx index 044faeb29..d45927226 100644 --- a/app/javascript/packs/public.tsx +++ b/app/javascript/entrypoints/public.tsx @@ -69,7 +69,7 @@ window.addEventListener('message', (e) => { }, '*', ); - }).catch((e) => { + }).catch((e: unknown) => { console.error('Error in setHeightMessage postMessage', e); }); }); @@ -206,7 +206,7 @@ function loaded() { return true; }) - .catch((error) => { + .catch((error: unknown) => { console.error(error); }); } @@ -448,7 +448,7 @@ Rails.delegate(document, '#registration_new_user,#new_user', 'submit', () => { }); function main() { - ready(loaded).catch((error) => { + ready(loaded).catch((error: unknown) => { console.error(error); }); } @@ -457,6 +457,6 @@ loadPolyfills() .then(loadLocale) .then(main) .then(loadKeyboardExtensions) - .catch((error) => { + .catch((error: unknown) => { console.error(error); }); diff --git a/app/javascript/packs/remote_interaction_helper.ts b/app/javascript/entrypoints/remote_interaction_helper.ts similarity index 100% rename from app/javascript/packs/remote_interaction_helper.ts rename to app/javascript/entrypoints/remote_interaction_helper.ts diff --git a/app/javascript/packs/share.jsx b/app/javascript/entrypoints/share.jsx similarity index 100% rename from app/javascript/packs/share.jsx rename to app/javascript/entrypoints/share.jsx diff --git a/app/javascript/packs/sign_up.js b/app/javascript/entrypoints/sign_up.js similarity index 100% rename from app/javascript/packs/sign_up.js rename to app/javascript/entrypoints/sign_up.js diff --git a/app/javascript/packs/two_factor_authentication.js b/app/javascript/entrypoints/two_factor_authentication.js similarity index 100% rename from app/javascript/packs/two_factor_authentication.js rename to app/javascript/entrypoints/two_factor_authentication.js diff --git a/app/javascript/mastodon/actions/boosts.js b/app/javascript/mastodon/actions/boosts.js deleted file mode 100644 index 1fc2e391e..000000000 --- a/app/javascript/mastodon/actions/boosts.js +++ /dev/null @@ -1,32 +0,0 @@ -import { openModal } from './modal'; - -export const BOOSTS_INIT_MODAL = 'BOOSTS_INIT_MODAL'; -export const BOOSTS_CHANGE_PRIVACY = 'BOOSTS_CHANGE_PRIVACY'; - -export function initBoostModal(props) { - return (dispatch, getState) => { - const default_privacy = getState().getIn(['compose', 'default_privacy']); - - const privacy = props.status.get('visibility') === 'private' ? 'private' : default_privacy; - - dispatch({ - type: BOOSTS_INIT_MODAL, - privacy, - }); - - dispatch(openModal({ - modalType: 'BOOST', - modalProps: props, - })); - }; -} - - -export function changeBoostPrivacy(privacy) { - return dispatch => { - dispatch({ - type: BOOSTS_CHANGE_PRIVACY, - privacy, - }); - }; -} diff --git a/app/javascript/mastodon/actions/markers.js b/app/javascript/mastodon/actions/markers.js deleted file mode 100644 index cfc329a8b..000000000 --- a/app/javascript/mastodon/actions/markers.js +++ /dev/null @@ -1,152 +0,0 @@ -import { List as ImmutableList } from 'immutable'; - -import { debounce } from 'lodash'; - -import api from '../api'; -import { compareId } from '../compare_id'; - -export const MARKERS_FETCH_REQUEST = 'MARKERS_FETCH_REQUEST'; -export const MARKERS_FETCH_SUCCESS = 'MARKERS_FETCH_SUCCESS'; -export const MARKERS_FETCH_FAIL = 'MARKERS_FETCH_FAIL'; -export const MARKERS_SUBMIT_SUCCESS = 'MARKERS_SUBMIT_SUCCESS'; - -export const synchronouslySubmitMarkers = () => (dispatch, getState) => { - const accessToken = getState().getIn(['meta', 'access_token'], ''); - const params = _buildParams(getState()); - - if (Object.keys(params).length === 0 || accessToken === '') { - return; - } - - // The Fetch API allows us to perform requests that will be carried out - // after the page closes. But that only works if the `keepalive` attribute - // is supported. - if (window.fetch && 'keepalive' in new Request('')) { - fetch('/api/v1/markers', { - keepalive: true, - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${accessToken}`, - }, - body: JSON.stringify(params), - }); - - return; - } else if (navigator && navigator.sendBeacon) { - // Failing that, we can use sendBeacon, but we have to encode the data as - // FormData for DoorKeeper to recognize the token. - const formData = new FormData(); - - formData.append('bearer_token', accessToken); - - for (const [id, value] of Object.entries(params)) { - formData.append(`${id}[last_read_id]`, value.last_read_id); - } - - if (navigator.sendBeacon('/api/v1/markers', formData)) { - return; - } - } - - // If neither Fetch nor sendBeacon worked, try to perform a synchronous - // request. - try { - const client = new XMLHttpRequest(); - - client.open('POST', '/api/v1/markers', false); - client.setRequestHeader('Content-Type', 'application/json'); - client.setRequestHeader('Authorization', `Bearer ${accessToken}`); - client.send(JSON.stringify(params)); - } catch (e) { - // Do not make the BeforeUnload handler error out - } -}; - -const _buildParams = (state) => { - const params = {}; - - const lastHomeId = state.getIn(['timelines', 'home', 'items'], ImmutableList()).find(item => item !== null); - const lastNotificationId = state.getIn(['notifications', 'lastReadId']); - - if (lastHomeId && compareId(lastHomeId, state.getIn(['markers', 'home'])) > 0) { - params.home = { - last_read_id: lastHomeId, - }; - } - - if (lastNotificationId && compareId(lastNotificationId, state.getIn(['markers', 'notifications'])) > 0) { - params.notifications = { - last_read_id: lastNotificationId, - }; - } - - return params; -}; - -const debouncedSubmitMarkers = debounce((dispatch, getState) => { - const accessToken = getState().getIn(['meta', 'access_token'], ''); - const params = _buildParams(getState()); - - if (Object.keys(params).length === 0 || accessToken === '') { - return; - } - - api(getState).post('/api/v1/markers', params).then(() => { - dispatch(submitMarkersSuccess(params)); - }).catch(() => {}); -}, 300000, { leading: true, trailing: true }); - -export function submitMarkersSuccess({ home, notifications }) { - return { - type: MARKERS_SUBMIT_SUCCESS, - home: (home || {}).last_read_id, - notifications: (notifications || {}).last_read_id, - }; -} - -export function submitMarkers(params = {}) { - const result = (dispatch, getState) => debouncedSubmitMarkers(dispatch, getState); - - if (params.immediate === true) { - debouncedSubmitMarkers.flush(); - } - - return result; -} - -export const fetchMarkers = () => (dispatch, getState) => { - const params = { timeline: ['notifications'] }; - - dispatch(fetchMarkersRequest()); - - api(getState).get('/api/v1/markers', { params }).then(response => { - dispatch(fetchMarkersSuccess(response.data)); - }).catch(error => { - dispatch(fetchMarkersFail(error)); - }); -}; - -export function fetchMarkersRequest() { - return { - type: MARKERS_FETCH_REQUEST, - skipLoading: true, - }; -} - -export function fetchMarkersSuccess(markers) { - return { - type: MARKERS_FETCH_SUCCESS, - markers, - skipLoading: true, - }; -} - -export function fetchMarkersFail(error) { - return { - type: MARKERS_FETCH_FAIL, - error, - skipLoading: true, - skipAlert: true, - }; -} diff --git a/app/javascript/mastodon/actions/markers.ts b/app/javascript/mastodon/actions/markers.ts new file mode 100644 index 000000000..84e5b33bc --- /dev/null +++ b/app/javascript/mastodon/actions/markers.ts @@ -0,0 +1,165 @@ +import { List as ImmutableList } from 'immutable'; + +import { debounce } from 'lodash'; + +import type { MarkerJSON } from 'mastodon/api_types/markers'; +import type { RootState } from 'mastodon/store'; +import { createAppAsyncThunk } from 'mastodon/store/typed_functions'; + +import api, { authorizationTokenFromState } from '../api'; +import { compareId } from '../compare_id'; + +export const synchronouslySubmitMarkers = createAppAsyncThunk( + 'markers/submit', + async (_args, { getState }) => { + const accessToken = authorizationTokenFromState(getState); + const params = buildPostMarkersParams(getState()); + + if (Object.keys(params).length === 0 || !accessToken) { + return; + } + + // The Fetch API allows us to perform requests that will be carried out + // after the page closes. But that only works if the `keepalive` attribute + // is supported. + if ('fetch' in window && 'keepalive' in new Request('')) { + await fetch('/api/v1/markers', { + keepalive: true, + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${accessToken}`, + }, + body: JSON.stringify(params), + }); + + return; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + } else if ('navigator' && 'sendBeacon' in navigator) { + // Failing that, we can use sendBeacon, but we have to encode the data as + // FormData for DoorKeeper to recognize the token. + const formData = new FormData(); + + formData.append('bearer_token', accessToken); + + for (const [id, value] of Object.entries(params)) { + if (value.last_read_id) + formData.append(`${id}[last_read_id]`, value.last_read_id); + } + + if (navigator.sendBeacon('/api/v1/markers', formData)) { + return; + } + } + + // If neither Fetch nor sendBeacon worked, try to perform a synchronous + // request. + try { + const client = new XMLHttpRequest(); + + client.open('POST', '/api/v1/markers', false); + client.setRequestHeader('Content-Type', 'application/json'); + client.setRequestHeader('Authorization', `Bearer ${accessToken}`); + client.send(JSON.stringify(params)); + } catch (e) { + // Do not make the BeforeUnload handler error out + } + }, +); + +interface MarkerParam { + last_read_id?: string; +} + +function getLastHomeId(state: RootState): string | undefined { + /* eslint-disable @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */ + return ( + state + // @ts-expect-error state.timelines is not yet typed + .getIn(['timelines', 'home', 'items'], ImmutableList()) + // @ts-expect-error state.timelines is not yet typed + .find((item) => item !== null) + ); +} + +function getLastNotificationId(state: RootState): string | undefined { + // @ts-expect-error state.notifications is not yet typed + return state.getIn(['notifications', 'lastReadId']); +} + +const buildPostMarkersParams = (state: RootState) => { + const params = {} as { home?: MarkerParam; notifications?: MarkerParam }; + + const lastHomeId = getLastHomeId(state); + const lastNotificationId = getLastNotificationId(state); + + if (lastHomeId && compareId(lastHomeId, state.markers.home) > 0) { + params.home = { + last_read_id: lastHomeId, + }; + } + + if ( + lastNotificationId && + compareId(lastNotificationId, state.markers.notifications) > 0 + ) { + params.notifications = { + last_read_id: lastNotificationId, + }; + } + + return params; +}; + +export const submitMarkersAction = createAppAsyncThunk<{ + home: string | undefined; + notifications: string | undefined; +}>('markers/submitAction', async (_args, { getState }) => { + const accessToken = authorizationTokenFromState(getState); + const params = buildPostMarkersParams(getState()); + + if (Object.keys(params).length === 0 || accessToken === '') { + return { home: undefined, notifications: undefined }; + } + + await api(getState).post('/api/v1/markers', params); + + return { + home: params.home?.last_read_id, + notifications: params.notifications?.last_read_id, + }; +}); + +const debouncedSubmitMarkers = debounce( + (dispatch) => { + dispatch(submitMarkersAction()); + }, + 300000, + { + leading: true, + trailing: true, + }, +); + +export const submitMarkers = createAppAsyncThunk( + 'markers/submit', + (params: { immediate?: boolean }, { dispatch }) => { + debouncedSubmitMarkers(dispatch); + + if (params.immediate) { + debouncedSubmitMarkers.flush(); + } + }, +); + +export const fetchMarkers = createAppAsyncThunk( + 'markers/fetch', + async (_args, { getState }) => { + const response = await api(getState).get>( + `/api/v1/markers`, + { params: { timeline: ['notifications'] } }, + ); + + return { markers: response.data }; + }, +); diff --git a/app/javascript/mastodon/actions/picture_in_picture.js b/app/javascript/mastodon/actions/picture_in_picture.js deleted file mode 100644 index 898375abe..000000000 --- a/app/javascript/mastodon/actions/picture_in_picture.js +++ /dev/null @@ -1,46 +0,0 @@ -// @ts-check - -export const PICTURE_IN_PICTURE_DEPLOY = 'PICTURE_IN_PICTURE_DEPLOY'; -export const PICTURE_IN_PICTURE_REMOVE = 'PICTURE_IN_PICTURE_REMOVE'; - -/** - * @typedef MediaProps - * @property {string} src - * @property {boolean} muted - * @property {number} volume - * @property {number} currentTime - * @property {string} poster - * @property {string} backgroundColor - * @property {string} foregroundColor - * @property {string} accentColor - */ - -/** - * @param {string} statusId - * @param {string} accountId - * @param {string} playerType - * @param {MediaProps} props - * @returns {object} - */ -export const deployPictureInPicture = (statusId, accountId, playerType, props) => { - // @ts-expect-error - return (dispatch, getState) => { - // Do not open a player for a toot that does not exist - if (getState().hasIn(['statuses', statusId])) { - dispatch({ - type: PICTURE_IN_PICTURE_DEPLOY, - statusId, - accountId, - playerType, - props, - }); - } - }; -}; - -/* - * @return {object} - */ -export const removePictureInPicture = () => ({ - type: PICTURE_IN_PICTURE_REMOVE, -}); diff --git a/app/javascript/mastodon/actions/picture_in_picture.ts b/app/javascript/mastodon/actions/picture_in_picture.ts new file mode 100644 index 000000000..d34b508a3 --- /dev/null +++ b/app/javascript/mastodon/actions/picture_in_picture.ts @@ -0,0 +1,31 @@ +import { createAction } from '@reduxjs/toolkit'; + +import type { PIPMediaProps } from 'mastodon/reducers/picture_in_picture'; +import { createAppAsyncThunk } from 'mastodon/store/typed_functions'; + +interface DeployParams { + statusId: string; + accountId: string; + playerType: 'audio' | 'video'; + props: PIPMediaProps; +} + +export const removePictureInPicture = createAction('pip/remove'); + +export const deployPictureInPictureAction = + createAction('pip/deploy'); + +export const deployPictureInPicture = createAppAsyncThunk( + 'pip/deploy', + (args: DeployParams, { dispatch, getState }) => { + const { statusId } = args; + + // Do not open a player for a toot that does not exist + + // @ts-expect-error state.statuses is not yet typed + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + if (getState().hasIn(['statuses', statusId])) { + dispatch(deployPictureInPictureAction(args)); + } + }, +); diff --git a/app/javascript/mastodon/api.ts b/app/javascript/mastodon/api.ts index f262fd857..de597a3e3 100644 --- a/app/javascript/mastodon/api.ts +++ b/app/javascript/mastodon/api.ts @@ -29,9 +29,14 @@ const setCSRFHeader = () => { void ready(setCSRFHeader); +export const authorizationTokenFromState = (getState?: GetState) => { + return ( + getState && (getState().meta.get('access_token', '') as string | false) + ); +}; + const authorizationHeaderFromState = (getState?: GetState) => { - const accessToken = - getState && (getState().meta.get('access_token', '') as string); + const accessToken = authorizationTokenFromState(getState); if (!accessToken) { return {}; diff --git a/app/javascript/mastodon/api_types/markers.ts b/app/javascript/mastodon/api_types/markers.ts new file mode 100644 index 000000000..f7664fd7c --- /dev/null +++ b/app/javascript/mastodon/api_types/markers.ts @@ -0,0 +1,7 @@ +// See app/serializers/rest/account_serializer.rb + +export interface MarkerJSON { + last_read_id: string; + version: string; + updated_at: string; +} diff --git a/app/javascript/mastodon/api_types/media_attachments.ts b/app/javascript/mastodon/api_types/media_attachments.ts new file mode 100644 index 000000000..fc027ccd2 --- /dev/null +++ b/app/javascript/mastodon/api_types/media_attachments.ts @@ -0,0 +1,22 @@ +// See app/serializers/rest/media_attachment_serializer.rb + +export type MediaAttachmentType = + | 'image' + | 'gifv' + | 'video' + | 'unknown' + | 'audio'; + +export interface ApiMediaAttachmentJSON { + id: string; + type: MediaAttachmentType; + url: string; + preview_url: string; + remoteUrl: string; + preview_remote_url: string; + text_url: string; + // TODO: how to define this? + meta: unknown; + description?: string; + blurhash: string; +} diff --git a/app/javascript/mastodon/api_types/polls.ts b/app/javascript/mastodon/api_types/polls.ts new file mode 100644 index 000000000..8181f7b81 --- /dev/null +++ b/app/javascript/mastodon/api_types/polls.ts @@ -0,0 +1,23 @@ +import type { ApiCustomEmojiJSON } from './custom_emoji'; + +// See app/serializers/rest/poll_serializer.rb + +export interface ApiPollOptionJSON { + title: string; + votes_count: number; +} + +export interface ApiPollJSON { + id: string; + expires_at: string; + expired: boolean; + multiple: boolean; + votes_count: number; + voters_count: number; + + options: ApiPollOptionJSON[]; + emojis: ApiCustomEmojiJSON[]; + + voted: boolean; + own_votes: number[]; +} diff --git a/app/javascript/mastodon/api_types/statuses.ts b/app/javascript/mastodon/api_types/statuses.ts new file mode 100644 index 000000000..c7dd33b5d --- /dev/null +++ b/app/javascript/mastodon/api_types/statuses.ts @@ -0,0 +1,91 @@ +// See app/serializers/rest/status_serializer.rb + +import type { ApiAccountJSON } from './accounts'; +import type { ApiCustomEmojiJSON } from './custom_emoji'; +import type { ApiMediaAttachmentJSON } from './media_attachments'; +import type { ApiPollJSON } from './polls'; + +// See app/modals/status.rb +export type StatusVisibility = + | 'public' + | 'unlisted' + | 'private' + // | 'limited' // This is never exposed to the API (they become `private`) + | 'direct'; + +export interface ApiStatusApplicationJSON { + name: string; + website: string; +} + +export interface ApiTagJSON { + name: string; + url: string; +} + +export interface ApiMentionJSON { + id: string; + username: string; + url: string; + acct: string; +} + +export interface ApiPreviewCardJSON { + url: string; + title: string; + description: string; + language: string; + type: string; + author_name: string; + author_url: string; + provider_name: string; + provider_url: string; + html: string; + width: number; + height: number; + image: string; + image_description: string; + embed_url: string; + blurhash: string; + published_at: string; +} + +export interface ApiStatusJSON { + id: string; + created_at: string; + in_reply_to_id?: string; + in_reply_to_account_id?: string; + sensitive: boolean; + spoiler_text?: string; + visibility: StatusVisibility; + language: string; + uri: string; + url: string; + replies_count: number; + reblogs_count: number; + favorites_count: number; + edited_at?: string; + + favorited?: boolean; + reblogged?: boolean; + muted?: boolean; + bookmarked?: boolean; + pinned?: boolean; + + // filtered: FilterResult[] + filtered: unknown; // TODO + content?: string; + text?: string; + + reblog?: ApiStatusJSON; + application?: ApiStatusApplicationJSON; + account: ApiAccountJSON; + media_attachments: ApiMediaAttachmentJSON[]; + mentions: ApiMentionJSON[]; + + tags: ApiTagJSON[]; + emojis: ApiCustomEmojiJSON[]; + + card?: ApiPreviewCardJSON; + poll?: ApiPollJSON; +} diff --git a/app/javascript/mastodon/common.js b/app/javascript/mastodon/common.js index 0ec844934..511568aa0 100644 --- a/app/javascript/mastodon/common.js +++ b/app/javascript/mastodon/common.js @@ -2,7 +2,7 @@ import Rails from '@rails/ujs'; import 'font-awesome/css/font-awesome.css'; export function start() { - require.context('../images/', true); + require.context('../images/', true, /\.(jpg|png|svg)$/); try { Rails.start(); diff --git a/app/javascript/mastodon/components/account.jsx b/app/javascript/mastodon/components/account.jsx index 4a99dd0bb..3282696d3 100644 --- a/app/javascript/mastodon/components/account.jsx +++ b/app/javascript/mastodon/components/account.jsx @@ -1,17 +1,19 @@ import PropTypes from 'prop-types'; +import { useCallback } from 'react'; -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; +import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; import classNames from 'classnames'; import { Link } from 'react-router-dom'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; +import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react'; import { EmptyAccount } from 'mastodon/components/empty_account'; import { ShortNumber } from 'mastodon/components/short_number'; import { VerifiedBadge } from 'mastodon/components/verified_badge'; +import DropdownMenuContainer from '../containers/dropdown_menu_container'; import { me } from '../initial_state'; import { Avatar } from './avatar'; @@ -30,151 +32,151 @@ const messages = defineMessages({ unmute_notifications: { id: 'account.unmute_notifications_short', defaultMessage: 'Unmute notifications' }, mute: { id: 'account.mute_short', defaultMessage: 'Mute' }, block: { id: 'account.block_short', defaultMessage: 'Block' }, + more: { id: 'status.more', defaultMessage: 'More' }, }); -class Account extends ImmutablePureComponent { +const Account = ({ size = 46, account, onFollow, onBlock, onMute, onMuteNotifications, hidden, minimal, defaultAction, withBio }) => { + const intl = useIntl(); - static propTypes = { - size: PropTypes.number, - account: ImmutablePropTypes.record, - onFollow: PropTypes.func, - onBlock: PropTypes.func, - onMute: PropTypes.func, - onMuteNotifications: PropTypes.func, - intl: PropTypes.object.isRequired, - hidden: PropTypes.bool, - minimal: PropTypes.bool, - defaultAction: PropTypes.string, - withBio: PropTypes.bool, - }; + const handleFollow = useCallback(() => { + onFollow(account); + }, [onFollow, account]); - static defaultProps = { - size: 46, - }; + const handleBlock = useCallback(() => { + onBlock(account); + }, [onBlock, account]); - handleFollow = () => { - this.props.onFollow(this.props.account); - }; + const handleMute = useCallback(() => { + onMute(account); + }, [onMute, account]); - handleBlock = () => { - this.props.onBlock(this.props.account); - }; + const handleMuteNotifications = useCallback(() => { + onMuteNotifications(account, true); + }, [onMuteNotifications, account]); - handleMute = () => { - this.props.onMute(this.props.account); - }; + const handleUnmuteNotifications = useCallback(() => { + onMuteNotifications(account, false); + }, [onMuteNotifications, account]); - handleMuteNotifications = () => { - this.props.onMuteNotifications(this.props.account, true); - }; - - handleUnmuteNotifications = () => { - this.props.onMuteNotifications(this.props.account, false); - }; - - render () { - const { account, intl, hidden, withBio, defaultAction, size, minimal } = this.props; - - if (!account) { - return ; - } - - if (hidden) { - return ( - <> - {account.get('display_name')} - {account.get('username')} - - ); - } - - let buttons; - - if (account.get('id') !== me && account.get('relationship', null) !== null) { - const following = account.getIn(['relationship', 'following']); - const requested = account.getIn(['relationship', 'requested']); - const blocking = account.getIn(['relationship', 'blocking']); - const muting = account.getIn(['relationship', 'muting']); - - if (requested) { - buttons = .", + "domain_pill.who_you_are": "Protože handle říká kdo jsi a kde jsi, mohou s tebou lidé komunikovat napříč sociálními weby .", + "domain_pill.your_handle": "Tvůj handle:", + "domain_pill.your_server": "Tvůj digitální domov, kde žijí všechny tvé příspěvky. Nelíbí se ti? Kdykoliv se přesuň na jiný server a vezmi si sebou i své sledující.", + "domain_pill.your_username": "Tvůj jedinečný identifikátor na tomto serveru. Je možné najít uživatele se stejným uživatelským jménem na jiných serverech.", "embed.instructions": "Pro přidání příspěvku na vaši webovou stránku zkopírujte níže uvedený kód.", "embed.preview": "Takhle to bude vypadat:", "emoji_button.activity": "Aktivita", @@ -236,6 +266,7 @@ "empty_column.list": "V tomto seznamu zatím nic není. Až nějaký člen z tohoto seznamu zveřejní nový příspěvek, objeví se zde.", "empty_column.lists": "Zatím nemáte žádné seznamy. Až nějaký vytvoříte, zobrazí se zde.", "empty_column.mutes": "Zatím jste neskryli žádného uživatele.", + "empty_column.notification_requests": "Vyčištěno! Nic tu není. Jakmile obdržíš nové notifikace, objeví se zde podle tvého nastavení.", "empty_column.notifications": "Zatím nemáte žádná oznámení. Až s vámi někdo bude interagovat, uvidíte to zde.", "empty_column.public": "Tady nic není! Napište něco veřejně, nebo začněte ručně sledovat uživatele z jiných serverů, aby tu něco přibylo", "error.unexpected_crash.explanation": "Kvůli chybě v našem kódu nebo problému s kompatibilitou prohlížeče nemohla být tato stránka správně zobrazena.", @@ -266,6 +297,9 @@ "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", "firehose.remote": "Ostatní servery", @@ -394,6 +428,15 @@ "loading_indicator.label": "Načítání…", "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é", @@ -429,14 +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:", @@ -462,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", @@ -638,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", @@ -661,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/da.json b/app/javascript/mastodon/locales/da.json index ca32ba298..a23d53733 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -220,7 +220,7 @@ "domain_pill.activitypub_lets_connect": "Det muliggør at komme i forbindelse og interagere med folk ikke kun på Mastodon, men også på tværs af forskellige sociale apps.", "domain_pill.activitypub_like_language": "ActivityPub er \"sproget\", Mastodon taler med andre sociale netværk.", "domain_pill.server": "Server", - "domain_pill.their_handle": "Deres handle:", + "domain_pill.their_handle": "Vedkommendes handle:", "domain_pill.username": "Brugernavn", "domain_pill.whats_in_a_handle": "Hvad er der i et handle (@brugernavn)?", "domain_pill.who_they_are": "Da et handle fortæller, hvem nogen er, og hvor de er, kan man interagere med folk på tværs af det sociale net af .", @@ -295,6 +295,7 @@ "filter_modal.select_filter.subtitle": "Vælg en eksisterende kategori eller opret en ny", "filter_modal.select_filter.title": "Filtrér dette indlæg", "filter_modal.title.status": "Filtrér et indlæg", + "filtered_notifications_banner.mentions": "{count, plural, one {omtale} other {omtaler}}", "filtered_notifications_banner.pending_requests": "Notifikationer fra {count, plural, =0 {ingen} one {én person} other {# personer}} du måske kender", "filtered_notifications_banner.title": "Filtrerede notifikationer", "firehose.all": "Alle", @@ -305,6 +306,8 @@ "follow_requests.unlocked_explanation": "Selvom din konto ikke er låst, synes {domain}-personalet, du måske bør gennemgå disse anmodninger manuelt.", "follow_suggestions.curated_suggestion": "Personaleudvalgt", "follow_suggestions.dismiss": "Vis ikke igen", + "follow_suggestions.featured_longer": "Håndplukket af {domain}-teamet", + "follow_suggestions.friends_of_friends_longer": "Populært blandt personer, som følges", "follow_suggestions.hints.featured": "Denne profil er håndplukket af {domain}-teamet.", "follow_suggestions.hints.friends_of_friends": "Denne profil er populær blandt de personer, som følges.", "follow_suggestions.hints.most_followed": "Denne profil er en af de mest fulgte på {domain}.", @@ -312,6 +315,8 @@ "follow_suggestions.hints.similar_to_recently_followed": "Denne profil svarer til de profiler, som senest er blevet fulgt.", "follow_suggestions.personalized_suggestion": "Personligt forslag", "follow_suggestions.popular_suggestion": "Populært forslag", + "follow_suggestions.popular_suggestion_longer": "Populært på {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Svarende til profiler, som for nylig er fulgt", "follow_suggestions.view_all": "Vis alle", "follow_suggestions.who_to_follow": "Hvem, som skal følges", "followed_tags": "Hashtag, som følges", @@ -466,9 +471,23 @@ "notification.follow": "{name} begyndte at følge dig", "notification.follow_request": "{name} har anmodet om at følge dig", "notification.mention": "{name} nævnte dig", + "notification.moderation-warning.learn_more": "Læs mere", + "notification.moderation_warning": "Du er tildelt en moderationsadvarsel", + "notification.moderation_warning.action_delete_statuses": "Nogle af dine indlæg er blevet fjernet.", + "notification.moderation_warning.action_disable": "Din konto er blevet deaktiveret.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Nogle af dine indlæg er blevet markeret som sensitive.", + "notification.moderation_warning.action_none": "Din konto er tildelt en moderationsadvarsel.", + "notification.moderation_warning.action_sensitive": "Dine indlæg markeres fra nu af som sensitive.", + "notification.moderation_warning.action_silence": "Din konto er blevet begrænset.", + "notification.moderation_warning.action_suspend": "Din konto er suspenderet.", "notification.own_poll": "Din afstemning er afsluttet", "notification.poll": "En afstemning, hvori du stemte, er slut", "notification.reblog": "{name} boostede dit indlæg", + "notification.relationships_severance_event": "Mistede forbindelser med {name}", + "notification.relationships_severance_event.account_suspension": "En admin fra {from} har suspenderet {target}, hvofor opdateringer herfra eller interaktion hermed ikke længer er mulig.", + "notification.relationships_severance_event.domain_block": "En admin fra {from} har blokeret {target}, herunder {followersCount} tilhængere og {followingCount, plural, one {# konto, der} other {# konti, som}} følges.", + "notification.relationships_severance_event.learn_more": "Læs mere", + "notification.relationships_severance_event.user_domain_block": "{target} er blevet blokeret, og {followersCount} tilhængere samt {followingCount, plural, one {# konto, der} other {# konti, som}} følges, er hermed fjernet.", "notification.status": "{name} har netop postet", "notification.update": "{name} redigerede et indlæg", "notification_requests.accept": "Acceptér", @@ -481,6 +500,8 @@ "notifications.column_settings.admin.sign_up": "Nye tilmeldinger:", "notifications.column_settings.alert": "Computernotifikationer", "notifications.column_settings.favourite": "Favoritter:", + "notifications.column_settings.filter_bar.advanced": "Vis alle kategorier", + "notifications.column_settings.filter_bar.category": "Hurtigfiltreringsbjælke", "notifications.column_settings.follow": "Nye følgere:", "notifications.column_settings.follow_request": "Nye følgeanmodninger:", "notifications.column_settings.mention": "Omtaler:", @@ -585,12 +606,6 @@ "refresh": "Genindlæs", "regeneration_indicator.label": "Indlæser…", "regeneration_indicator.sublabel": "Din hjemmetidslinje klargøres!", - "relationship_severance_notification.purged_data": "renset af administratorer", - "relationship_severance_notification.relationships": "{count, plural, one {# forhold} other {# forhold}}", - "relationship_severance_notification.types.account_suspension": "Konto er blevet suspenderet", - "relationship_severance_notification.types.domain_block": "Domæne er blevet suspenderet", - "relationship_severance_notification.types.user_domain_block": "Dette domæne blev blokeret", - "relationship_severance_notification.view": "Vis", "relative_time.days": "{number}d", "relative_time.full.days": "{number, plural, one {# dag} other {# dage}} siden", "relative_time.full.hours": "{number, plural, one {# time} other {# timer}} siden", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index bed336f76..59d3d0965 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -85,7 +85,7 @@ "alert.rate_limited.message": "Bitte versuche es nach {retry_time, time, medium} erneut.", "alert.rate_limited.title": "Anfragelimit überschritten", "alert.unexpected.message": "Ein unerwarteter Fehler ist aufgetreten.", - "alert.unexpected.title": "Ups!", + "alert.unexpected.title": "Oha!", "announcement.announcement": "Ankündigung", "attachments_list.unprocessed": "(ausstehend)", "audio.hide": "Audio ausblenden", @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Einem vorhandenen Filter hinzufügen oder einen neuen erstellen", "filter_modal.select_filter.title": "Diesen Beitrag filtern", "filter_modal.title.status": "Beitrag per Filter ausblenden", + "filtered_notifications_banner.mentions": "{count, plural, one {Erwähnung} other {Erwähnungen}}", "filtered_notifications_banner.pending_requests": "Benachrichtigungen von {count, plural, =0 {keinem Profil, das du möglicherweise kennst} one {einem Profil, das du möglicherweise kennst} other {# Profilen, die du möglicherweise kennst}}", "filtered_notifications_banner.title": "Gefilterte Benachrichtigungen", "firehose.all": "Alles", @@ -307,6 +308,8 @@ "follow_requests.unlocked_explanation": "Auch wenn dein Konto öffentlich bzw. nicht geschützt ist, haben die Moderator*innen von {domain} gedacht, dass du diesen Follower lieber manuell bestätigen solltest.", "follow_suggestions.curated_suggestion": "Vom Server-Team empfohlen", "follow_suggestions.dismiss": "Nicht mehr anzeigen", + "follow_suggestions.featured_longer": "Vom {domain}-Team ausgewählt", + "follow_suggestions.friends_of_friends_longer": "Beliebt bei Leuten, denen du folgst", "follow_suggestions.hints.featured": "Dieses Profil wurde vom {domain}-Team ausgewählt.", "follow_suggestions.hints.friends_of_friends": "Dieses Profil ist bei deinen Followern beliebt.", "follow_suggestions.hints.most_followed": "Dieses Profil ist eines der am meisten gefolgten auf {domain}.", @@ -314,6 +317,8 @@ "follow_suggestions.hints.similar_to_recently_followed": "Dieses Profil ähnelt den Profilen, denen du in letzter Zeit gefolgt hast.", "follow_suggestions.personalized_suggestion": "Persönliche Empfehlung", "follow_suggestions.popular_suggestion": "Beliebte Empfehlung", + "follow_suggestions.popular_suggestion_longer": "Beliebt auf {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Ähnlich zu Profilen, denen du seit kurzem folgst", "follow_suggestions.view_all": "Alle anzeigen", "follow_suggestions.who_to_follow": "Empfohlene Profile", "followed_tags": "Gefolgte Hashtags", @@ -468,10 +473,23 @@ "notification.follow": "{name} folgt dir", "notification.follow_request": "{name} möchte dir folgen", "notification.mention": "{name} erwähnte dich", + "notification.moderation-warning.learn_more": "Mehr erfahren", + "notification.moderation_warning": "Du wurdest von den Moderator*innen verwarnt", + "notification.moderation_warning.action_delete_statuses": "Einige deiner Beiträge sind entfernt worden.", + "notification.moderation_warning.action_disable": "Dein Konto wurde deaktiviert.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Einige deiner Beiträge wurden mit einer Inhaltswarnung versehen.", + "notification.moderation_warning.action_none": "Dein Konto ist von den Moderator*innen verwarnt worden.", + "notification.moderation_warning.action_sensitive": "Deine zukünftigen Beiträge werden mit einer Inhaltswarnung versehen.", + "notification.moderation_warning.action_silence": "Dein Konto wurde eingeschränkt.", + "notification.moderation_warning.action_suspend": "Dein Konto wurde gesperrt.", "notification.own_poll": "Deine Umfrage ist beendet", "notification.poll": "Eine Umfrage, an der du teilgenommen hast, ist beendet", "notification.reblog": "{name} teilte deinen Beitrag", - "notification.severed_relationships": "Beziehungen zu {name} getrennt", + "notification.relationships_severance_event": "Verbindungen mit {name} verloren", + "notification.relationships_severance_event.account_suspension": "Ein Admin von {from} hat {target} gesperrt. Du wirst von diesem Profil keine Updates mehr erhalten und auch nicht mit ihm interagieren können.", + "notification.relationships_severance_event.domain_block": "Ein Admin von {from} hat {target} blockiert – darunter {followersCount} deiner Follower und {followingCount, plural, one {# Konto, dem} other {# Konten, denen}} du folgst.", + "notification.relationships_severance_event.learn_more": "Mehr erfahren", + "notification.relationships_severance_event.user_domain_block": "Du hast {target} blockiert – {followersCount} deiner Follower und {followingCount, plural, one {# Konto, dem} other {# Konten, denen}} du folgst, wurden entfernt.", "notification.status": "{name} hat gerade etwas gepostet", "notification.update": "{name} bearbeitete einen Beitrag", "notification_requests.accept": "Akzeptieren", @@ -484,6 +502,8 @@ "notifications.column_settings.admin.sign_up": "Neue Registrierungen:", "notifications.column_settings.alert": "Desktop-Benachrichtigungen", "notifications.column_settings.favourite": "Favoriten:", + "notifications.column_settings.filter_bar.advanced": "Alle Filterkategorien anzeigen", + "notifications.column_settings.filter_bar.category": "Filterleiste", "notifications.column_settings.follow": "Neue Follower:", "notifications.column_settings.follow_request": "Neue Follower-Anfragen:", "notifications.column_settings.mention": "Erwähnungen:", @@ -529,11 +549,11 @@ "onboarding.follows.empty": "Bedauerlicherweise können aktuell keine Ergebnisse angezeigt werden. Du kannst die Suche verwenden oder den Reiter „Entdecken“ auswählen, um neue Leute zum Folgen zu finden – oder du versuchst es später erneut.", "onboarding.follows.lead": "Deine Startseite ist der primäre Anlaufpunkt, um Mastodon zu erleben. Je mehr Profilen du folgst, umso aktiver und interessanter wird sie. Damit du direkt loslegen kannst, gibt es hier ein paar Vorschläge:", "onboarding.follows.title": "Personalisiere deine Startseite", - "onboarding.profile.discoverable": "Mein Profil auffindbar machen", + "onboarding.profile.discoverable": "Mein Profil darf entdeckt werden", "onboarding.profile.discoverable_hint": "Wenn du entdeckt werden möchtest, dann können deine Beiträge in Suchergebnissen und Trends erscheinen. Dein Profil kann ebenfalls anderen mit ähnlichen Interessen vorgeschlagen werden.", "onboarding.profile.display_name": "Anzeigename", "onboarding.profile.display_name_hint": "Dein richtiger Name oder dein Fantasiename …", - "onboarding.profile.lead": "Du kannst das später in den Einstellungen vervollständigen, wo noch mehr Anpassungsmöglichkeiten zur Verfügung stehen.", + "onboarding.profile.lead": "Du kannst dein Profil später in den Einstellungen vervollständigen. Dort stehen weitere Anpassungsmöglichkeiten zur Verfügung.", "onboarding.profile.note": "Über mich", "onboarding.profile.note_hint": "Du kannst andere @Profile erwähnen oder #Hashtags verwenden …", "onboarding.profile.save_and_continue": "Speichern und fortfahren", @@ -549,16 +569,16 @@ "onboarding.start.title": "Du hast es geschafft!", "onboarding.steps.follow_people.body": "Interessanten Profilen zu folgen ist das, was Mastodon ausmacht.", "onboarding.steps.follow_people.title": "Personalisiere deine Startseite", - "onboarding.steps.publish_status.body": "Begrüße die Welt mit Text, Fotos, Videos oder Umfragen {emoji}", + "onboarding.steps.publish_status.body": "Begrüße die Welt mit Text, Fotos, Videos oder Umfragen. {emoji}", "onboarding.steps.publish_status.title": "Erstelle deinen ersten Beitrag", "onboarding.steps.setup_profile.body": "Mit einem vollständigen Profil interagieren andere eher mit dir.", "onboarding.steps.setup_profile.title": "Personalisiere dein Profil", - "onboarding.steps.share_profile.body": "Lass deine Freund*innen wissen, wie sie dich auf Mastodon finden können", + "onboarding.steps.share_profile.body": "Lass deine Freund*innen wissen, wie sie dich auf Mastodon finden können.", "onboarding.steps.share_profile.title": "Teile dein Mastodon-Profil", "onboarding.tips.2fa": "Wusstest du schon? Du kannst die Sicherheit deines Kontos erhöhen, indem du die Zwei-Faktor-Authentisierung in deinen Kontoeinstellungen aktivierst. Dafür ist keine Telefonnummer notwendig und es funktioniert jede beliebige TOTP-App!", "onboarding.tips.accounts_from_other_servers": "Wusstest du schon? Da Mastodon dezentralisiert ist, werden einige Profile, denen du begegnest, auf anderen Servern als deinem bereitgestellt. Und trotzdem kannst du uneingeschränkt mit ihnen interagieren! Der Servername befindet sich in der zweiten Hälfte ihres Profilnamens!", "onboarding.tips.migration": "Wusstest du schon? Wenn du das Gefühl hast, dass {domain} in Zukunft nicht die richtige Serverwahl für dich ist, kannst du auf einen anderen Mastodon-Server umziehen, ohne deine Follower zu verlieren. Du kannst sogar deinen eigenen Server betreiben!", - "onboarding.tips.verification": "Wusstest du schon? Du kannst dein Konto verifizieren, indem du auf deiner Website auf dein Mastodon-Profil verlinkst und den Link deiner Website zu deinem Profil hinzufügst. Keine Gebühren oder Dokumente erforderlich!", + "onboarding.tips.verification": "Wusstest du schon? Du kannst dein Konto verifizieren, indem du auf deiner Website auf dein Mastodon-Profil verlinkst und den Link deiner Website zu deinem Profil hinzufügst. Völlig kostenlos und ohne Dokumente einsenden zu müssen!", "password_confirmation.exceeds_maxlength": "Passwortbestätigung überschreitet die maximal erlaubte Zeichenanzahl", "password_confirmation.mismatching": "Passwortbestätigung stimmt nicht überein", "picture_in_picture.restore": "Zurücksetzen", @@ -588,12 +608,6 @@ "refresh": "Aktualisieren", "regeneration_indicator.label": "Wird geladen …", "regeneration_indicator.sublabel": "Deine Startseite wird gerade vorbereitet!", - "relationship_severance_notification.purged_data": "von Administrator*innen entfernt", - "relationship_severance_notification.relationships": "{count, plural, one {# Beziehung} other {# Beziehungen}}", - "relationship_severance_notification.types.account_suspension": "Konto wurde gesperrt", - "relationship_severance_notification.types.domain_block": "Domain wurde gesperrt", - "relationship_severance_notification.types.user_domain_block": "Du hast diese Domain blockiert", - "relationship_severance_notification.view": "Anzeigen", "relative_time.days": "{number} T.", "relative_time.full.days": "vor {number, plural, one {# Tag} other {# Tagen}}", "relative_time.full.hours": "vor {number, plural, one {# Stunde} other {# Stunden}}", diff --git a/app/javascript/mastodon/locales/en-GB.json b/app/javascript/mastodon/locales/en-GB.json index 228a16def..6c24d5a26 100644 --- a/app/javascript/mastodon/locales/en-GB.json +++ b/app/javascript/mastodon/locales/en-GB.json @@ -89,6 +89,14 @@ "announcement.announcement": "Announcement", "attachments_list.unprocessed": "(unprocessed)", "audio.hide": "Hide audio", + "block_modal.remote_users_caveat": "We will ask the server {domain} to respect your decision. However, compliance is not guaranteed since some servers may handle blocks differently. Public posts may still be visible to non-logged-in users.", + "block_modal.show_less": "Show less", + "block_modal.show_more": "Show more", + "block_modal.they_cant_mention": "They can't mention or follow you.", + "block_modal.they_cant_see_posts": "They can't see your posts and you won't see theirs.", + "block_modal.they_will_know": "They can see that they're blocked.", + "block_modal.title": "Block user?", + "block_modal.you_wont_see_mentions": "You won't see posts that mention them.", "boost_modal.combo": "You can press {combo} to skip this next time", "bundle_column_error.copy_stacktrace": "Copy error report", "bundle_column_error.error.body": "The requested page could not be rendered. It could be due to a bug in our code, or a browser compatibility issue.", @@ -169,6 +177,7 @@ "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?", "confirmations.discard_edit_media.confirm": "Discard", "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.domain_block.confirm": "Block server", "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.", "confirmations.edit.confirm": "Edit", "confirmations.edit.message": "Editing now will overwrite the message you are currently composing. Are you sure you want to proceed?", @@ -200,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", @@ -236,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.", @@ -266,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", @@ -388,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", @@ -423,14 +472,25 @@ "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:", "notifications.column_settings.mention": "Mentions:", @@ -456,6 +516,15 @@ "notifications.permission_denied": "Desktop notifications are unavailable due to previously denied browser permissions request", "notifications.permission_denied_alert": "Desktop notifications can't be enabled, as browser permission has been denied before", "notifications.permission_required": "Desktop notifications are unavailable because the required permission has not been granted.", + "notifications.policy.filter_new_accounts.hint": "Created within the past {days, plural, one {one day} other {# days}}", + "notifications.policy.filter_new_accounts_title": "New accounts", + "notifications.policy.filter_not_followers_hint": "Including people who have been following you fewer than {days, plural, one {one day} other {# days}}", + "notifications.policy.filter_not_followers_title": "People not following you", + "notifications.policy.filter_not_following_hint": "Until you manually approve them", + "notifications.policy.filter_not_following_title": "People you don't follow", + "notifications.policy.filter_private_mentions_hint": "Filtered unless it's in reply to your own mention or if you follow the sender", + "notifications.policy.filter_private_mentions_title": "Unsolicited private mentions", + "notifications.policy.title": "Filter out notifications from…", "notifications_permission_banner.enable": "Enable desktop notifications", "notifications_permission_banner.how_to_control": "To receive notifications when Mastodon isn't open, enable desktop notifications. You can control precisely which types of interactions generate desktop notifications through the {icon} button above once they're enabled.", "notifications_permission_banner.title": "Never miss a thing", @@ -632,9 +701,11 @@ "status.direct": "Privately mention @{name}", "status.direct_indicator": "Private mention", "status.edit": "Edit", + "status.edited": "Last edited {date}", "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favourite", + "status.favourites": "{count, plural, one {favorite} other {favorites}}", "status.filter": "Filter this post", "status.filtered": "Filtered", "status.hide": "Hide post", @@ -655,6 +726,7 @@ "status.reblog": "Boost", "status.reblog_private": "Boost with original visibility", "status.reblogged_by": "{name} boosted", + "status.reblogs": "{count, plural, one {boost} other {boosts}}", "status.reblogs.empty": "No one has boosted this post yet. When someone does, they will show up here.", "status.redraft": "Delete & re-draft", "status.remove_bookmark": "Remove bookmark", diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 1134b393a..9d127b6b0 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -297,6 +297,7 @@ "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", @@ -307,6 +308,8 @@ "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.featured_longer": "Hand-picked by the {domain} team", + "follow_suggestions.friends_of_friends_longer": "Popular among people you follow", "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}.", @@ -314,6 +317,8 @@ "follow_suggestions.hints.similar_to_recently_followed": "This profile is similar to the profiles you have most recently followed.", "follow_suggestions.personalized_suggestion": "Personalized suggestion", "follow_suggestions.popular_suggestion": "Popular suggestion", + "follow_suggestions.popular_suggestion_longer": "Popular on {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Similar to profiles you recently followed", "follow_suggestions.view_all": "View all", "follow_suggestions.who_to_follow": "Who to follow", "followed_tags": "Followed hashtags", @@ -468,10 +473,23 @@ "notification.follow": "{name} followed you", "notification.follow_request": "{name} has requested to follow you", "notification.mention": "{name} mentioned you", + "notification.moderation-warning.learn_more": "Learn more", + "notification.moderation_warning": "Your have received a moderation warning", + "notification.moderation_warning.action_delete_statuses": "Some of your posts have been removed.", + "notification.moderation_warning.action_disable": "Your account has been disabled.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Some of your posts have been marked as sensitive.", + "notification.moderation_warning.action_none": "Your account has received a moderation warning.", + "notification.moderation_warning.action_sensitive": "Your posts will be marked as sensitive from now on.", + "notification.moderation_warning.action_silence": "Your account has been limited.", + "notification.moderation_warning.action_suspend": "Your account has been suspended.", "notification.own_poll": "Your poll has ended", "notification.poll": "A poll you have voted in has ended", "notification.reblog": "{name} boosted your post", - "notification.severed_relationships": "Relationships with {name} severed", + "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", @@ -590,12 +608,6 @@ "refresh": "Refresh", "regeneration_indicator.label": "Loading…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", - "relationship_severance_notification.purged_data": "purged by administrators", - "relationship_severance_notification.relationships": "{count, plural, one {# relationship} other {# relationships}}", - "relationship_severance_notification.types.account_suspension": "Account has been suspended", - "relationship_severance_notification.types.domain_block": "Domain has been suspended", - "relationship_severance_notification.types.user_domain_block": "You blocked this domain", - "relationship_severance_notification.view": "View", "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", diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index fec707be6..2cf419862 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.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 este mensaje", "filter_modal.title.status": "Filtrar un mensaje", + "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": "Todos", @@ -427,7 +428,7 @@ "loading_indicator.label": "Cargando…", "media_gallery.toggle_visible": "Ocultar {number, plural, one {imagen} other {imágenes}}", "moved_to_account_banner.text": "Tu cuenta {disabledAccount} está actualmente deshabilitada porque te mudaste a {movedToAccount}.", - "mute_modal.hide_from_notifications": "Ocultar de las notificaciones", + "mute_modal.hide_from_notifications": "Ocultar en las notificaciones", "mute_modal.hide_options": "Ocultar opciones", "mute_modal.indefinite": "Hasta que deje de silenciarlos", "mute_modal.show_options": "Mostrar opciones", @@ -471,7 +472,11 @@ "notification.own_poll": "Tu encuesta finalizó", "notification.poll": "Finalizó una encuesta en la que votaste", "notification.reblog": "{name} adhirió a tu mensaje", - "notification.severed_relationships": "Relaciones con {name} cortadas", + "notification.relationships_severance_event": "Conexiones perdidas con {name}", + "notification.relationships_severance_event.account_suspension": "Un administrador de {from} suspendió a {target}, lo que significa que ya no podés recibir actualizaciones de esa cuenta o interactuar con la misma.", + "notification.relationships_severance_event.domain_block": "Un administrador de {from} bloqueó a {target}, incluyendo {followersCount} de tus seguidores y {followingCount, plural, one {# cuenta} other {# cuentas}} que seguís.", + "notification.relationships_severance_event.learn_more": "Aprendé más", + "notification.relationships_severance_event.user_domain_block": "Bloqueaste a {target}, eliminando {followersCount} de tus seguidores y {followingCount, plural, one {# cuenta} other {# cuentas}} que seguís.", "notification.status": "{name} acaba de enviar un mensaje", "notification.update": "{name} editó un mensaje", "notification_requests.accept": "Aceptar", @@ -484,6 +489,8 @@ "notifications.column_settings.admin.sign_up": "Nuevos registros:", "notifications.column_settings.alert": "Notificaciones de escritorio", "notifications.column_settings.favourite": "Favoritos:", + "notifications.column_settings.filter_bar.advanced": "Mostrar todas las categorías", + "notifications.column_settings.filter_bar.category": "Barra de filtrado rápido", "notifications.column_settings.follow": "Nuevos seguidores:", "notifications.column_settings.follow_request": "Nuevas solicitudes de seguimiento:", "notifications.column_settings.mention": "Menciones:", @@ -588,12 +595,6 @@ "refresh": "Refrescar", "regeneration_indicator.label": "Cargando…", "regeneration_indicator.sublabel": "¡Se está preparando tu línea temporal principal!", - "relationship_severance_notification.purged_data": "purgada por administradores", - "relationship_severance_notification.relationships": "{count, plural, one {# relación} other {# relaciones}}", - "relationship_severance_notification.types.account_suspension": "La cuenta fue suspendida", - "relationship_severance_notification.types.domain_block": "El dominio fue suspendido", - "relationship_severance_notification.types.user_domain_block": "Bloqueaste este dominio", - "relationship_severance_notification.view": "Ver", "relative_time.days": "{number}d", "relative_time.full.days": "{number, plural,one {hace # día} other {hace # días}}", "relative_time.full.hours": "{number, plural,one {hace # hora} other {hace # horas}}", diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json index 00dcb8146..1d8d4cedf 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", @@ -471,6 +472,11 @@ "notification.own_poll": "Tu encuesta ha terminado", "notification.poll": "Una encuesta en la que has votado ha terminado", "notification.reblog": "{name} ha retooteado tu estado", + "notification.relationships_severance_event": "Conexiones perdidas con {name}", + "notification.relationships_severance_event.account_suspension": "Un administrador de {from} ha suspendido {target}, lo que significa que ya no puedes recibir actualizaciones de sus cuentas o interactuar con ellas.", + "notification.relationships_severance_event.domain_block": "Un administrador de {from} ha bloqueado {target}, incluyendo {followersCount} de tus seguidores y {followingCount, plural, one {# cuenta} other {# cuentas}} que sigues.", + "notification.relationships_severance_event.learn_more": "Más información", + "notification.relationships_severance_event.user_domain_block": "Has bloqueado {target}, eliminando {followersCount} de tus seguidores y {followingCount, plural, one {# cuenta} other {# cuentas}} que sigues.", "notification.status": "{name} acaba de publicar", "notification.update": "{name} editó una publicación", "notification_requests.accept": "Aceptar", @@ -483,6 +489,8 @@ "notifications.column_settings.admin.sign_up": "Registros nuevos:", "notifications.column_settings.alert": "Notificaciones de escritorio", "notifications.column_settings.favourite": "Favoritos:", + "notifications.column_settings.filter_bar.advanced": "Mostrar todas las categorías", + "notifications.column_settings.filter_bar.category": "Barra de filtrado rápido", "notifications.column_settings.follow": "Nuevos seguidores:", "notifications.column_settings.follow_request": "Nuevas solicitudes de seguimiento:", "notifications.column_settings.mention": "Menciones:", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index 728f4d05f..149a37d74 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", @@ -471,6 +472,11 @@ "notification.own_poll": "Tu encuesta ha terminado", "notification.poll": "Una encuesta en la que has votado ha terminado", "notification.reblog": "{name} ha impulsado tu publicación", + "notification.relationships_severance_event": "Conexiones perdidas con {name}", + "notification.relationships_severance_event.account_suspension": "Un administrador de {from} ha suspendido {target}, lo que significa que ya no puedes recibir actualizaciones de sus cuentas o interactuar con ellas.", + "notification.relationships_severance_event.domain_block": "Un administrador de {from} ha bloqueado {target}, incluyendo {followersCount} de tus seguidores y {followingCount, plural, one {# cuenta} other {# cuentas}} que sigues.", + "notification.relationships_severance_event.learn_more": "Más información", + "notification.relationships_severance_event.user_domain_block": "Has bloqueado {target}, eliminando {followersCount} de tus seguidores y {followingCount, plural, one {# cuenta} other {# cuentas}} que sigues.", "notification.status": "{name} acaba de publicar", "notification.update": "{name} editó una publicación", "notification_requests.accept": "Aceptar", @@ -483,6 +489,8 @@ "notifications.column_settings.admin.sign_up": "Nuevos registros:", "notifications.column_settings.alert": "Notificaciones de escritorio", "notifications.column_settings.favourite": "Favoritos:", + "notifications.column_settings.filter_bar.advanced": "Mostrar todas las categorías", + "notifications.column_settings.filter_bar.category": "Barra de filtrado rápido", "notifications.column_settings.follow": "Nuevos seguidores:", "notifications.column_settings.follow_request": "Nuevas solicitudes de seguimiento:", "notifications.column_settings.mention": "Menciones:", @@ -634,7 +642,7 @@ "report.statuses.subtitle": "Selecciona todos los que correspondan", "report.statuses.title": "¿Hay alguna publicación que respalde este informe?", "report.submit": "Enviar", - "report.target": "Reportando", + "report.target": "Reportando {target}", "report.thanks.take_action": "Aquí están tus opciones para controlar lo que ves en Mastodon:", "report.thanks.take_action_actionable": "Mientras revisamos esto, puedes tomar medidas contra @{name}:", "report.thanks.title": "¿No quieres esto?", diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index f617ced6e..b2759d66c 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -92,7 +92,11 @@ "block_modal.remote_users_caveat": "Serverile {domain} edastatakse palve otsust järgida. Ometi pole see tagatud, kuna mõned serverid võivad blokeeringuid käsitleda omal moel. Avalikud postitused võivad tuvastamata kasutajatele endiselt näha olla.", "block_modal.show_less": "Kuva vähem", "block_modal.show_more": "Kuva rohkem", + "block_modal.they_cant_mention": "Ta ei saa mainida sind ega jälgida.", + "block_modal.they_cant_see_posts": "Ta ei näe sinu postitusi ja sa ei näe tema omi.", + "block_modal.they_will_know": "Ta näeb, et ta on blokeeritud.", "block_modal.title": "Blokeeri kasutaja?", + "block_modal.you_wont_see_mentions": "Sa ei näe postitusi, mis mainivad teda.", "boost_modal.combo": "Vajutades {combo}, saab selle edaspidi vahele jätta", "bundle_column_error.copy_stacktrace": "Kopeeri veateade", "bundle_column_error.error.body": "Soovitud lehte ei õnnestunud esitada. See võib olla meie koodiviga või probleem brauseri ühilduvusega.", @@ -206,8 +210,26 @@ "dismissable_banner.explore_tags": "Need sildid siit ja teistes serveritest detsentraliseeritud võrgus koguvad tähelepanu just praegu selles serveris.", "dismissable_banner.public_timeline": "Need on kõige uuemad avalikud postitused inimestelt sotsiaalvõrgustikus, mida {domain} inimesed jälgivad.", "domain_block_modal.block": "Blokeeri server", + "domain_block_modal.block_account_instead": "Selle asemel blokeeri @{name}", + "domain_block_modal.they_can_interact_with_old_posts": "Inimesed sellest serverist saavad interakteeruda sinu vanade postitustega.", + "domain_block_modal.they_cant_follow": "Sellest serverist ei saa keegi sind jälgida.", + "domain_block_modal.they_wont_know": "Nad ei tea, et nad on blokeeritud.", + "domain_block_modal.title": "Blokeerida domeen?", + "domain_block_modal.you_will_lose_followers": "Kõik sinu sellest serverist pärit jälgijad eemaldatakse.", + "domain_block_modal.you_wont_see_posts": "Sa ei näe selle serveri kasutajate postitusi ega teavitusi.", + "domain_pill.activitypub_lets_connect": "See võimaldab sul ühenduda inimestega ja nendega suhelda mitte ainult Mastodonis, vaid ka teistes suhtlusrakendustes.", + "domain_pill.activitypub_like_language": "ActivityPub on nagu keel, mida Mastodon räägib teiste suhtlusvõrgustikega.", "domain_pill.server": "Server", + "domain_pill.their_handle": "Tema tunnus:", + "domain_pill.their_server": "Tema digitaalne kodu, kus kõik tema postitused on.", + "domain_pill.their_username": "Tema unikaalne tunnus tema serveris. On võimalik, et mingites teistes serverites on sama kasutajanimega kasutajaid.", "domain_pill.username": "Kasutajanimi", + "domain_pill.whats_in_a_handle": "Mis on tunnuses?", + "domain_pill.who_they_are": "Kuna tunnus ütleb, kes keegi on ja kus, saad suhelda inimestega üle .", + "domain_pill.who_you_are": "Kuna tunnus ütleb, kes sa oled ja kus, saavad inimesed sinuga suhelda üle .", + "domain_pill.your_handle": "Sinu tunnus:", + "domain_pill.your_server": "Sinu digitaalne kodu, kus on kõik sinu postitused. Sulle ei meeldi see? Vaheta mistahes ajal serverit ja võta jälgijad ka.", + "domain_pill.your_username": "Sinu unikaalne identifikaator siin serveris. On võimalik, et leiad teistes serverites samasuguse kasutajanimega kasutajaid.", "embed.instructions": "Lisa see postitus oma veebilehele, kopeerides alloleva koodi.", "embed.preview": "Nii näeb see välja:", "emoji_button.activity": "Tegevus", @@ -244,6 +266,7 @@ "empty_column.list": "Siin loetelus pole veel midagi. Kui loetelu liikmed teevad uusi postitusi, näed neid siin.", "empty_column.lists": "Pole veel ühtegi nimekirja. Kui lood mõne, näed neid siin.", "empty_column.mutes": "Sa pole veel ühtegi kasutajat vaigistanud.", + "empty_column.notification_requests": "Kõik tühi! Siin pole mitte midagi. Kui saad uusi teavitusi, ilmuvad need siin vastavalt sinu seadistustele.", "empty_column.notifications": "Ei ole veel teateid. Kui keegi suhtleb sinuga, näed seda siin.", "empty_column.public": "Siin pole midagi! Kirjuta midagi avalikku või jälgi ise kasutajaid täitmaks seda ruumi", "error.unexpected_crash.explanation": "Meie poolse probleemi või veebilehitseja ühilduvusprobleemi tõttu ei suutnud me seda lehekülge korrektselt näidata.", @@ -275,6 +298,7 @@ "filter_modal.select_filter.title": "Filtreeri seda postitust", "filter_modal.title.status": "Postituse filtreerimine", "filtered_notifications_banner.pending_requests": "Teateid {count, plural, =0 {mitte üheltki} one {ühelt} other {#}} inimeselt, keda võid teada", + "filtered_notifications_banner.title": "Filtreeritud teavitused", "firehose.all": "Kõik", "firehose.local": "See server", "firehose.remote": "Teised serverid", @@ -403,8 +427,15 @@ "loading_indicator.label": "Laadimine…", "media_gallery.toggle_visible": "{number, plural, one {Varja pilt} other {Varja pildid}}", "moved_to_account_banner.text": "Kontot {disabledAccount} ei ole praegu võimalik kasutada, sest kolisid kontole {movedToAccount}.", + "mute_modal.hide_from_notifications": "Peida teavituste hulgast", "mute_modal.hide_options": "Peida valikud", + "mute_modal.indefinite": "Kuni eemaldan neilt vaigistuse", "mute_modal.show_options": "Kuva valikud", + "mute_modal.they_can_mention_and_follow": "Ta saab sind mainida ja sind jälgida, kuid sa ei näe teda.", + "mute_modal.they_wont_know": "Ta ei tea, et ta on vaigistatud.", + "mute_modal.title": "Vaigistada kasutaja?", + "mute_modal.you_wont_see_mentions": "Sa ei näe postitusi, mis teda mainivad.", + "mute_modal.you_wont_see_posts": "Ta näeb jätkuvalt sinu postitusi, kuid sa ei näe tema omi.", "navigation_bar.about": "Teave", "navigation_bar.advanced_interface": "Ava kohandatud veebiliides", "navigation_bar.blocks": "Blokeeritud kasutajad", @@ -440,16 +471,25 @@ "notification.own_poll": "Su küsitlus on lõppenud", "notification.poll": "Küsitlus, milles osalesid, on lõppenud", "notification.reblog": "{name} jagas edasi postitust", + "notification.relationships_severance_event": "Kadunud ühendus kasutajaga {name}", + "notification.relationships_severance_event.account_suspension": "{from} admin on kustutanud {target}, mis tähendab, et sa ei saa enam neilt uuendusi või suhelda nendega.", + "notification.relationships_severance_event.domain_block": "{from} admin on blokeerinud {target}, sealhulgas {followersCount} sinu jälgijat ja {followingCount, plural, one {# konto} other {# kontot}}, mida jälgid.", + "notification.relationships_severance_event.learn_more": "Saa rohkem teada", + "notification.relationships_severance_event.user_domain_block": "Blokeerisid {target}, eemaldades oma jälgijate hulgast {followersCount} ja jälgitavate hulgast {followingCount, plural, one {# konto} other {# kontot}}.", "notification.status": "{name} just postitas", "notification.update": "{name} muutis postitust", "notification_requests.accept": "Nõus", "notification_requests.dismiss": "Hülga", + "notification_requests.notifications_from": "Teavitus kasutajalt {name}", + "notification_requests.title": "Filtreeritud teavitused", "notifications.clear": "Puhasta teated", "notifications.clear_confirmation": "Oled kindel, et soovid püsivalt kõik oma teated eemaldada?", "notifications.column_settings.admin.report": "Uued teavitused:", "notifications.column_settings.admin.sign_up": "Uued kasutajad:", "notifications.column_settings.alert": "Töölauateated", "notifications.column_settings.favourite": "Lemmikud:", + "notifications.column_settings.filter_bar.advanced": "Näita kõiki kategooriaid", + "notifications.column_settings.filter_bar.category": "Kiirfiltri riba", "notifications.column_settings.follow": "Uued jälgijad:", "notifications.column_settings.follow_request": "Uued jälgimistaotlused:", "notifications.column_settings.mention": "Mainimised:", @@ -475,7 +515,15 @@ "notifications.permission_denied": "Töölauamärguanded pole saadaval, kuna eelnevalt keelduti lehitsejale teavituste luba andmast", "notifications.permission_denied_alert": "Töölaua märguandeid ei saa lubada, kuna brauseri luba on varem keeldutud", "notifications.permission_required": "Töölaua märguanded ei ole saadaval, kuna vajalik luba pole antud.", + "notifications.policy.filter_new_accounts.hint": "Loodud viimase {days, plural, one {ühe päeva} other {# päeva}} jooksul", "notifications.policy.filter_new_accounts_title": "Uued kontod", + "notifications.policy.filter_not_followers_hint": "Kaasates kasutajad, kes on sind jälginud vähem kui {days, plural, one {ühe päeva} other {# päeva}}", + "notifications.policy.filter_not_followers_title": "Sind mittejälgivad kasutajad", + "notifications.policy.filter_not_following_hint": "Kuni sa nad käsitsi kinnitad", + "notifications.policy.filter_not_following_title": "Inimesed, keda sa ei jälgi", + "notifications.policy.filter_private_mentions_hint": "Filtreeritud, kui see pole vastus sinupoolt mainimisele või kui jälgid saatjat", + "notifications.policy.filter_private_mentions_title": "Soovimatud privaatsed mainimised", + "notifications.policy.title": "Filtreeri välja teavitused kohast…", "notifications_permission_banner.enable": "Luba töölaua märguanded", "notifications_permission_banner.how_to_control": "Et saada teateid, ajal mil Mastodon pole avatud, luba töölauamärguanded. Saad täpselt määrata, mis tüüpi tegevused tekitavad märguandeid, kasutates peale teadaannete sisse lülitamist üleval olevat nuppu {icon}.", "notifications_permission_banner.title": "Ära jää millestki ilma", @@ -652,9 +700,11 @@ "status.direct": "Maini privaatselt @{name}", "status.direct_indicator": "Privaatne mainimine", "status.edit": "Muuda", + "status.edited": "Viimati muudetud {date}", "status.edited_x_times": "Muudetud {count, plural, one{{count} kord} other {{count} korda}}", "status.embed": "Manustamine", "status.favourite": "Lemmik", + "status.favourites": "{count, plural, one {lemmik} other {lemmikud}}", "status.filter": "Filtreeri seda postitust", "status.filtered": "Filtreeritud", "status.hide": "Peida postitus", @@ -675,6 +725,7 @@ "status.reblog": "Jaga", "status.reblog_private": "Jaga algse nähtavusega", "status.reblogged_by": "{name} jagas", + "status.reblogs": "{count, plural, one {jagamine} other {jagamist}}", "status.reblogs.empty": "Keegi pole seda postitust veel jaganud. Kui keegi seda teeb, näeb seda siin.", "status.redraft": "Kustuta & alga uuesti", "status.remove_bookmark": "Eemalda järjehoidja", diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json index bd0081d71..9fae07487 100644 --- a/app/javascript/mastodon/locales/eu.json +++ b/app/javascript/mastodon/locales/eu.json @@ -148,7 +148,7 @@ "compose.published.open": "Ireki", "compose.saved.body": "Argitalpena gorde da.", "compose_form.direct_message_warning_learn_more": "Ikasi gehiago", - "compose_form.encryption_warning": "Mastodoneko bidalketak ez daude muturretik muturrera enkriptatuta. Ez partekatu informazio sentikorrik Mastodonen.", + "compose_form.encryption_warning": "Mastodon-go bidalketak ez daude muturretik muturrera enkriptatuta. Ez partekatu informazio sentikorrik Mastodonen.", "compose_form.hashtag_warning": "Tut hau ez da inolako traolatan zerrendatuko, ez baita publikoa. Tut publikoak soilik traolen bitartez bila daitezke.", "compose_form.lock_disclaimer": "Zure kontua ez dago {locked}. Edonork jarraitu zaitzake zure jarraitzaileentzako soilik diren bidalketak ikusteko.", "compose_form.lock_disclaimer.lock": "giltzapetuta", @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Hautatu lehendik dagoen kategoria bat edo sortu berria", "filter_modal.select_filter.title": "Iragazi bidalketa hau", "filter_modal.title.status": "Iragazi bidalketa bat", + "filtered_notifications_banner.mentions": "{count, plural, one {aipamen} other {aipamen}}", "filtered_notifications_banner.pending_requests": "Ezagutu {count, plural, =0 {dezakezun inoren} one {dezakezun pertsona baten} other {ditzakezun # pertsonen}} jakinarazpenak", "filtered_notifications_banner.title": "Iragazitako jakinarazpenak", "firehose.all": "Guztiak", @@ -307,6 +308,8 @@ "follow_requests.unlocked_explanation": "Zure kontua blokeatuta ez badago ere, {domain} domeinuko arduradunek uste dute kontu hauetako jarraipen eskaerak agian eskuz begiratu nahiko dituzula.", "follow_suggestions.curated_suggestion": "Domeinuaren iradokizuna", "follow_suggestions.dismiss": "Ez erakutsi berriro", + "follow_suggestions.featured_longer": "{domain} domeinuko taldeak hautaturikoak", + "follow_suggestions.friends_of_friends_longer": "Jarraitzen duzun jendearen artean ezagunak direnak", "follow_suggestions.hints.featured": "Profil hau {domain} domeinuko taldeak eskuz aukeratu du.", "follow_suggestions.hints.friends_of_friends": "Profil hau ezaguna da jarraitzen duzun jendearen artean.", "follow_suggestions.hints.most_followed": "Profil hau {domain} domeinuan gehien jarraitzen den profiletako bat da.", @@ -314,6 +317,8 @@ "follow_suggestions.hints.similar_to_recently_followed": "Profil hau duela gutxi jarraitu dituzun profil askoren antzekoa da.", "follow_suggestions.personalized_suggestion": "Iradokizun pertsonalizatua", "follow_suggestions.popular_suggestion": "Iradokizun ezaguna", + "follow_suggestions.popular_suggestion_longer": "{domain} domeinuan ezagunak direnak", + "follow_suggestions.similar_to_recently_followed_longer": "Berriki jarraitu dituzun profilen antzekoa", "follow_suggestions.view_all": "Ikusi denak", "follow_suggestions.who_to_follow": "Zein jarraitu", "followed_tags": "Jarraitutako traolak", @@ -345,7 +350,7 @@ "home.column_settings.show_reblogs": "Erakutsi bultzadak", "home.column_settings.show_replies": "Erakutsi erantzunak", "home.hide_announcements": "Ezkutatu iragarpenak", - "home.pending_critical_update.body": "Eguneratu zure Mastodoneko zerbitzaria leheinbailehen!", + "home.pending_critical_update.body": "Eguneratu zure Mastodon-go zerbitzaria leheinbailehen!", "home.pending_critical_update.link": "Ikusi eguneraketak", "home.pending_critical_update.title": "Segurtasun eguneraketa kritikoa eskuragarri!", "home.show_announcements": "Erakutsi iragarpenak", @@ -408,7 +413,7 @@ "lightbox.previous": "Aurrekoa", "limited_account_hint.action": "Erakutsi profila hala ere", "limited_account_hint.title": "Profil hau ezkutatu egin dute {domain} zerbitzariko moderatzaileek.", - "link_preview.author": "{name}(r)en eskutik", + "link_preview.author": "Egilea: {name}", "lists.account.add": "Gehitu zerrendara", "lists.account.remove": "Kendu zerrendatik", "lists.delete": "Ezabatu zerrenda", @@ -468,10 +473,21 @@ "notification.follow": "{name}(e)k jarraitzen dizu", "notification.follow_request": "{name}(e)k zu jarraitzeko eskaera egin du", "notification.mention": "{name}(e)k aipatu zaitu", + "notification.moderation-warning.learn_more": "Informazio gehiago", + "notification.moderation_warning": "Moderazio-abisu bat jaso duzu", + "notification.moderation_warning.action_delete_statuses": "Argitalpen batzuk kendu dira.", + "notification.moderation_warning.action_disable": "Zure kontua desaktibatua izan da.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Argitalpen batzuk hunkigarri gisa ezarri dira.", + "notification.moderation_warning.action_none": "Kontuak moderazio-abisu bat jaso du.", + "notification.moderation_warning.action_sensitive": "Argitalpenak hunkigarri gisa markatuko dira hemendik aurrera.", + "notification.moderation_warning.action_silence": "Kontua murriztu egin da.", + "notification.moderation_warning.action_suspend": "Kontua itxi da.", "notification.own_poll": "Zure inkesta amaitu da", "notification.poll": "Zuk erantzun duzun inkesta bat bukatu da", "notification.reblog": "{name}(e)k bultzada eman dio zure bidalketari", - "notification.severed_relationships": "{name} erabiltzailearekin zenuen erlazioa galdu da", + "notification.relationships_severance_event": "{name} erabiltzailearekin galdutako konexioak", + "notification.relationships_severance_event.account_suspension": "{from} zerbitzariko administratzaile batek {target} bertan behera utzi du, hau da, ezin izango dituzu jaso hango eguneratzerik edo hangoekin elkarreragin.", + "notification.relationships_severance_event.learn_more": "Informazio gehiago", "notification.status": "{name} erabiltzaileak bidalketa egin berri du", "notification.update": "{name} erabiltzaileak bidalketa bat editatu du", "notification_requests.accept": "Onartu", @@ -484,6 +500,8 @@ "notifications.column_settings.admin.sign_up": "Izen-emate berriak:", "notifications.column_settings.alert": "Mahaigaineko jakinarazpenak", "notifications.column_settings.favourite": "Gogokoak:", + "notifications.column_settings.filter_bar.advanced": "Bistaratu kategoria guztiak", + "notifications.column_settings.filter_bar.category": "Iragazki-barra bizkorra", "notifications.column_settings.follow": "Jarraitzaile berriak:", "notifications.column_settings.follow_request": "Jarraitzeko eskaera berriak:", "notifications.column_settings.mention": "Aipamenak:", @@ -544,7 +562,7 @@ "onboarding.share.message": "{username} naiz #Mastodon-en! Jarrai nazazu hemen: {url}", "onboarding.share.next_steps": "Hurrengo urrats posibleak:", "onboarding.share.title": "Partekatu zure profila", - "onboarding.start.lead": "Mastodonen parte zara orain, bakarra eta deszentralizatua den sare-sozialaren plataforma, non zuk, eta ez algoritmo batek, zeure esperientzia pertsonaliza dezakezun. Igaro ezazu muga soziala:", + "onboarding.start.lead": "Mastodon-en parte zara orain, bakarra eta deszentralizatua den sare sozialaren plataforma, non zuk, eta ez algoritmo batek, zeure esperientzia pertsonaliza dezakezun. Igaro ezazu muga soziala:", "onboarding.start.skip": "Urrats guztiak saltatu nahi dituzu?", "onboarding.start.title": "Lortu duzu!", "onboarding.steps.follow_people.body": "Zure jarioa zuk pertsonalizatzen duzu. Bete dezagun jende interesgarriaz.", @@ -558,7 +576,7 @@ "onboarding.tips.2fa": "Bazenekien? Zure kontua babes dezakezu, bi faktoreko autentifikazioa zure kontuko ezarpenetan ezarriaz. Edozein TOTP aplikaziorekin dabil, ez da telefono-zenbakirik behar!", "onboarding.tips.accounts_from_other_servers": "Badakizu? Mastodon deszentralizatua denez, beste zerbitzarietako profilak topatuko dituzu. Eta, hala ere, arazorik gabe jardun dezakezu haiekin! Haien zerbitzaria erabiltzaile-izenaren bigarren erdian dago!", "onboarding.tips.migration": "Bazenekien? Uste baduzu {domain} ez dela aukera on bat zuretzako etorkizunari begira, beste Mastodon zerbitzari batera alda zaitezke, zure jarraitzaileak galdu gabe. Zure zerbitzaria propioa ere ostata dezakezu!", - "onboarding.tips.verification": "Bazenekien? Zure kontua egiazta dezakezu zure webgunean zure Mastodoneko profilaren esteka jarriz, eta profilean webgunea gehituz. Ordainketa edo dokumenturik gabe!", + "onboarding.tips.verification": "Bazenekien? Zure kontua egiazta dezakezu zure webgunean zure Mastodon-go profilaren esteka jarriz, eta profilean webgunea gehituz. Ordainketa edo dokumenturik gabe!", "password_confirmation.exceeds_maxlength": "Pasahitzaren berrespenak pasahitzaren gehienezko luzera gainditzen du", "password_confirmation.mismatching": "Pasahitzaren berrespena ez dator bat", "picture_in_picture.restore": "Leheneratu", @@ -588,12 +606,6 @@ "refresh": "Berritu", "regeneration_indicator.label": "Kargatzen…", "regeneration_indicator.sublabel": "Zure hasiera-jarioa prestatzen ari da!", - "relationship_severance_notification.purged_data": "administratzaileek kendua", - "relationship_severance_notification.relationships": "{count, plural, one {Erlazio #} other {# erlazio}}", - "relationship_severance_notification.types.account_suspension": "Kontua bertan behera utzi da", - "relationship_severance_notification.types.domain_block": "Domeinua bertan behera utzi da", - "relationship_severance_notification.types.user_domain_block": "Domeinu hau blokeatu duzu", - "relationship_severance_notification.view": "Ikusi", "relative_time.days": "{number}e", "relative_time.full.days": "Duela {number, plural, one {egun #} other {# egun}}", "relative_time.full.hours": "Duela {number, plural, one {ordu #} other {# ordu}}", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index b784a1d5c..6d6b7d612 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -462,6 +462,8 @@ "notifications.permission_denied": "آگاهی‌های میزکار به دلیل رد کردن درخواست اجازهٔ پیشین مرورگر، در دسترس نیستند", "notifications.permission_denied_alert": "از آن‌جا که پیش از این اجازهٔ مرورگر رد شده است، آگاهی‌های میزکار نمی‌توانند به کار بیفتند", "notifications.permission_required": "آگاهی‌های میزکار در دسترس نیستند زیرا اجازه‌های لازم، اعطا نشده.", + "notifications.policy.filter_not_followers_title": "کسانی که شما را دنبال میکنند", + "notifications.policy.filter_not_following_hint": "", "notifications_permission_banner.enable": "به کار انداختن آگاهی‌های میزکار", "notifications_permission_banner.how_to_control": "برای دریافت آگاهی‌ها هنگام باز نبودن ماستودون، آگاهی‌های میزکار را به کار بیندازید. پس از به کار افتادنشان می‌توانید گونه‌های دقیق برهم‌کنش‌هایی که آگاهی‌های میزکار تولید می‌کنند را از {icon} بالا واپایید.", "notifications_permission_banner.title": "هرگز چیزی را از دست ندهید", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index 2cf85926f..5a5031fd1 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -297,7 +297,8 @@ "filter_modal.select_filter.subtitle": "Käytä olemassa olevaa luokkaa tai luo uusi", "filter_modal.select_filter.title": "Suodata tämä julkaisu", "filter_modal.title.status": "Suodata julkaisu", - "filtered_notifications_banner.pending_requests": "Ilmoitukset {count, plural, =0 {ei keltään} one {yhdeltä henkilöltä} other {# henkilöltä}}, jonka saatat tuntea", + "filtered_notifications_banner.mentions": "{count, plural, one {maininta} other {mainintaa}}", + "filtered_notifications_banner.pending_requests": "Sinulle on ilmoituksia mahdollisesti tuntemiltasi henkilöiltä seuraavasti: {count, plural, =0 {Ei keltään} one {Yhdeltä henkilöltä} other {# henkilöltä}}", "filtered_notifications_banner.title": "Suodatetut ilmoitukset", "firehose.all": "Kaikki", "firehose.local": "Tämä palvelin", @@ -305,15 +306,19 @@ "follow_request.authorize": "Valtuuta", "follow_request.reject": "Hylkää", "follow_requests.unlocked_explanation": "Vaikkei tiliäsi ole lukittu, palvelimen {domain} ylläpito on arvioinut, että saatat olla halukas tarkistamaan nämä seuraamispyynnöt erikseen.", - "follow_suggestions.curated_suggestion": "Ylläpidon valinta", + "follow_suggestions.curated_suggestion": "Ehdotus ylläpidolta", "follow_suggestions.dismiss": "Älä näytä uudelleen", + "follow_suggestions.featured_longer": "Käsin valinnut palvelimen {domain} tiimi", + "follow_suggestions.friends_of_friends_longer": "Suosittu seuraamiesi ihmisten keskuudessa", "follow_suggestions.hints.featured": "Tämän profiilin on valinnut palvelimen {domain} tiimi.", - "follow_suggestions.hints.friends_of_friends": "Tämä profiili on suosittu seuraamiesi henkilöiden parissa.", - "follow_suggestions.hints.most_followed": "Tämä profiili on yksi seuratuimmista palvelimella {domain}.", + "follow_suggestions.hints.friends_of_friends": "Seuraamasi käyttäjät suosivat tätä profiilia.", + "follow_suggestions.hints.most_followed": "Tämä profiili on palvelimen {domain} seuratuimpia.", "follow_suggestions.hints.most_interactions": "Tämä profiili on viime aikoina saanut paljon huomiota palvelimella {domain}.", "follow_suggestions.hints.similar_to_recently_followed": "Tämä profiili on samankaltainen kuin profiilit, joita olet viimeksi seurannut.", "follow_suggestions.personalized_suggestion": "Mukautettu ehdotus", "follow_suggestions.popular_suggestion": "Suosittu ehdotus", + "follow_suggestions.popular_suggestion_longer": "Suosittu palvelimella {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Samankaltainen kuin äskettäin seuraamasi profiilit", "follow_suggestions.view_all": "Näytä kaikki", "follow_suggestions.who_to_follow": "Ehdotuksia seurattavaksi", "followed_tags": "Seuratut aihetunnisteet", @@ -468,10 +473,23 @@ "notification.follow": "{name} seurasi sinua", "notification.follow_request": "{name} on pyytänyt lupaa saada seurata sinua", "notification.mention": "{name} mainitsi sinut", + "notification.moderation-warning.learn_more": "Lue lisää", + "notification.moderation_warning": "Olet saanut moderointivaroituksen", + "notification.moderation_warning.action_delete_statuses": "Jotkin julkaisusi on poistettu.", + "notification.moderation_warning.action_disable": "Tilisi on poistettu käytöstä.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Jotkin julkaisusi on merkitty arkaluonteisiksi.", + "notification.moderation_warning.action_none": "Tilisi on saanut moderointivaroituksen.", + "notification.moderation_warning.action_sensitive": "Tästä lähtien julkaisusi merkitään arkaluonteisiksi.", + "notification.moderation_warning.action_silence": "Tiliäsi on rajoitettu.", + "notification.moderation_warning.action_suspend": "Tilisi on jäädytetty.", "notification.own_poll": "Äänestyksesi on päättynyt", "notification.poll": "Kysely, johon osallistuit, on päättynyt", "notification.reblog": "{name} tehosti julkaisuasi", - "notification.severed_relationships": "Suhteet palvelimeen {name} katkenneet", + "notification.relationships_severance_event": "Menetettiin yhteydet palvelimeen {name}", + "notification.relationships_severance_event.account_suspension": "Palvelimen {from} ylläpitäjä on jäädyttänyt palvelimen {target} vuorovaikutuksen. Enää et voi siis vastaanottaa päivityksiä heiltä tai olla yhteyksissä heidän kanssaan.", + "notification.relationships_severance_event.domain_block": "Palvelimen {from} ylläpitäjä on estänyt palvelimen {target} vuorovaikutuksen – mukaan lukien {followersCount} seuraajistasi ja {followingCount, plural, one {# seuratuistasi} other {# seuratuistasi}}.", + "notification.relationships_severance_event.learn_more": "Lue lisää", + "notification.relationships_severance_event.user_domain_block": "Olet estänyt palvelimen {target}, mikä poisti {followersCount} seuraajistasi ja {followingCount, plural, one {# seuratuistasi} other {# seuratuistasi}}.", "notification.status": "{name} julkaisi juuri", "notification.update": "{name} muokkasi julkaisua", "notification_requests.accept": "Hyväksy", @@ -484,6 +502,8 @@ "notifications.column_settings.admin.sign_up": "Uudet rekisteröitymiset:", "notifications.column_settings.alert": "Työpöytäilmoitukset", "notifications.column_settings.favourite": "Suosikit:", + "notifications.column_settings.filter_bar.advanced": "Näytä kaikki luokat", + "notifications.column_settings.filter_bar.category": "Pikasuodatuspalkki", "notifications.column_settings.follow": "Uudet seuraajat:", "notifications.column_settings.follow_request": "Uudet seuraamispyynnöt:", "notifications.column_settings.mention": "Maininnat:", @@ -588,12 +608,6 @@ "refresh": "Päivitä", "regeneration_indicator.label": "Ladataan…", "regeneration_indicator.sublabel": "Kotisyötettäsi valmistellaan!", - "relationship_severance_notification.purged_data": "ylläpitäjien tyhjentämä", - "relationship_severance_notification.relationships": "{count, plural, one {# suhde} other {# suhdetta}}", - "relationship_severance_notification.types.account_suspension": "Tili on jäädytetty", - "relationship_severance_notification.types.domain_block": "Verkkotunnus on jäädytetty", - "relationship_severance_notification.types.user_domain_block": "Estit tämän verkkotunnuksen", - "relationship_severance_notification.view": "Näytä", "relative_time.days": "{number} pv", "relative_time.full.days": "{number, plural, one {# päivä} other {# päivää}} sitten", "relative_time.full.hours": "{number, plural, one {# tunti} other {# tuntia}} sitten", diff --git a/app/javascript/mastodon/locales/fil.json b/app/javascript/mastodon/locales/fil.json index afa0e5fbc..894d73c8c 100644 --- a/app/javascript/mastodon/locales/fil.json +++ b/app/javascript/mastodon/locales/fil.json @@ -50,6 +50,7 @@ "admin.dashboard.retention.cohort_size": "Mga bagong tagagamit", "alert.rate_limited.message": "Mangyaring subukan muli pagkatapos ng {retry_time, time, medium}.", "audio.hide": "Itago ang tunog", + "block_modal.title": "Harangan ang tagagamit?", "bundle_column_error.error.title": "Naku!", "bundle_column_error.network.body": "Nagkaroon ng kamalian habang sinusubukang i-karga ang pahinang ito. Maaaring dahil ito sa pansamantalang problema ng iyong koneksyon sa internet o ang server na ito.", "bundle_column_error.network.title": "Kamaliang network", @@ -104,6 +105,7 @@ "compose_form.poll.multiple": "Maraming pagpipilian", "compose_form.poll.single": "Piliin ang isa", "compose_form.reply": "Tumugon", + "compose_form.spoiler.marked": "Tanggalin ang babala sa nilalaman", "compose_form.spoiler.unmarked": "Idagdag ang babala sa nilalaman", "confirmation_modal.cancel": "Pagpaliban", "confirmations.block.confirm": "Harangan", @@ -115,6 +117,7 @@ "confirmations.discard_edit_media.confirm": "Ipagpaliban", "confirmations.edit.confirm": "Baguhin", "confirmations.reply.confirm": "Tumugon", + "conversation.mark_as_read": "Markahan bilang nabasa na", "copy_icon_button.copied": "Sinipi sa clipboard", "copypaste.copied": "Sinipi", "copypaste.copy_to_clipboard": "I-sipi sa clipboard", @@ -130,6 +133,10 @@ "dismissable_banner.explore_statuses": "Ito ang mga sumisikat na mga post sa iba't ibang bahagi ng social web ngayon. Ang mga mas bagong post na mas marami ang mga pagpapalakas at paborito ay tinataasan ng antas.", "dismissable_banner.explore_tags": "Ito ang mga sumisikat na mga hashtag sa iba't ibang bahagi ng social web ngayon. Ang mga hashtag ginagamit ng mas maraming mga iba't ibang tao ay tinataasan ng antas.", "dismissable_banner.public_timeline": "Ito ang mga pinakamakailang nakapublikong post mula sa mga taong nasa social web na sinusundan ng mga tao sa {domain}.", + "domain_block_modal.block": "Harangan ang serbiro", + "domain_block_modal.title": "Harangan ang domain?", + "domain_block_modal.you_will_lose_followers": "Mabubura ang iyong mga tagasunod mula sa serbirong ito.", + "domain_pill.server": "Serbiro", "embed.instructions": "I-embed ang post na ito sa iyong pook-sapot sa pamamagitan ng pagsipi ng kodigo sa ilalim.", "embed.preview": "Ito ang magiging itsura:", "emoji_button.activity": "Aktibidad", @@ -166,6 +173,8 @@ "empty_column.list": "Wala pang laman ang listahang ito. Kapag naglathala ng mga bagong post ang mga miyembro ng listahang ito, makikita iyon dito.", "empty_column.lists": "Wala ka pang mga listahan. Kapag gumawa ka ng isa, makikita yun dito.", "explore.search_results": "Mga resulta ng paghahanap", + "explore.title": "Tuklasin", + "explore.trending_links": "Mga balita", "filter_modal.select_filter.search": "Hanapin o gumawa", "firehose.all": "Lahat", "firehose.local": "Itong serbiro", @@ -180,6 +189,7 @@ "generic.saved": "Nakaimbak", "hashtag.column_header.tag_mode.all": "at {additional}", "hashtag.column_header.tag_mode.any": "o {additional}", + "home.column_settings.show_replies": "Ipakita ang mga tugon", "home.pending_critical_update.body": "Mangyaring i-update ang iyong serbiro ng Mastodon sa lalong madaling panahon!", "interaction_modal.login.action": "Iuwi mo ako", "interaction_modal.no_account_yet": "Wala sa Mastodon?", @@ -216,14 +226,21 @@ "notification.follow": "Sinundan ka ni {name}", "notification.follow_request": "Hinihiling ni {name} na sundan ka", "notification.mention": "Binanggit ka ni {name}", + "notification.relationships_severance_event.learn_more": "Matuto nang higit pa", + "notification_requests.accept": "Tanggapin", + "notification_requests.notifications_from": "Mga abiso mula kay/sa {name}", "notifications.clear": "Burahin mga abiso", "notifications.column_settings.admin.report": "Mga bagong ulat:", + "notifications.column_settings.alert": "Mga abiso sa Desktop", "notifications.column_settings.favourite": "Mga paborito:", "notifications.column_settings.follow": "Mga bagong tagasunod:", "notifications.column_settings.unread_notifications.category": "Hindi Nabasang mga Abiso", "notifications.column_settings.update": "Mga pagbago:", "notifications.filter.all": "Lahat", + "notifications.filter.favourites": "Mga paborito", "notifications.mark_as_read": "Markahan lahat ng abiso bilang nabasa na", + "notifications.policy.filter_not_followers_title": "Mga taong hindi ka susundan", + "notifications.policy.filter_not_following_title": "Mga taong hindi mo sinusundan", "onboarding.action.back": "Ibalik mo ako", "onboarding.actions.back": "Ibalik mo ako", "onboarding.profile.note_hint": "Maaari mong @bangitin ang ibang mga tao o mga #hashtag…", @@ -236,6 +253,8 @@ "privacy.direct.long": "Lahat ng mga binanggit sa post", "privacy.private.long": "Mga tagasunod mo lamang", "privacy.private.short": "Mga tagasunod", + "privacy.public.long": "Sinumang nasa loob at labas ng Mastodon", + "regeneration_indicator.label": "Kumakarga…", "relative_time.days": "{number}a", "relative_time.full.days": "{number, plural, one {# araw} other {# na araw}} ang nakalipas", "relative_time.full.hours": "{number, plural, one {# oras} other {# na oras}} ang nakalipas", @@ -261,6 +280,10 @@ "report.thanks.title": "Ayaw mo bang makita ito?", "report.thanks.title_actionable": "Salamat sa pag-uulat, titingnan namin ito.", "report_notification.categories.other": "Iba pa", + "search.quick_action.open_url": "Buksan ang URL sa Mastodon", + "search.search_or_paste": "Maghanap o ilagay ang URL", + "search_popout.full_text_search_disabled_message": "Hindi magagamit sa {domain}.", + "search_popout.full_text_search_logged_out_message": "Magagamit lamang kapag naka-log in.", "search_results.all": "Lahat", "search_results.see_all": "Ipakita lahat", "server_banner.learn_more": "Matuto nang higit pa", diff --git a/app/javascript/mastodon/locales/fo.json b/app/javascript/mastodon/locales/fo.json index 3ea13cc7f..77257413f 100644 --- a/app/javascript/mastodon/locales/fo.json +++ b/app/javascript/mastodon/locales/fo.json @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Brúka ein verandi bólk ella skapa ein nýggjan", "filter_modal.select_filter.title": "Filtrera hendan postin", "filter_modal.title.status": "Filtrera ein post", + "filtered_notifications_banner.mentions": "{count, plural, one {umrøða} other {umrøður}}", "filtered_notifications_banner.pending_requests": "Fráboðanir frá {count, plural, =0 {ongum} one {einum persóni} other {# persónum}}, sum tú kanska kennir", "filtered_notifications_banner.title": "Sáldaðar fráboðanir", "firehose.all": "Allar", @@ -307,6 +308,8 @@ "follow_requests.unlocked_explanation": "Sjálvt um konta tín ikki er læst, so hugsa {domain} starvsfólkini, at tú kanska hevur hug at kanna umbønir um at fylgja frá hesum kontum við hond.", "follow_suggestions.curated_suggestion": "Val hjá ábyrgdarfólki", "follow_suggestions.dismiss": "Lat vera við at vísa", + "follow_suggestions.featured_longer": "Vald burturúr av {domain} toyminum", + "follow_suggestions.friends_of_friends_longer": "Vælumtókt millum fólk, sum tú fylgir", "follow_suggestions.hints.featured": "Hesin vangin er úrvaldur av toyminum handan {domain}.", "follow_suggestions.hints.friends_of_friends": "Hesin vangin er vælumtóktur millum tey, tú fylgir.", "follow_suggestions.hints.most_followed": "Hesin vangin er ein av teimum, sum er mest fylgdur á {domain}.", @@ -314,6 +317,8 @@ "follow_suggestions.hints.similar_to_recently_followed": "Hesin vangin líkist teimum, sum tú nýliga hevur fylgt.", "follow_suggestions.personalized_suggestion": "Persónligt uppskot", "follow_suggestions.popular_suggestion": "Vælumtókt uppskot", + "follow_suggestions.popular_suggestion_longer": "Vælumtókt á {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Líkist vangum, sum tú nýliga hevur fylgt", "follow_suggestions.view_all": "Vís øll", "follow_suggestions.who_to_follow": "Hvørji tú átti at fylgt", "followed_tags": "Fylgd frámerki", @@ -468,10 +473,23 @@ "notification.follow": "{name} fylgdi tær", "notification.follow_request": "{name} biður um at fylgja tær", "notification.mention": "{name} nevndi teg", + "notification.moderation-warning.learn_more": "Lær meira", + "notification.moderation_warning": "Tú hevur móttikið eina umsjónarávarðing", + "notification.moderation_warning.action_delete_statuses": "Onkrir av tínum postum eru strikaðir.", + "notification.moderation_warning.action_disable": "Konta tín er gjørd óvirkin.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Nakrir av postum tínum eru merktir sum viðkvæmir.", + "notification.moderation_warning.action_none": "Konta tín hevur móttikið eina umsjónarávarðing.", + "notification.moderation_warning.action_sensitive": "Postar tínir verða merktir sum viðkvæmir frá nú av.", + "notification.moderation_warning.action_silence": "Konta tín er avmarkað.", + "notification.moderation_warning.action_suspend": "Konta tín er ógildað.", "notification.own_poll": "Tín atkvøðugreiðsla er endað", "notification.poll": "Ein atkvøðugreiðsla, har tú hevur atkvøtt, er endað", "notification.reblog": "{name} lyfti tín post", - "notification.severed_relationships": "Tilknýti við {name} avbrotið", + "notification.relationships_severance_event": "Mist sambond við {name}", + "notification.relationships_severance_event.account_suspension": "Ein umsitari frá {from} hevur gjørt {target} óvirkna, sum merkir, at tú ikki kanst móttaka dagføringar ella virka saman við teimum longur.", + "notification.relationships_severance_event.domain_block": "Ein umsitari frá {from} hevur blokerað {target}, íroknað {followersCount} av tínum fylgjarum og {followingCount, plural, one {# kontu} other {# kontur}}, sum tú fylgir.", + "notification.relationships_severance_event.learn_more": "Lær meira", + "notification.relationships_severance_event.user_domain_block": "Tú hevur blokerað {target}, strikað {followersCount} av tínum fylgjarum og {followingCount, plural, one {# kontu} other {# kontur}}, sum tú fylgir.", "notification.status": "{name} hevur júst postað", "notification.update": "{name} rættaði ein post", "notification_requests.accept": "Góðtak", @@ -484,6 +502,8 @@ "notifications.column_settings.admin.sign_up": "Nýggjar tilmeldingar:", "notifications.column_settings.alert": "Skriviborðsfráboðanir", "notifications.column_settings.favourite": "Dámdir postar:", + "notifications.column_settings.filter_bar.advanced": "Vís allar bólkar", + "notifications.column_settings.filter_bar.category": "Skjótfilturbjálki", "notifications.column_settings.follow": "Nýggir fylgjarar:", "notifications.column_settings.follow_request": "Nýggjar umbønir um at fylgja:", "notifications.column_settings.mention": "Umrøður:", @@ -588,12 +608,6 @@ "refresh": "Endurles", "regeneration_indicator.label": "Innlesur…", "regeneration_indicator.sublabel": "Tín heimarás verður gjørd klár!", - "relationship_severance_notification.purged_data": "reinsað av umsitarum", - "relationship_severance_notification.relationships": "{count, plural, one {# tilknýti} other {# tilknýti}}", - "relationship_severance_notification.types.account_suspension": "Kontan er ógildað", - "relationship_severance_notification.types.domain_block": "Økisnavn er ógildað", - "relationship_severance_notification.types.user_domain_block": "Tú hevur forðað hesum økisnavni", - "relationship_severance_notification.view": "Vís", "relative_time.days": "{number}d", "relative_time.full.days": "{number, plural, one {# dagur} other {# dagar}} síðani", "relative_time.full.hours": "{number, plural, one {# tími} other {# tímar}} síðani", diff --git a/app/javascript/mastodon/locales/fr-CA.json b/app/javascript/mastodon/locales/fr-CA.json index 1e1c78f29..9e2985290 100644 --- a/app/javascript/mastodon/locales/fr-CA.json +++ b/app/javascript/mastodon/locales/fr-CA.json @@ -222,14 +222,14 @@ "domain_pill.server": "Serveur", "domain_pill.their_handle": "Son identifiant :", "domain_pill.their_server": "Son foyer numérique, là où tous ses posts résident.", - "domain_pill.their_username": "Son identifiant unique sur leur serveur. Il est possible de rencontrer des utilisateurs avec le même nom sur différents serveurs.", + "domain_pill.their_username": "Son identifiant unique sur leur serveur. Il est possible de rencontrer des utilisateur·rice·s avec le même nom sur différents serveurs.", "domain_pill.username": "Nom d’utilisateur", "domain_pill.whats_in_a_handle": "Qu'est-ce qu'un identifiant ?", "domain_pill.who_they_are": "Comme un identifiant contient le nom et le service hébergeant une personne, vous pouvez interagir sur .", "domain_pill.who_you_are": "Comme un identifiant indique votre nom et le service vous hébergeant, vous pouvez interagir avec .", "domain_pill.your_handle": "Votre identifiant :", "domain_pill.your_server": "Votre foyer numérique, là où vos messages résident. Vous souhaitez changer ? Lancez un transfert vers un autre serveur quand vous le voulez et vos abonné·e·s suivront automatiquement.", - "domain_pill.your_username": "Votre identifiant unique sur ce serveur. Il est possible de trouver des utilisateurs ayant le même nom d'utilisateur sur différents serveurs.", + "domain_pill.your_username": "Votre identifiant unique sur ce serveur. Il est possible de rencontrer des utilisateur·rice·s ayant le même nom d'utilisateur sur différents serveurs.", "embed.instructions": "Intégrez cette publication à votre site en copiant le code ci-dessous.", "embed.preview": "Voici comment il apparaîtra:", "emoji_button.activity": "Activité", @@ -471,7 +471,11 @@ "notification.own_poll": "Votre sondage est terminé", "notification.poll": "Un sondage auquel vous avez participé est terminé", "notification.reblog": "{name} a boosté votre message", - "notification.severed_relationships": "Relation avec {name} rompues", + "notification.relationships_severance_event": "Connexions perdues avec {name}", + "notification.relationships_severance_event.account_suspension": "Un·e administrateur·rice de {from} a suspendu {target}, ce qui signifie que vous ne pourrez plus recevoir de mises à jour ou interagir avec lui.", + "notification.relationships_severance_event.domain_block": "Un·e administrateur·rice de {from} en a bloqué {target}, comprenant {followersCount} de vos abonné·e·s et {followingCount, plural, one {# compte} other {# comptes}} vous suivez.", + "notification.relationships_severance_event.learn_more": "En savoir plus", + "notification.relationships_severance_event.user_domain_block": "Vous avez bloqué {target}, en supprimant {followersCount} de vos abonnés et {followingCount, plural, one {# compte} other {# comptes}} que vous suivez.", "notification.status": "{name} vient de publier", "notification.update": "{name} a modifié une publication", "notification_requests.accept": "Accepter", @@ -484,6 +488,8 @@ "notifications.column_settings.admin.sign_up": "Nouvelles inscriptions:", "notifications.column_settings.alert": "Notifications navigateur", "notifications.column_settings.favourite": "Favoris:", + "notifications.column_settings.filter_bar.advanced": "Afficher toutes les catégories", + "notifications.column_settings.filter_bar.category": "Barre de filtre rapide", "notifications.column_settings.follow": "Nouveaux⋅elles abonné⋅e⋅s:", "notifications.column_settings.follow_request": "Nouvelles demandes d’abonnement:", "notifications.column_settings.mention": "Mentions:", @@ -588,12 +594,6 @@ "refresh": "Actualiser", "regeneration_indicator.label": "Chargement…", "regeneration_indicator.sublabel": "Votre fil d'accueil est en cours de préparation!", - "relationship_severance_notification.purged_data": "supprimées par les administrateurs", - "relationship_severance_notification.relationships": "{count, plural, one {# relation} other {# relations}}", - "relationship_severance_notification.types.account_suspension": "Le compte a été suspendu", - "relationship_severance_notification.types.domain_block": "Le domaine a été suspendu", - "relationship_severance_notification.types.user_domain_block": "Vous avez bloqué ce domaine", - "relationship_severance_notification.view": "Afficher", "relative_time.days": "{number} j", "relative_time.full.days": "il y a {number, plural, one {# jour} other {# jours}}", "relative_time.full.hours": "il y a {number, plural, one {# heure} other {# heures}}", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index af5ed66bd..1a5803623 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -222,14 +222,14 @@ "domain_pill.server": "Serveur", "domain_pill.their_handle": "Son identifiant :", "domain_pill.their_server": "Son foyer numérique, là où tous ses posts résident.", - "domain_pill.their_username": "Son identifiant unique sur leur serveur. Il est possible de rencontrer des utilisateurs avec le même nom sur différents serveurs.", + "domain_pill.their_username": "Son identifiant unique sur leur serveur. Il est possible de rencontrer des utilisateur·rice·s avec le même nom sur différents serveurs.", "domain_pill.username": "Nom d’utilisateur", "domain_pill.whats_in_a_handle": "Qu'est-ce qu'un identifiant ?", "domain_pill.who_they_are": "Comme un identifiant contient le nom et le service hébergeant une personne, vous pouvez interagir sur .", "domain_pill.who_you_are": "Comme un identifiant indique votre nom et le service vous hébergeant, vous pouvez interagir avec .", "domain_pill.your_handle": "Votre identifiant :", "domain_pill.your_server": "Votre foyer numérique, là où vos messages résident. Vous souhaitez changer ? Lancez un transfert vers un autre serveur quand vous le voulez et vos abonné·e·s suivront automatiquement.", - "domain_pill.your_username": "Votre identifiant unique sur ce serveur. Il est possible de trouver des utilisateurs ayant le même nom d'utilisateur sur différents serveurs.", + "domain_pill.your_username": "Votre identifiant unique sur ce serveur. Il est possible de rencontrer des utilisateur·rice·s ayant le même nom d'utilisateur sur différents serveurs.", "embed.instructions": "Intégrez ce message à votre site en copiant le code ci-dessous.", "embed.preview": "Il apparaîtra comme cela :", "emoji_button.activity": "Activités", @@ -471,7 +471,11 @@ "notification.own_poll": "Votre sondage est terminé", "notification.poll": "Un sondage auquel vous avez participé vient de se terminer", "notification.reblog": "{name} a partagé votre message", - "notification.severed_relationships": "Relation avec {name} rompues", + "notification.relationships_severance_event": "Connexions perdues avec {name}", + "notification.relationships_severance_event.account_suspension": "Un·e administrateur·rice de {from} a suspendu {target}, ce qui signifie que vous ne pourrez plus recevoir de mises à jour ou interagir avec lui.", + "notification.relationships_severance_event.domain_block": "Un·e administrateur·rice de {from} en a bloqué {target}, comprenant {followersCount} de vos abonné·e·s et {followingCount, plural, one {# compte} other {# comptes}} vous suivez.", + "notification.relationships_severance_event.learn_more": "En savoir plus", + "notification.relationships_severance_event.user_domain_block": "Vous avez bloqué {target}, en supprimant {followersCount} de vos abonnés et {followingCount, plural, one {# compte} other {# comptes}} que vous suivez.", "notification.status": "{name} vient de publier", "notification.update": "{name} a modifié un message", "notification_requests.accept": "Accepter", @@ -484,6 +488,8 @@ "notifications.column_settings.admin.sign_up": "Nouvelles inscriptions :", "notifications.column_settings.alert": "Notifications du navigateur", "notifications.column_settings.favourite": "Favoris :", + "notifications.column_settings.filter_bar.advanced": "Afficher toutes les catégories", + "notifications.column_settings.filter_bar.category": "Barre de filtre rapide", "notifications.column_settings.follow": "Nouveaux·elles abonné·e·s :", "notifications.column_settings.follow_request": "Nouvelles demandes d’abonnement :", "notifications.column_settings.mention": "Mentions :", @@ -527,7 +533,7 @@ "onboarding.actions.go_to_home": "Allers vers mon flux principal", "onboarding.compose.template": "Bonjour #Mastodon !", "onboarding.follows.empty": "Malheureusement, aucun résultat ne peut être affiché pour le moment. Vous pouvez essayer d'utiliser la recherche ou parcourir la page de découverte pour trouver des personnes à suivre, ou réessayez plus tard.", - "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", + "onboarding.follows.lead": "Votre flux principal est le principal moyen de découvrir Mastodon. Plus vous suivez de personnes, plus il sera actif et intéressant. Pour commencer, voici quelques suggestions :", "onboarding.follows.title": "Personnaliser votre flux principal", "onboarding.profile.discoverable": "Rendre mon profil découvrable", "onboarding.profile.discoverable_hint": "Lorsque vous acceptez d'être découvert sur Mastodon, vos messages peuvent apparaître dans les résultats de recherche et les tendances, et votre profil peut être suggéré à des personnes ayant des intérêts similaires aux vôtres.", @@ -544,10 +550,10 @@ "onboarding.share.message": "Je suis {username} sur #Mastodon ! Suivez-moi sur {url}", "onboarding.share.next_steps": "Étapes suivantes possibles :", "onboarding.share.title": "Partager votre profil", - "onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:", + "onboarding.start.lead": "Vous faites désormais partie de Mastodon, une plateforme de médias sociaux unique et décentralisée où c'est vous, et non un algorithme, qui créez votre propre expérience. Nous allons vous aider à vous lancer dans cette nouvelle frontière sociale :", "onboarding.start.skip": "Vous n’avez donc pas besoin d’aide pour commencer ?", "onboarding.start.title": "Vous avez réussi !", - "onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.", + "onboarding.steps.follow_people.body": "Suivre des personnes intéressantes, c'est la raison d'être de Mastodon.", "onboarding.steps.follow_people.title": "Personnaliser votre flux principal", "onboarding.steps.publish_status.body": "Dites bonjour au monde avec du texte, des photos, des vidéos ou des sondages {emoji}", "onboarding.steps.publish_status.title": "Rédigez votre premier message", @@ -588,12 +594,6 @@ "refresh": "Actualiser", "regeneration_indicator.label": "Chargement…", "regeneration_indicator.sublabel": "Votre fil principal est en cours de préparation !", - "relationship_severance_notification.purged_data": "supprimées par les administrateurs", - "relationship_severance_notification.relationships": "{count, plural, one {# relation} other {# relations}}", - "relationship_severance_notification.types.account_suspension": "Le compte a été suspendu", - "relationship_severance_notification.types.domain_block": "Le domaine a été suspendu", - "relationship_severance_notification.types.user_domain_block": "Vous avez bloqué ce domaine", - "relationship_severance_notification.view": "Afficher", "relative_time.days": "{number} j", "relative_time.full.days": "il y a {number, plural, one {# jour} other {# jours}}", "relative_time.full.hours": "il y a {number, plural, one {# heure} other {# heures}}", diff --git a/app/javascript/mastodon/locales/fy.json b/app/javascript/mastodon/locales/fy.json index 97119e30c..a22f4767a 100644 --- a/app/javascript/mastodon/locales/fy.json +++ b/app/javascript/mastodon/locales/fy.json @@ -13,7 +13,7 @@ "about.rules": "Serverrigels", "account.account_note_header": "Opmerking", "account.add_or_remove_from_list": "Tafoegje oan of fuortsmite út listen", - "account.badges.bot": "Bot", + "account.badges.bot": "Automatisearre", "account.badges.group": "Groep", "account.block": "@{name} blokkearje", "account.block_domain": "Domein {domain} blokkearje", @@ -89,6 +89,11 @@ "announcement.announcement": "Oankundiging", "attachments_list.unprocessed": "(net ferwurke)", "audio.hide": "Audio ferstopje", + "block_modal.show_less": "Minder toane", + "block_modal.show_more": "Mear toane", + "block_modal.they_cant_mention": "Sy kinne jo net fermelde of folgje.", + "block_modal.title": "Brûker blokkearje?", + "block_modal.you_wont_see_mentions": "Jo sjogge gjin berjochten mear dy’t dizze account fermelde.", "boost_modal.combo": "Jo kinne op {combo} drukke om dit de folgjende kear oer te slaan", "bundle_column_error.copy_stacktrace": "Flaterrapport kopiearje", "bundle_column_error.error.body": "De opfrege side koe net werjûn wurde. It kin wêze troch in flater yn ús koade, of in probleem mei browserkompatibiliteit.", @@ -169,6 +174,7 @@ "confirmations.delete_list.message": "Binne jo wis dat jo dizze list foar permanint fuortsmite wolle?", "confirmations.discard_edit_media.confirm": "Fuortsmite", "confirmations.discard_edit_media.message": "Jo hawwe net-bewarre wizigingen yn de mediabeskriuwing of foarfertoaning, wolle jo dizze dochs fuortsmite?", + "confirmations.domain_block.confirm": "Server blokkearje", "confirmations.domain_block.message": "Binne jo echt wis dat jo alles fan {domain} negearje wolle? Yn de measte gefallen is it blokkearjen of negearjen fan in pear spesifike persoanen genôch en better. Jo sille gjin berjochten fan dizze server op iepenbiere tiidlinen sjen of yn jo meldingen. Jo folgers fan dizze server wurde fuortsmiten.", "confirmations.edit.confirm": "Bewurkje", "confirmations.edit.message": "Troch no te bewurkjen sil it berjocht dat jo no oan it skriuwen binne oerskreaun wurde. Wolle jo trochgean?", @@ -200,6 +206,20 @@ "dismissable_banner.explore_statuses": "Dizze berjochten winne oan populariteit op dizze en oare servers binnen it desintrale netwurk. Nijere berjochten mei mear boosts en favoriten stean heger.", "dismissable_banner.explore_tags": "Dizze hashtags winne oan populariteit op dizze en oare servers binnen it desintrale netwurk.", "dismissable_banner.public_timeline": "Dit binne de meast resinte iepenbiere berjochten fan accounts op it sosjale web dy’t troch minsken op {domain} folge wurde.", + "domain_block_modal.block": "Server blokkearje", + "domain_block_modal.block_account_instead": "Yn stee hjirfan {name} blokkearje", + "domain_block_modal.they_can_interact_with_old_posts": "Minsken op dizze server kinne ynteraksje hawwe mei jo âlde berjochten.", + "domain_block_modal.they_cant_follow": "Net ien op dizze server kin jo folgje.", + "domain_block_modal.they_wont_know": "Se krije net te witten dat se blokkearre wurde.", + "domain_block_modal.title": "Domein blokkearje?", + "domain_block_modal.you_will_lose_followers": "Al jo folgers fan dizze server wurde ûntfolge.", + "domain_block_modal.you_wont_see_posts": "Jo sjogge gjin berjochten of meldingen mear fan brûkers op dizze server.", + "domain_pill.server": "Server", + "domain_pill.their_handle": "Harren fediverse-adres:", + "domain_pill.their_server": "Harren digitale thús, wer’t al harren berjochten binne.", + "domain_pill.username": "Brûkersnamme", + "domain_pill.whats_in_a_handle": "Wat is in fediverse-adres?", + "domain_pill.your_handle": "Jo fediverse-adres:", "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Sa komt it der út te sjen:", "emoji_button.activity": "Aktiviteiten", @@ -266,6 +286,7 @@ "filter_modal.select_filter.subtitle": "In besteande kategory brûke of in nije oanmeitsje", "filter_modal.select_filter.title": "Dit berjocht filterje", "filter_modal.title.status": "In berjocht filterje", + "filtered_notifications_banner.title": "Filtere meldingen", "firehose.all": "Alles", "firehose.local": "Dizze server", "firehose.remote": "Oare servers", @@ -394,6 +415,9 @@ "loading_indicator.label": "Lade…", "media_gallery.toggle_visible": "{number, plural, one {ôfbylding ferstopje} other {ôfbyldingen ferstopje}}", "moved_to_account_banner.text": "Omdat jo nei {movedToAccount} ferhuze binne is jo account {disabledAccount} op dit stuit útskeakele.", + "mute_modal.hide_options": "Opsjes ferstopje", + "mute_modal.indefinite": "Oant ik se net mear negearje", + "mute_modal.show_options": "Opsjes toane", "navigation_bar.about": "Oer", "navigation_bar.advanced_interface": "Yn avansearre webomjouwing iepenje", "navigation_bar.blocks": "Blokkearre brûkers", @@ -429,14 +453,20 @@ "notification.own_poll": "Jo poll is beëinige", "notification.poll": "In enkête dêr’t jo yn stimd hawwe is beëinige", "notification.reblog": "{name} hat jo berjocht boost", + "notification.relationships_severance_event.learn_more": "Mear ynfo", "notification.status": "{name} hat in berjocht pleatst", "notification.update": "{name} hat in berjocht bewurke", + "notification_requests.accept": "Akseptearje", + "notification_requests.dismiss": "Ofwize", + "notification_requests.notifications_from": "Meldingen fan {name}", + "notification_requests.title": "Filtere meldingen", "notifications.clear": "Meldingen wiskje", "notifications.clear_confirmation": "Binne jo wis dat jo al jo meldingen permanint fuortsmite wolle?", "notifications.column_settings.admin.report": "Nije rapportaazjes:", "notifications.column_settings.admin.sign_up": "Nije registraasjes:", "notifications.column_settings.alert": "Desktopmeldingen", "notifications.column_settings.favourite": "Favoriten:", + "notifications.column_settings.filter_bar.advanced": "Alle kategoryen toane", "notifications.column_settings.follow": "Nije folgers:", "notifications.column_settings.follow_request": "Nij folchfersyk:", "notifications.column_settings.mention": "Fermeldingen:", diff --git a/app/javascript/mastodon/locales/gd.json b/app/javascript/mastodon/locales/gd.json index 9c566909a..9e79793de 100644 --- a/app/javascript/mastodon/locales/gd.json +++ b/app/javascript/mastodon/locales/gd.json @@ -12,7 +12,7 @@ "about.powered_by": "Lìonra sòisealta sgaoilte le cumhachd {mastodon}", "about.rules": "Riaghailtean an fhrithealaiche", "account.account_note_header": "Nòta", - "account.add_or_remove_from_list": "Cuir ris no thoir air falbh o na liostaichean", + "account.add_or_remove_from_list": "Cuir ris no thoir air falbh o liostaichean", "account.badges.bot": "Fèin-obrachail", "account.badges.group": "Buidheann", "account.block": "Bac @{name}", @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Cleachd roinn-seòrsa a tha ann no cruthaich tè ùr", "filter_modal.select_filter.title": "Criathraich am post seo", "filter_modal.title.status": "Criathraich post", + "filtered_notifications_banner.mentions": "{count, plural, one {iomradh} two {iomradh} few {iomraidhean} other {iomradh}}", "filtered_notifications_banner.pending_requests": "{count, plural, =0 {Chan eil brath ann o dhaoine} one {Tha brathan ann o # neach} two {Tha brathan ann o # neach} few {Tha brathan ann o # daoine} other {Tha brathan ann o # duine}} air a bheil thu eòlach ’s dòcha", "filtered_notifications_banner.title": "Brathan criathraichte", "firehose.all": "Na h-uile", @@ -307,6 +308,7 @@ "follow_requests.unlocked_explanation": "Ged nach eil an cunntas agad glaiste, tha sgioba {domain} dhen bheachd gum b’ fheàirrde thu lèirmheas a dhèanamh air na h-iarrtasan leantainn o na cunntasan seo a làimh.", "follow_suggestions.curated_suggestion": "Roghainn an sgioba", "follow_suggestions.dismiss": "Na seall seo a-rithist", + "follow_suggestions.friends_of_friends_longer": "Fèill mhòr am measg nan daoine a leanas tu", "follow_suggestions.hints.featured": "Chaidh a’ phròifil seo a thaghadh le sgioba {domain} a làimh.", "follow_suggestions.hints.friends_of_friends": "Tha fèill mhòr air a’ phròifil seo am measg nan daoine a leanas tu.", "follow_suggestions.hints.most_followed": "Tha a’ phròifil seo am measg an fheadhainn a leanar as trice air {domain}.", @@ -314,6 +316,7 @@ "follow_suggestions.hints.similar_to_recently_followed": "Tha a’ phròifil seo coltach ris na pròifilean air an lean thu o chionn goirid.", "follow_suggestions.personalized_suggestion": "Moladh pearsanaichte", "follow_suggestions.popular_suggestion": "Moladh air a bheil fèill mhòr", + "follow_suggestions.popular_suggestion_longer": "Fèill mhòr air {domain}", "follow_suggestions.view_all": "Seall na h-uile", "follow_suggestions.who_to_follow": "Molaidhean leantainn", "followed_tags": "Tagaichean hais ’gan leantainn", @@ -468,10 +471,15 @@ "notification.follow": "Tha {name} ’gad leantainn a-nis", "notification.follow_request": "Dh’iarr {name} ’gad leantainn", "notification.mention": "Thug {name} iomradh ort", + "notification.moderation-warning.learn_more": "Barrachd fiosrachaidh", "notification.own_poll": "Thàinig an cunntas-bheachd agad gu crìoch", "notification.poll": "Thàinig cunntas-bheachd sa bhòt thu gu crìoch", "notification.reblog": "Bhrosnaich {name} am post agad", - "notification.severed_relationships": "Chaidh na dàimhean le {name} a dhealachadh", + "notification.relationships_severance_event": "Chaill thu dàimhean le {name}", + "notification.relationships_severance_event.account_suspension": "Chuir rianaire aig {from} {target} à rèim agus is ciall dha sin nach fhaigh thu naidheachdan uapa ’s nach urrainn dhut conaltradh leotha.", + "notification.relationships_severance_event.domain_block": "Bhac rianaire aig {from} {target}, a’ gabhail a-staigh {followersCount} dhen luchd-leantainn agad agus {followingCount, plural, one {# chunntas} two {# chunntas} few {# cunntasan} other {# cunntas}} a tha thu fhèin a’ leantainn.", + "notification.relationships_severance_event.learn_more": "Barrachd fiosrachaidh", + "notification.relationships_severance_event.user_domain_block": "Bhac thu {target} agus thug sin air falbh {followersCount} dhen luchd-leantainn agad agus {followingCount, plural, one {# chunntas} two {# chunntas} few {# cunntasan} other {# cunntas}} a tha thu fhèin a’ leantainn.", "notification.status": "Phostaich {name} rud", "notification.update": "Dheasaich {name} post", "notification_requests.accept": "Gabh ris", @@ -484,6 +492,8 @@ "notifications.column_settings.admin.sign_up": "Clàraidhean ùra:", "notifications.column_settings.alert": "Brathan deasga", "notifications.column_settings.favourite": "Annsachdan:", + "notifications.column_settings.filter_bar.advanced": "Seall a h-uile roinn-seòrsa", + "notifications.column_settings.filter_bar.category": "Bàr-criathraidh luath", "notifications.column_settings.follow": "Luchd-leantainn ùr:", "notifications.column_settings.follow_request": "Iarrtasan leantainn ùra:", "notifications.column_settings.mention": "Iomraidhean:", @@ -509,7 +519,7 @@ "notifications.permission_denied": "Chan eil brathan deasga ri fhaighinn on a chaidh iarrtas ceadan a’ bhrabhsair a dhiùltadh cheana", "notifications.permission_denied_alert": "Cha ghabh brathan deasga a chur an comas on a chaidh iarrtas ceadan a’ bhrabhsair a dhiùltadh cheana", "notifications.permission_required": "Chan eil brathan deasga ri fhaighinn on nach deach an cead riatanach a thoirt seachad.", - "notifications.policy.filter_new_accounts.hint": "Chaidh a chruthachadh o chionn {days, plural, one {# latha} two {# latha} few {# làithean} other {# latha}}", + "notifications.policy.filter_new_accounts.hint": "A chaidh a chruthachadh o chionn {days, plural, one {# latha} two {# latha} few {# làithean} other {# latha}}", "notifications.policy.filter_new_accounts_title": "Cunntasan ùra", "notifications.policy.filter_not_followers_hint": "A’ gabhail a-staigh an fheadhainn a lean ort nas lugha na {days, plural, one {# latha} two {# latha} few {# làithean} other {# latha}} seo chaidh", "notifications.policy.filter_not_followers_title": "Daoine nach eil gad leantainn", @@ -588,12 +598,6 @@ "refresh": "Ath-nuadhaich", "regeneration_indicator.label": "’Ga luchdadh…", "regeneration_indicator.sublabel": "Tha do dhachaigh ’ga ullachadh!", - "relationship_severance_notification.purged_data": "chaidh a phurgaideachadh leis na rianairean", - "relationship_severance_notification.relationships": "{count, plural, one {# dàimh} two {# dhàimh} few {# dàimhean} other {# dàimh}}", - "relationship_severance_notification.types.account_suspension": "Chaidh cunntas a chur à rèim", - "relationship_severance_notification.types.domain_block": "Chaidh àrainn a chur à rèim", - "relationship_severance_notification.types.user_domain_block": "Bhac thu an àrainn seo", - "relationship_severance_notification.view": "Seall", "relative_time.days": "{number}l", "relative_time.full.days": "{number, plural, one {# latha} two {# latha} few {# làithean} other {# latha}} air ais", "relative_time.full.hours": "{number, plural, one {# uair a thìde} two {# uair a thìde} few {# uairean a thìde} other {# uair a thìde}} air ais", @@ -701,10 +705,10 @@ "status.direct_indicator": "Iomradh prìobhaideach", "status.edit": "Deasaich", "status.edited": "An deasachadh mu dheireadh {date}", - "status.edited_x_times": "Chaidh a dheasachadh {count, plural, one {{counter} turas} two {{counter} thuras} few {{counter} tursan} other {{counter} turas}}", + "status.edited_x_times": "Chaidh a dheasachadh {count, plural, one {{count} turas} two {{count} thuras} few {{count} tursan} other {{count} turas}}", "status.embed": "Leabaich", "status.favourite": "Cuir ris na h-annsachdan", - "status.favourites": "{count, plural, one {annsachd} two {annsachd} few {annsachdan} other {annsachd}", + "status.favourites": "{count, plural, one {annsachd} two {annsachd} few {annsachdan} other {annsachd}}", "status.filter": "Criathraich am post seo", "status.filtered": "Criathraichte", "status.hide": "Falaich am post", @@ -725,7 +729,7 @@ "status.reblog": "Brosnaich", "status.reblog_private": "Brosnaich leis an t-so-fhaicsinneachd tùsail", "status.reblogged_by": "’Ga bhrosnachadh le {name}", - "status.reblogs": "{count, plural, one {bhrosnachadh} two {bhrosnachadh} few {brosnachaidhean} other {brosnachadh}", + "status.reblogs": "{count, plural, one {bhrosnachadh} two {bhrosnachadh} few {brosnachaidhean} other {brosnachadh}}", "status.reblogs.empty": "Chan deach am post seo a bhrosnachadh le duine sam bith fhathast. Nuair a bhrosnaicheas cuideigin e, nochdaidh iad an-seo.", "status.redraft": "Sguab às ⁊ dèan dreachd ùr", "status.remove_bookmark": "Thoir an comharra-lìn air falbh", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index 57d13205f..49802ac48 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Usar unha categoría existente ou crear unha nova", "filter_modal.select_filter.title": "Filtrar esta publicación", "filter_modal.title.status": "Filtrar unha publicación", + "filtered_notifications_banner.mentions": "{count, plural, one {mención} other {mencións}}", "filtered_notifications_banner.pending_requests": "Notificacións de {count, plural, =0 {ninguén} one {unha persoa} other {# persoas}} que poderías coñecer", "filtered_notifications_banner.title": "Notificacións filtradas", "firehose.all": "Todo", @@ -307,6 +308,8 @@ "follow_requests.unlocked_explanation": "Malia que a túa conta non é privada, a administración de {domain} pensou que quizabes terías que revisar de xeito manual as solicitudes de seguiminto.", "follow_suggestions.curated_suggestion": "Suxestións do Servidor", "follow_suggestions.dismiss": "Non mostrar máis", + "follow_suggestions.featured_longer": "Elección persoal do equipo de {domain}", + "follow_suggestions.friends_of_friends_longer": "Popular entre as persoas que sigues", "follow_suggestions.hints.featured": "Este perfil foi escollido pola administración de {domain}.", "follow_suggestions.hints.friends_of_friends": "Este perfil é popular entre as persoas que segues.", "follow_suggestions.hints.most_followed": "Este perfil é un dos máis seguidos en {domain}.", @@ -314,6 +317,8 @@ "follow_suggestions.hints.similar_to_recently_followed": "Este perfil ten semellanzas cos perfís que ti seguiches últimamente.", "follow_suggestions.personalized_suggestion": "Suxestión personalizada", "follow_suggestions.popular_suggestion": "Suxestión popular", + "follow_suggestions.popular_suggestion_longer": "Popular en {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Perfís semellantes aos que seguiches recentemente", "follow_suggestions.view_all": "Ver todas", "follow_suggestions.who_to_follow": "A quen seguir", "followed_tags": "Cancelos seguidos", @@ -468,10 +473,23 @@ "notification.follow": "{name} comezou a seguirte", "notification.follow_request": "{name} solicitou seguirte", "notification.mention": "{name} mencionoute", + "notification.moderation-warning.learn_more": "Saber máis", + "notification.moderation_warning": "Recibiches unha advertencia da moderación", + "notification.moderation_warning.action_delete_statuses": "Algunha das túas publicacións foron eliminadas.", + "notification.moderation_warning.action_disable": "A túa conta foi desactivada.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Algunha das túas publicacións foron marcadas como sensibles.", + "notification.moderation_warning.action_none": "A túa conta recibeu unha advertencia da moderación.", + "notification.moderation_warning.action_sensitive": "De agora en diante as túas publicacións van ser marcadas como sensibles.", + "notification.moderation_warning.action_silence": "A túa conta foi limitada.", + "notification.moderation_warning.action_suspend": "A túa conta foi suspendida.", "notification.own_poll": "A túa enquisa rematou", "notification.poll": "Rematou a enquisa na que votaches", "notification.reblog": "{name} compartiu a túa publicación", - "notification.severed_relationships": "Cortouse a relación con {name}", + "notification.relationships_severance_event": "Perdeuse a conexión con {name}", + "notification.relationships_severance_event.account_suspension": "A administración de {from} suspendeu a {target}, o que significa que xa non vas recibir actualizacións de esa conta ou interactuar con ela.", + "notification.relationships_severance_event.domain_block": "A administración de {from} bloqueou a {target}, que inclúe a {followersCount} das túas seguidoras e a {followingCount, plural, one {# conta} other {# contas}} que sigues.", + "notification.relationships_severance_event.learn_more": "Saber máis", + "notification.relationships_severance_event.user_domain_block": "Bloqueaches a {target}, eliminando a {followersCount} das túas seguidoras e a {followingCount, plural, one {# conta} other {# contas}} que sigues.", "notification.status": "{name} publicou", "notification.update": "{name} editou unha publicación", "notification_requests.accept": "Aceptar", @@ -484,6 +502,8 @@ "notifications.column_settings.admin.sign_up": "Novas usuarias:", "notifications.column_settings.alert": "Notificacións de escritorio", "notifications.column_settings.favourite": "Favoritas:", + "notifications.column_settings.filter_bar.advanced": "Mostrar todas as categorías", + "notifications.column_settings.filter_bar.category": "Barra de filtrado rápido", "notifications.column_settings.follow": "Novas seguidoras:", "notifications.column_settings.follow_request": "Novas peticións de seguimento:", "notifications.column_settings.mention": "Mencións:", @@ -588,12 +608,6 @@ "refresh": "Actualizar", "regeneration_indicator.label": "Estase a cargar…", "regeneration_indicator.sublabel": "Estase a preparar a túa cronoloxía de inicio!", - "relationship_severance_notification.purged_data": "purgada pola administración", - "relationship_severance_notification.relationships": "{count, plural, one {# relación} other {# relacións}}", - "relationship_severance_notification.types.account_suspension": "A conta foi suspendida", - "relationship_severance_notification.types.domain_block": "O dominio foi suspendido", - "relationship_severance_notification.types.user_domain_block": "Bloqueaches este dominio", - "relationship_severance_notification.view": "Ver", "relative_time.days": "{number}d", "relative_time.full.days": "hai {number, plural, one {# día} other {# días}}", "relative_time.full.hours": "hai {number, plural, one {# hora} other {# horas}}", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index 1f65c3549..0b66a27fa 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.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, one {איזכור} other {איזכורים} two {איזכוריים}}", "filtered_notifications_banner.pending_requests": "{count, plural,=0 {אין התראות ממשתמשים ה}one {התראה אחת ממישהו/מישהי ה}two {יש התראותיים ממשתמשים }other {יש # התראות ממשתמשים }}מוכרים לך", "filtered_notifications_banner.title": "התראות מסוננות", "firehose.all": "הכל", @@ -307,6 +308,8 @@ "follow_requests.unlocked_explanation": "למרות שחשבונך אינו נעול, צוות {domain} חושב שאולי כדאי לוודא את בקשות המעקב האלה ידנית.", "follow_suggestions.curated_suggestion": "בחירת הצוות", "follow_suggestions.dismiss": "לא להציג שוב", + "follow_suggestions.featured_longer": "נבחר ידנית על ידי הצוות של {domain}", + "follow_suggestions.friends_of_friends_longer": "פופולרי בין הנעקבים שלך", "follow_suggestions.hints.featured": "החשבון הזה נבחר אישית על ידי צוות {domain}.", "follow_suggestions.hints.friends_of_friends": "חשבון זה פופולרי בין הנעקבים שלך.", "follow_suggestions.hints.most_followed": "חשבון זה הוא מבין הנעקבים ביותר בשרת {domain}.", @@ -314,6 +317,8 @@ "follow_suggestions.hints.similar_to_recently_followed": "חשבון זה דומה לחשבונות אחרים שאחריהם התחלת לעקוב לאחרונה.", "follow_suggestions.personalized_suggestion": "הצעות מותאמות אישית", "follow_suggestions.popular_suggestion": "הצעה פופולרית", + "follow_suggestions.popular_suggestion_longer": "פופולרי בקהילת {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "דומה למשתמשות.ים שעקבת אחריהן.ם לאחרונה", "follow_suggestions.view_all": "צפיה בכל", "follow_suggestions.who_to_follow": "אחרי מי לעקוב", "followed_tags": "התגיות שהחשבון שלך עוקב אחריהן", @@ -471,7 +476,11 @@ "notification.own_poll": "הסקר שלך הסתיים", "notification.poll": "סקר שהצבעת בו הסתיים", "notification.reblog": "הודעתך הודהדה על ידי {name}", - "notification.severed_relationships": "חתכתם כל קשר עם {name}", + "notification.relationships_severance_event": "אבד הקשר עם {name}", + "notification.relationships_severance_event.account_suspension": "מנהל.ת משרת {from} השע(ת)ה את {target}, ולפיכך לא תעודכנו יותר על ידם ולא תוכלו להיות איתם בקשר.", + "notification.relationships_severance_event.domain_block": "מנהל.ת מאתר {from} חסמו את {target} ובכלל זה {followersCount} מעוקביך וגם {followingCount, plural, one {חשבון אחד} two {שני חשבונות} many {# חשבונות} other {# חשבונות}} מבין נעקביך.", + "notification.relationships_severance_event.learn_more": "למידע נוסף", + "notification.relationships_severance_event.user_domain_block": "חסמת את {target} ובכלל זה {followersCount} מעוקביך וגם {followingCount, plural, one {חשבון אחד} two {שני חשבונות} many {# חשבונות} other {# חשבונות}} מבין נעקביך.", "notification.status": "{name} הרגע פרסמו", "notification.update": "{name} ערכו הודעה", "notification_requests.accept": "לקבל", @@ -484,6 +493,8 @@ "notifications.column_settings.admin.sign_up": "הרשמות חדשות:", "notifications.column_settings.alert": "התראות לשולחן העבודה", "notifications.column_settings.favourite": "חיבובים:", + "notifications.column_settings.filter_bar.advanced": "להציג את כל הקטגוריות", + "notifications.column_settings.filter_bar.category": "שורת סינון מהיר", "notifications.column_settings.follow": "עוקבים חדשים:", "notifications.column_settings.follow_request": "בקשות מעקב חדשות:", "notifications.column_settings.mention": "פניות:", @@ -588,12 +599,6 @@ "refresh": "רענון", "regeneration_indicator.label": "טוען…", "regeneration_indicator.sublabel": "פיד הבית שלך בהכנה!", - "relationship_severance_notification.purged_data": "המידע נמחק על ידי ההנהלה", - "relationship_severance_notification.relationships": "{count, plural, one {קשר אחד} other {# קשרים}}", - "relationship_severance_notification.types.account_suspension": "החשבון הושעה", - "relationship_severance_notification.types.domain_block": "השרת הושעה", - "relationship_severance_notification.types.user_domain_block": "חסמת שרת זה", - "relationship_severance_notification.view": "הצג", "relative_time.days": "{number} ימים", "relative_time.full.days": "לפני {number, plural, one {# יום} other {# ימים}}", "relative_time.full.hours": "לפני {number, plural, one {# שעה} other {# שעות}}", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index d9dfd01a2..42ce84258 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -124,7 +124,7 @@ "column.domain_blocks": "Letiltott domainek", "column.favourites": "Kedvencek", "column.firehose": "Hírfolyamok", - "column.follow_requests": "Követési kérelmek", + "column.follow_requests": "Követési kérések", "column.home": "Kezdőlap", "column.lists": "Listák", "column.mutes": "Némított felhasználók", @@ -133,8 +133,8 @@ "column.public": "Föderációs idővonal", "column_back_button.label": "Vissza", "column_header.hide_settings": "Beállítások elrejtése", - "column_header.moveLeft_settings": "Oszlop elmozdítása balra", - "column_header.moveRight_settings": "Oszlop elmozdítása jobbra", + "column_header.moveLeft_settings": "Oszlop áthelyezése balra", + "column_header.moveRight_settings": "Oszlop áthelyezése jobbra", "column_header.pin": "Kitűzés", "column_header.show_settings": "Beállítások megjelenítése", "column_header.unpin": "Kitűzés eltávolítása", @@ -143,7 +143,7 @@ "community.column_settings.media_only": "Csak média", "community.column_settings.remote_only": "Csak távoli", "compose.language.change": "Nyelv megváltoztatása", - "compose.language.search": "Nyelv keresése...", + "compose.language.search": "Nyelvek keresése…", "compose.published.body": "A bejegyzés publikálásra került.", "compose.published.open": "Megnyitás", "compose.saved.body": "A bejegyzés mentve.", @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Válassz egy meglévő kategóriát, vagy hozz létre egy újat", "filter_modal.select_filter.title": "E bejegyzés szűrése", "filter_modal.title.status": "Egy bejegyzés szűrése", + "filtered_notifications_banner.mentions": "{count, plural, one {említés} other {említés}}", "filtered_notifications_banner.pending_requests": "Értesítések {count, plural, =0 {nincsenek} one {egy valósztínűleg ismerős személytől} other {# valószínűleg ismerős személytől}}", "filtered_notifications_banner.title": "Szűrt értesítések", "firehose.all": "Összes", @@ -307,6 +308,8 @@ "follow_requests.unlocked_explanation": "Bár a fiókod nincs zárolva, a(z) {domain} csapata úgy gondolta, hogy talán kézzel szeretnéd ellenőrizni ezen fiókok követési kéréseit.", "follow_suggestions.curated_suggestion": "A stáb választása", "follow_suggestions.dismiss": "Ne jelenjen meg újra", + "follow_suggestions.featured_longer": "A {domain} csapata által kézzel kiválasztott", + "follow_suggestions.friends_of_friends_longer": "Népszerű az Ön által követett emberek körében", "follow_suggestions.hints.featured": "Ezt a profilt a(z) {domain} csapata választotta ki.", "follow_suggestions.hints.friends_of_friends": "Ez a profil népszerű az általad követett emberek körében.", "follow_suggestions.hints.most_followed": "Ez a profil a leginkább követett a(z) {domain} oldalon.", @@ -314,6 +317,8 @@ "follow_suggestions.hints.similar_to_recently_followed": "Ez a profil hasonló azokhoz a profilokhoz, melyeket nemrég kezdtél el követni.", "follow_suggestions.personalized_suggestion": "Személyre szabott javaslat", "follow_suggestions.popular_suggestion": "Népszerű javaslat", + "follow_suggestions.popular_suggestion_longer": "Népszerű itt: {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Hasonló profilok, melyeket nemrég követett", "follow_suggestions.view_all": "Összes megtekintése", "follow_suggestions.who_to_follow": "Kit érdemes követni", "followed_tags": "Követett hashtagek", @@ -468,10 +473,23 @@ "notification.follow": "{name} követ téged", "notification.follow_request": "{name} követni szeretne téged", "notification.mention": "{name} megemlített", + "notification.moderation-warning.learn_more": "További információk", + "notification.moderation_warning": "Moderációs figyelmeztetést kaptál", + "notification.moderation_warning.action_delete_statuses": "Néhány bejegyzésedet eltávolították.", + "notification.moderation_warning.action_disable": "A fiókod le van tiltva.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Néhány bejegyzésedet kényesnek jelölték.", + "notification.moderation_warning.action_none": "A fiókod moderációs figyelmeztetést kapott.", + "notification.moderation_warning.action_sensitive": "A bejegyzéseid mostantól érzékenynek lesznek jelölve.", + "notification.moderation_warning.action_silence": "A fiókod korlátozásra került.", + "notification.moderation_warning.action_suspend": "A fiókod felfüggesztésre került.", "notification.own_poll": "A szavazásod véget ért", "notification.poll": "Egy szavazás, melyben részt vettél, véget ért", "notification.reblog": "{name} megtolta a bejegyzésedet", - "notification.severed_relationships": "A kapcsolatok megszakítva ezzel: {name}", + "notification.relationships_severance_event": "Elvesztek a kapcsolatok vele: {name}", + "notification.relationships_severance_event.account_suspension": "Egy admin a(z) {from} kiszolgálóról felfüggesztette {target} fiókját, ami azt jelenti, hogy mostantól nem fogsz róla értesítést kapni, és nem fogsz tudni vele kapcsolatba lépni.", + "notification.relationships_severance_event.domain_block": "Egy admin a(z) {from} kiszolgálón letiltotta {target} domaint, beleértve {followersCount} követőt és {followingCount, plural, one {#} other {#}} követett fiókot.", + "notification.relationships_severance_event.learn_more": "További információk", + "notification.relationships_severance_event.user_domain_block": "Letiltottad a(z) {target} domaint, ezzel eltávolítva {followersCount} követőt és {followingCount, plural, one {#} other {#}} követett fiókot.", "notification.status": "{name} bejegyzést tett közzé", "notification.update": "{name} szerkesztett egy bejegyzést", "notification_requests.accept": "Elfogadás", @@ -484,8 +502,10 @@ "notifications.column_settings.admin.sign_up": "Új regisztrálók:", "notifications.column_settings.alert": "Asztali értesítések", "notifications.column_settings.favourite": "Kedvencek:", + "notifications.column_settings.filter_bar.advanced": "Minden kategória megjelenítése", + "notifications.column_settings.filter_bar.category": "Gyorsszűrő sáv", "notifications.column_settings.follow": "Új követők:", - "notifications.column_settings.follow_request": "Új követési kérelmek:", + "notifications.column_settings.follow_request": "Új követési kérések:", "notifications.column_settings.mention": "Megemlítések:", "notifications.column_settings.poll": "Szavazási eredmények:", "notifications.column_settings.push": "Leküldéses értesítések", @@ -545,14 +565,14 @@ "onboarding.share.next_steps": "Lehetséges következő lépések:", "onboarding.share.title": "Profil megosztása", "onboarding.start.lead": "Az új Mastodon-fiók használatra kész. Így hozhatod ki belőle a legtöbbet:", - "onboarding.start.skip": "Szeretnél előreugrani?", + "onboarding.start.skip": "Nincs szükséged segítségre a kezdéshez?", "onboarding.start.title": "Ez sikerült!", "onboarding.steps.follow_people.body": "A Mastodon az érdekes emberek követéséről szól.", - "onboarding.steps.follow_people.title": "{count, plural, one {egy ember} other {# ember}} követése", - "onboarding.steps.publish_status.body": "Üdvözöljük a világot.", + "onboarding.steps.follow_people.title": "Szabd személyre a kezdőlapodat", + "onboarding.steps.publish_status.body": "Köszöntsd a világot szöveggel, fotókkal, videókkal vagy szavazásokkal {emoji}", "onboarding.steps.publish_status.title": "Az első bejegyzés létrehozása", - "onboarding.steps.setup_profile.body": "Mások nagyobb valószínűséggel lépnek kapcsolatba veled egy kitöltött profil esetén.", - "onboarding.steps.setup_profile.title": "Profilod testreszabása", + "onboarding.steps.setup_profile.body": "Növeld az interakciók számát a profilod részletesebb kitöltésével.", + "onboarding.steps.setup_profile.title": "Szabd személyre a profilodat", "onboarding.steps.share_profile.body": "Tudasd az ismerőseiddel, hogyan találhatnak meg a Mastodonon", "onboarding.steps.share_profile.title": "Oszd meg a Mastodon profilodat", "onboarding.tips.2fa": "Tudtad? A fiókod biztonságossá teheted, ha a fiók beállításaiban beállítod a kétlépcsős hitelesítést. Bármilyen választott TOTP alkalmazással működik, nincs szükség telefonszámra!", @@ -588,12 +608,6 @@ "refresh": "Frissítés", "regeneration_indicator.label": "Betöltés…", "regeneration_indicator.sublabel": "A saját idővonalad épp készül!", - "relationship_severance_notification.purged_data": "rendszergazdák által véglegesen törölve", - "relationship_severance_notification.relationships": "{count, plural, one {# kapcsolat} other {# kapcsolat}}", - "relationship_severance_notification.types.account_suspension": "A fiók fel van függesztve", - "relationship_severance_notification.types.domain_block": "A domain fel van függesztve", - "relationship_severance_notification.types.user_domain_block": "Blokkoltad ezt a domaint", - "relationship_severance_notification.view": "Megtekintés", "relative_time.days": "{number}n", "relative_time.full.days": "{number, plural, one {# napja} other {# napja}}", "relative_time.full.hours": "{number, plural, one {# órája} other {# órája}}", @@ -786,9 +800,9 @@ "upload_modal.hint": "Kattints vagy húzd a kört az előnézetben arra a fókuszpontra, mely minden bélyegképen látható kell, hogy legyen.", "upload_modal.preparing_ocr": "OCR előkészítése…", "upload_modal.preview_label": "Előnézet ({ratio})", - "upload_progress.label": "Feltöltés...", + "upload_progress.label": "Feltöltés…", "upload_progress.processing": "Feldolgozás…", - "username.taken": "Ez a felhasználónév foglalt. Válassz másikat", + "username.taken": "Ez a felhasználónév foglalt. Válassz másikat.", "video.close": "Videó bezárása", "video.download": "Fájl letöltése", "video.exit_fullscreen": "Kilépés teljes képernyőből", @@ -798,5 +812,5 @@ "video.mute": "Hang némítása", "video.pause": "Szünet", "video.play": "Lejátszás", - "video.unmute": "Hang némításának vége" + "video.unmute": "Hang némításának feloldása" } diff --git a/app/javascript/mastodon/locales/ia.json b/app/javascript/mastodon/locales/ia.json index e587dbc52..73634b99c 100644 --- a/app/javascript/mastodon/locales/ia.json +++ b/app/javascript/mastodon/locales/ia.json @@ -3,59 +3,66 @@ "about.contact": "Contacto:", "about.disclaimer": "Mastodon es software libere, de codice aperte, e un marca de Mastodon gGmbH.", "about.domain_blocks.no_reason_available": "Ration non disponibile", - "about.domain_blocks.preamble": "Mastodon generalmente permitte vider contento ab e interacter con usatores ab ulle altere servitor in le fediverso. Iste es le exceptiones que ha essite facite in iste servitor particular.", - "about.domain_blocks.silenced.explanation": "Generalmente non videras perfiles e contento de iste servitor, a minus que tu expressemente lo cerca o opta pro lo per sequer.", + "about.domain_blocks.preamble": "Mastodon generalmente permitte vider le contento de, e interager con, usatores de qualcunque altere servitor in le fediverso. Istes es le exceptiones que ha essite facite sur iste servitor particular.", + "about.domain_blocks.silenced.explanation": "Generalmente, tu non videra le profilos e le contento de iste servitor, excepte si tu expressemente cerca le contento o seque le profilos.", "about.domain_blocks.silenced.title": "Limitate", - "about.domain_blocks.suspended.explanation": "Nulle data de iste servitor essera processate, immagazinate o scambiate, faciente qualcunque interaction o communication con usatores de iste servitor impossibile.", + "about.domain_blocks.suspended.explanation": "Nulle datos de iste servitor essera processate, immagazinate o excambiate, rendente omne interaction o communication con usatores de iste servitor impossibile.", "about.domain_blocks.suspended.title": "Suspendite", - "about.not_available": "Iste information non faceva disponibile in iste servitor.", + "about.not_available": "Iste information non ha essite rendite disponibile sur iste servitor.", + "about.powered_by": "Rete social decentralisate, actionate per {mastodon}", "about.rules": "Regulas del servitor", "account.account_note_header": "Nota", - "account.add_or_remove_from_list": "Adder o remover ab listas", + "account.add_or_remove_from_list": "Adder a, o remover de listas", + "account.badges.bot": "Automatisate", "account.badges.group": "Gruppo", "account.block": "Blocar @{name}", "account.block_domain": "Blocar dominio {domain}", "account.block_short": "Blocar", "account.blocked": "Blocate", "account.browse_more_on_origin_server": "Navigar plus sur le profilo original", + "account.cancel_follow_request": "Cancellar sequimento", "account.copy": "Copiar ligamine a profilo", - "account.direct": "Mentionar privatemente a @{name}", - "account.disable_notifications": "Stoppar le notificationes quando @{name} publica", + "account.direct": "Mentionar privatemente @{name}", + "account.disable_notifications": "Non plus notificar me quando @{name} publica", "account.domain_blocked": "Dominio blocate", "account.edit_profile": "Modificar profilo", - "account.enable_notifications": "Notifica me quando @{name} publica", + "account.enable_notifications": "Notificar me quando @{name} publica", "account.endorse": "Evidentiar sur le profilo", - "account.featured_tags.last_status_at": "Ultime message in {date}", - "account.featured_tags.last_status_never": "Necun messages", + "account.featured_tags.last_status_at": "Ultime message publicate le {date}", + "account.featured_tags.last_status_never": "Necun message", "account.featured_tags.title": "Hashtags eminente de {name}", "account.follow": "Sequer", - "account.follow_back": "Sequer etiam", + "account.follow_back": "Sequer in retorno", "account.followers": "Sequitores", - "account.followers.empty": "Iste usator ancora non ha sequitores.", + "account.followers.empty": "Necuno seque ancora iste usator.", "account.followers_counter": "{count, plural, one {{counter} sequitor} other {{counter} sequitores}}", "account.following": "Sequente", - "account.follows.empty": "Iste usator ancora non seque nemo.", + "account.following_counter": "{count, plural, one {{counter} sequite} other {{counter} sequites}}", + "account.follows.empty": "Iste usator non seque ancora alcuno.", "account.go_to_profile": "Vader al profilo", - "account.hide_reblogs": "Celar boosts de @{name}", - "account.in_memoriam": "In Memoriam.", + "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 esseva verificate le {date}", - "account.locked_info": "Le stato de confidentialitate de iste conto es definite a blocate. Le proprietario revisa manualmente qui pote sequer lo.", + "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.", "account.media": "Multimedia", "account.mention": "Mentionar @{name}", - "account.moved_to": "{name} indicava que lor nove conto ora es:", + "account.moved_to": "{name} ha indicate que su nove conto ora es:", "account.mute": "Silentiar @{name}", "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} habeva requestate sequer te", + "account.requested_follow": "{name} ha requestate de sequer te", "account.share": "Compartir profilo de @{name}", - "account.show_reblogs": "Monstrar responsas de @{name}", + "account.show_reblogs": "Monstrar impulsos de @{name}", "account.statuses_counter": "{count, plural, one {{counter} message} other {{counter} messages}}", "account.unblock": "Disblocar @{name}", "account.unblock_domain": "Disblocar dominio {domain}", @@ -66,23 +73,49 @@ "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.retention.average": "Median", + "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_followers": "Sequitores que nostre usatores poterea perder", - "admin.impact_report.instance_follows": "Sequitores que lor usatores poterea perder", - "alert.rate_limited.message": "Retenta depost {retry_time, time, medium}.", - "alert.unexpected.message": "Ocurreva un error inexpectate.", + "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", - "bundle_column_error.error.title": "Oh, non!", + "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_modal.description": "Crear un conto in {domain} actualmente non es possibile, ma considera que tu non besonia un conto specific in {domain} pro usar Mastodon.", - "closed_registrations_modal.find_another_server": "Trovar altere servitor", - "column.about": "A proposito de", + "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", "column.community": "Chronologia local", @@ -90,35 +123,43 @@ "column.directory": "Navigar profilos", "column.domain_blocks": "Dominios blocate", "column.favourites": "Favoritos", - "column.firehose": "Fluxos in directe", + "column.firehose": "Fluxos in directo", + "column.follow_requests": "Requestas de sequimento", "column.home": "Initio", "column.lists": "Listas", "column.mutes": "Usatores silentiate", "column.notifications": "Notificationes", + "column.pins": "Messages fixate", "column.public": "Chronologia federate", "column_back_button.label": "Retro", "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 medios", + "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.", "compose.published.open": "Aperir", "compose.saved.body": "Message salvate.", "compose_form.direct_message_warning_learn_more": "Apprender plus", + "compose_form.encryption_warning": "Le messages sur Mastodon non es cryptate de puncta a puncta. Non condivide alcun information sensibile usante Mastodon.", + "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": "blocate", - "compose_form.poll.duration": "Duration del inquesta", + "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}", "compose_form.poll.single": "Seliger un", - "compose_form.poll.switch_to_multiple": "Cambiar inquesta pro permitter selectiones multiple", - "compose_form.poll.switch_to_single": "Cambiar inquesta pro permitter selection singule", - "compose_form.poll.type": "Stylo", + "compose_form.poll.switch_to_multiple": "Cambiar le sondage pro permitter selectiones multiple", + "compose_form.poll.switch_to_single": "Cambiar le sondage pro permitter selection singule", + "compose_form.poll.type": "Stilo", "compose_form.publish": "Publicar", "compose_form.publish_form": "Nove message", "compose_form.reply": "Responder", @@ -129,18 +170,26 @@ "confirmation_modal.cancel": "Cancellar", "confirmations.block.confirm": "Blocar", "confirmations.cancel_follow_request.confirm": "Retirar requesta", - "confirmations.cancel_follow_request.message": "Es tu secur que tu vole retirar tu requesta a sequer a {name}?", + "confirmations.cancel_follow_request.message": "Es tu secur que tu vole retirar tu requesta de sequer {name}?", "confirmations.delete.confirm": "Deler", "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.logout.confirm": "Clauder le session", + "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 non plus sequer {name}?", + "confirmations.unfollow.message": "Es tu secur que tu vole cessar de sequer {name}?", "conversation.delete": "Deler conversation", "conversation.mark_as_read": "Marcar como legite", "conversation.open": "Vider conversation", @@ -154,9 +203,35 @@ "directory.recently_active": "Recentemente active", "disabled_account_banner.account_settings": "Parametros de conto", "disabled_account_banner.text": "Tu conto {disabledAccount} es actualmente disactivate.", + "dismissable_banner.community_timeline": "Ecce le messages public le plus recente del personas con contos sur {domain}.", "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", + "domain_block_modal.they_can_interact_with_old_posts": "Le personas de iste servitor pote interager con tu messages ancian.", + "domain_block_modal.they_cant_follow": "Nulle persona ab iste servitor pote sequer te.", + "domain_block_modal.they_wont_know": "Illes non sapera que illes ha essite blocate.", + "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", - "embed.preview": "Hic es como il parera:", + "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", "emoji_button.clear": "Rader", "emoji_button.custom": "Personalisate", @@ -164,22 +239,41 @@ "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...", "emoji_button.search_results": "Resultatos de recerca", "emoji_button.symbols": "Symbolos", "emoji_button.travel": "Viages e locos", - "empty_column.account_hides_collections": "Le usator ha seligite non facer iste information disponibile", + "empty_column.account_hides_collections": "Le usator non ha rendite iste information disponibile", "empty_column.account_suspended": "Conto suspendite", "empty_column.account_timeline": "Nulle messages hic!", "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": "Nihil es in tendentias ora mesme. Retorna postea!", - "empty_column.favourited_statuses": "Tu non ha necun messages favorite ancora. Quando tu marca un como favorito, ille essera monstrate hic.", - "empty_column.followed_tags": "Tu ancora non ha sequite necun hashtags. Quando tu lo face, illes essera monstrate hic.", - "empty_column.hashtag": "Ancora non il ha nihil in iste hashtag.", + "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", @@ -187,25 +281,46 @@ "explore.trending_links": "Novas", "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 esseva addite al sequente categoria de filtros: {title}.", + "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", - "footer.about": "A proposito de", + "follow_suggestions.who_to_follow": "Qui sequer", + "followed_tags": "Hashtags sequite", + "footer.about": "A proposito", "footer.directory": "Directorio de profilos", - "footer.get_app": "Obtene le application", + "footer.get_app": "Obtener le application", "footer.invite": "Invitar personas", "footer.keyboard_shortcuts": "Accessos directe de claviero", "footer.privacy_policy": "Politica de confidentialitate", @@ -218,60 +333,112 @@ "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", "hashtag.unfollow": "Non sequer plus le hashtag", "hashtags.and_other": "…e {count, plural, one {}other {# plus}}", - "home.column_settings.show_reblogs": "Monstrar boosts", + "home.column_settings.show_reblogs": "Monstrar impulsos", "home.column_settings.show_replies": "Monstrar responsas", "home.hide_announcements": "Celar annuncios", "home.pending_critical_update.body": "Actualisa tu servitor de Mastodon le plus tosto possibile!", "home.pending_critical_update.link": "Vider actualisationes", "home.pending_critical_update.title": "Actualisation de securitate critic disponibile!", "home.show_announcements": "Monstrar annuncios", - "interaction_modal.login.prompt": "Dominio de tu servitor, p.e. mastodon.social", + "interaction_modal.description.favourite": "Con un conto sur Mastodon, tu pote marcar iste message como favorite pro informar le autor que tu lo apprecia e salveguarda pro plus tarde.", + "interaction_modal.description.follow": "Con un conto sur Mastodon, tu pote sequer {name} e reciper su messages in tu fluxo de initio.", + "interaction_modal.description.reblog": "Con un conto sur Mastodon, tu pote impulsar iste message pro condivider lo con tu proprie sequitores.", + "interaction_modal.description.reply": "Con un conto sur Mastodon, tu pote responder a iste message.", + "interaction_modal.login.action": "Porta me a casa", + "interaction_modal.login.prompt": "Dominio de tu servitor, p.ex. mastodon.social", "interaction_modal.no_account_yet": "Non sur Mstodon?", - "interaction_modal.on_another_server": "In un servitor differente", - "interaction_modal.on_this_server": "In iste servitor", + "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": "Facer boost al message de {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": "Facer boost al message", + "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.down": "Displaciar a basso in le lista", "keyboard_shortcuts.enter": "Aperir message", + "keyboard_shortcuts.favourite": "Message favorite", "keyboard_shortcuts.favourites": "Aperir lista de favoritos", "keyboard_shortcuts.federated": "Aperir le chronologia federate", "keyboard_shortcuts.heading": "Accessos directe de claviero", "keyboard_shortcuts.home": "Aperir le chronologia de initio", + "keyboard_shortcuts.hotkey": "Clave accelerator", + "keyboard_shortcuts.legend": "Monstrar iste legenda", "keyboard_shortcuts.local": "Aperir le chronologia local", + "keyboard_shortcuts.mention": "Mentionar le author", "keyboard_shortcuts.muted": "Aperir lista de usatores silentiate", "keyboard_shortcuts.my_profile": "Aperir tu profilo", "keyboard_shortcuts.notifications": "Aperir columna de notificationes", - "keyboard_shortcuts.open_media": "Aperir medio", + "keyboard_shortcuts.open_media": "Aperir multimedia", + "keyboard_shortcuts.pinned": "Aperir le lista de messages fixate", "keyboard_shortcuts.profile": "Aperir le profilo del autor", "keyboard_shortcuts.reply": "Responder al message", + "keyboard_shortcuts.requests": "Aperir le lista de requestas de sequimento", + "keyboard_shortcuts.search": "Focalisar barra de recerca", "keyboard_shortcuts.spoilers": "Monstrar/celar le campo CW", - "keyboard_shortcuts.toggle_sensitivity": "Monstrar/celar medios", + "keyboard_shortcuts.start": "Aperir columna “comenciar”", + "keyboard_shortcuts.toggle_hidden": "Monstrar/celar texto detra advertimento de contento", + "keyboard_shortcuts.toggle_sensitivity": "Monstrar/celar multimedia", "keyboard_shortcuts.toot": "Initiar un nove message", + "keyboard_shortcuts.unfocus": "Disfocalisar le area de composition de texto/de recerca", + "keyboard_shortcuts.up": "Displaciar in alto in le lista", "lightbox.close": "Clauder", + "lightbox.compress": "Comprimer le quadro de visualisation de imagine", + "lightbox.expand": "Expander le quadro de visualisation de imagine", "lightbox.next": "Sequente", "lightbox.previous": "Precedente", + "limited_account_hint.action": "Monstrar profilo in omne caso", + "limited_account_hint.title": "Iste profilo esseva celate per le moderatores de {domain}.", "link_preview.author": "Per {name}", "lists.account.add": "Adder al lista", - "lists.account.remove": "Remover ab le lista", + "lists.account.remove": "Remover del lista", "lists.delete": "Deler lista", "lists.edit": "Modificar lista", "lists.edit.submit": "Cambiar titulo", - "lists.exclusive": "Celar iste messages ab le initio", + "lists.exclusive": "Celar iste messages sur le pagina de initio", "lists.new.create": "Adder lista", "lists.new.title_placeholder": "Nove titulo del lista", + "lists.replies_policy.followed": "Qualcunque usator sequite", + "lists.replies_policy.list": "Membros del lista", "lists.replies_policy.none": "Nemo", "lists.replies_policy.title": "Monstrar responsas a:", + "lists.search": "Cercar inter le gente que tu seque", "lists.subheading": "Tu listas", + "load_pending": "{count, plural, one {# nove entrata} other {# nove entratas}}", "loading_indicator.label": "Cargante…", "media_gallery.toggle_visible": "{number, plural, one {Celar imagine} other {Celar imagines}}", - "navigation_bar.about": "A proposito de", - "navigation_bar.advanced_interface": "Aperir in un interfacie web avantiate", + "moved_to_account_banner.text": "Tu conto {disabledAccount} es actualmente disactivate perque tu ha cambiate de conto a {movedToAccount}.", + "mute_modal.hide_from_notifications": "Celar ab notificationes", + "mute_modal.hide_options": "Celar optiones", + "mute_modal.indefinite": "Usque io dissilentia iste persona", + "mute_modal.show_options": "Monstrar optiones", + "mute_modal.they_can_mention_and_follow": "Illes pote mentionar te e sequer te, ma tu non potera vider los.", + "mute_modal.they_wont_know": "Illes non sapera que illes ha essite silentiate.", + "mute_modal.title": "Silentiar le usator?", + "mute_modal.you_wont_see_mentions": "Tu non videra le messages que mentiona iste persona.", + "mute_modal.you_wont_see_posts": "Iste persona pote totevia vider tu messages, ma tu non videra le sues.", + "navigation_bar.about": "A proposito", + "navigation_bar.advanced_interface": "Aperir in le interfacie web avantiate", "navigation_bar.blocks": "Usatores blocate", "navigation_bar.bookmarks": "Marcapaginas", "navigation_bar.community_timeline": "Chronologia local", @@ -282,116 +449,351 @@ "navigation_bar.explore": "Explorar", "navigation_bar.favourites": "Favoritos", "navigation_bar.filters": "Parolas silentiate", + "navigation_bar.follow_requests": "Requestas de sequimento", + "navigation_bar.followed_tags": "Hashtags sequite", + "navigation_bar.follows_and_followers": "Sequites e sequitores", "navigation_bar.lists": "Listas", "navigation_bar.logout": "Clauder le session", "navigation_bar.mutes": "Usatores silentiate", "navigation_bar.opened_in_classic_interface": "Messages, contos e altere paginas specific es aperite per predefinition in le interfacie web classic.", "navigation_bar.personal": "Personal", + "navigation_bar.pins": "Messages fixate", "navigation_bar.preferences": "Preferentias", "navigation_bar.public_timeline": "Chronologia federate", "navigation_bar.search": "Cercar", "navigation_bar.security": "Securitate", - "notification.own_poll": "Tu inquesta finiva", - "notification.update": "{name} modificava un message", + "not_signed_in_indicator.not_signed_in": "Es necessari aperir session pro acceder a iste ressource.", + "notification.admin.report": "{name} ha signalate {target}", + "notification.admin.sign_up": "{name} se ha inscribite", + "notification.favourite": "{name} ha marcate tu message como favorite", + "notification.follow": "{name} te ha sequite", + "notification.follow_request": "{name} ha requestate de sequer te", + "notification.mention": "{name} te ha mentionate", + "notification.own_poll": "Tu sondage ha finite", + "notification.poll": "Un sondage in le qual tu ha votate ha finite", + "notification.reblog": "{name} ha impulsate tu message", + "notification.relationships_severance_event": "Connexiones perdite con {name}", + "notification.relationships_severance_event.account_suspension": "Un administrator de {from} ha suspendiute {target}. Isto significa que tu non pote plus reciper actualisationes de iste persona o interager con ille.", + "notification.relationships_severance_event.domain_block": "Un administrator de {from} ha blocate {target}, includente {followersCount} de tu sequitores e {followingCount, plural, one {# conto} other {# contos}} que tu seque.", + "notification.relationships_severance_event.learn_more": "Apprender plus", + "notification.relationships_severance_event.user_domain_block": "Tu ha blocate {target}, assi removente {followersCount} de tu sequitores e {followingCount, plural, one {# conto} other {# contos}} que tu seque.", + "notification.status": "{name} ha justo ora publicate", + "notification.update": "{name} ha modificate un message", + "notification_requests.accept": "Acceptar", + "notification_requests.dismiss": "Dimitter", + "notification_requests.notifications_from": "Notificationes de {name}", + "notification_requests.title": "Notificationes filtrate", "notifications.clear": "Rader notificationes", + "notifications.clear_confirmation": "Es tu secur que tu vole rader permanentemente tote tu notificationes?", + "notifications.column_settings.admin.report": "Nove signalationes:", + "notifications.column_settings.admin.sign_up": "Nove inscriptiones:", "notifications.column_settings.alert": "Notificationes de scriptorio", "notifications.column_settings.favourite": "Favoritos:", + "notifications.column_settings.filter_bar.advanced": "Monstrar tote le categorias", + "notifications.column_settings.filter_bar.category": "Barra de filtro rapide", "notifications.column_settings.follow": "Nove sequitores:", + "notifications.column_settings.follow_request": "Nove requestas de sequimento:", "notifications.column_settings.mention": "Mentiones:", - "notifications.column_settings.poll": "Resultatos del inquesta:", + "notifications.column_settings.poll": "Resultatos del sondage:", "notifications.column_settings.push": "Notificationes push", + "notifications.column_settings.reblog": "Impulsos:", "notifications.column_settings.show": "Monstrar in columna", "notifications.column_settings.sound": "Reproducer sono", "notifications.column_settings.status": "Nove messages:", "notifications.column_settings.unread_notifications.category": "Notificationes non legite", + "notifications.column_settings.unread_notifications.highlight": "Marcar le notificationes non legite", + "notifications.column_settings.update": "Modificationes:", "notifications.filter.all": "Toto", + "notifications.filter.boosts": "Impulsos", "notifications.filter.favourites": "Favoritos", + "notifications.filter.follows": "Sequites", "notifications.filter.mentions": "Mentiones", - "notifications.filter.polls": "Resultatos del inquesta", + "notifications.filter.polls": "Resultatos del sondage", "notifications.filter.statuses": "Actualisationes de personas que tu seque", "notifications.grant_permission": "Conceder permission.", "notifications.group": "{count} notificationes", + "notifications.mark_as_read": "Marcar cata notification como legite", + "notifications.permission_denied": "Le notificationes de scriptorio es indisponibile a causa de un requesta anteriormente refusate de permissiones del navigator", + "notifications.permission_denied_alert": "Le notificationes de scriptorio non pote esser activate perque le permission del navigator ha essite refusate anteriormente", + "notifications.permission_required": "Le notificationes de scriptorio es indisponibile perque le permission necessari non ha essite concedite.", + "notifications.policy.filter_new_accounts.hint": "Create in le ultime {days, plural, one {die} other {# dies}}", + "notifications.policy.filter_new_accounts_title": "Nove contos", + "notifications.policy.filter_not_followers_hint": "Includente le personas que te ha sequite durante minus de {days, plural, one {un die} other {# dies}}", + "notifications.policy.filter_not_followers_title": "Personas qui non te seque", + "notifications.policy.filter_not_following_hint": "Usque tu les approba manualmente", + "notifications.policy.filter_not_following_title": "Personas que tu non seque", + "notifications.policy.filter_private_mentions_hint": "Filtrate, excepte si es in responsa a tu proprie mention o si tu seque le expeditor", + "notifications.policy.filter_private_mentions_title": "Mentiones private indesirate", + "notifications.policy.title": "Filtrar notificationes de…", "notifications_permission_banner.enable": "Activar notificationes de scriptorio", + "notifications_permission_banner.how_to_control": "Pro reciper notificationes quando Mastodon non es aperte, activa le notificationes de scriptorio. Post lor activation, es possibile controlar precisemente qual typos de interaction genera notificationes de scriptorio per medio del button {icon} hic supra.", + "notifications_permission_banner.title": "Non mancar jammais a un cosa", + "onboarding.action.back": "Porta me retro", + "onboarding.actions.back": "Porta me retro", + "onboarding.actions.go_to_explore": "Porta me al tendentias", + "onboarding.actions.go_to_home": "Porta me a mi fluxo de initio", "onboarding.compose.template": "Salute #Mastodon!", + "onboarding.follows.empty": "Regrettabilemente, non es possibile monstrar resultatos al momento. Tu pote tentar usar le recerca o percurrer le pagina de exploration pro cercar personas a sequer, o tentar lo de novo plus tarde.", + "onboarding.follows.lead": "Le fluxo de initio es le maniera principal de discoperir Mastodon. Quanto plus personas tu seque, tanto plus active e interessante illo essera. Pro comenciar, ecce alcun suggestiones:", + "onboarding.follows.title": "Personalisar tu fluxo de initio", + "onboarding.profile.discoverable": "Render mi profilo discoperibile", + "onboarding.profile.discoverable_hint": "Quando tu opta pro devenir discoperibile sur Mastodon, tu messages pote apparer in resultatos de recerca e in tendentias, e tu profilo pote esser suggerite al personas con interesses simile al tues.", + "onboarding.profile.display_name": "Nomine a monstrar", + "onboarding.profile.display_name_hint": "Tu nomine complete o tu supernomine…", + "onboarding.profile.lead": "Tu pote sempre completar isto plus tarde in le parametros, ubi se trova mesmo plus optiones de personalisation.", + "onboarding.profile.note": "Bio", + "onboarding.profile.note_hint": "Tu pote @mentionar altere personas o #hashtags…", "onboarding.profile.save_and_continue": "Salvar e continuar", + "onboarding.profile.title": "Configuration del profilo", + "onboarding.profile.upload_avatar": "Incargar imagine de profilo", + "onboarding.profile.upload_header": "Actualisar capite de profilo", + "onboarding.share.lead": "Face saper al gente como illes pote trovar te sur Mastodon!", + "onboarding.share.message": "Io es {username} sur Mastodon! Veni sequer me a {url}", "onboarding.share.next_steps": "Sequente passos possibile:", "onboarding.share.title": "Compartir tu profilo", - "onboarding.steps.follow_people.title": "Personalisa tu fluxo de initio", + "onboarding.start.lead": "Tu face ora parte de Mastodon, un platteforma de medios social unic e decentralisate ubi es tu, e non un algorithmo, qui crea tu proprie experientia. Nos va adjutar te a lancear te in iste nove frontiera social:", + "onboarding.start.skip": "Non require adjuta a comenciar?", + "onboarding.start.title": "Tu ha arrivate!", + "onboarding.steps.follow_people.body": "Sequer personas interessante es le ration de esser de Mastodon.", + "onboarding.steps.follow_people.title": "Personalisar tu fluxo de initio", + "onboarding.steps.publish_status.body": "Saluta le mundo con texto, photos, videos o sondages {emoji}", "onboarding.steps.publish_status.title": "Face tu prime message", + "onboarding.steps.setup_profile.body": "Impulsa tu interactiones con un profilo comprehensive.", "onboarding.steps.setup_profile.title": "Personalisa tu profilo", + "onboarding.steps.share_profile.body": "Face saper a tu amicos como trovar te sur Mastodon", "onboarding.steps.share_profile.title": "Compartir tu profilo de Mastodon", + "onboarding.tips.2fa": "Lo sapeva tu? Tu pote securisar tu conto configurante le authentication bifactorial in le parametros de tu conto. Isto functiona con le application TOTP de tu preferentia, sin necessitate de un numero de telephono!", + "onboarding.tips.accounts_from_other_servers": "Lo sapeva tu? Perque Mastodon es decentralisate, le profilos que tu incontra pote esser hospitate sur servitores altere que le tue. Nonobstante, tu pote interager con illos sin problema! Lor servitor se trova in le secunde medietate de lor nomine de usator!", + "onboarding.tips.migration": "Lo sapeva tu? Si tu pensa que {domain} non es un bon servitor pro te in le futuro, tu pote cambiar a un altere servitor Mastodon sin perder tu sequitores. Tu pote mesmo hospitar tu proprie servitor!", + "onboarding.tips.verification": "Lo sapeva tu? Pro verificar tu conto, insere un ligamine a tu profilo Mastodon sur tu proprie sito web e adde le sito web a tu profilo. Nulle moneta o documentos necessari!", + "password_confirmation.exceeds_maxlength": "Le confirmation del contrasigno excede le longitude maxime del contrasigno", + "password_confirmation.mismatching": "Le confirmation del contrasigno non corresponde", + "picture_in_picture.restore": "Restaurar", "poll.closed": "Claudite", + "poll.refresh": "Refrescar", "poll.reveal": "Vider le resultatos", - "privacy.change": "Cambiar privacitate del message", + "poll.total_people": "{count, plural, one {# persona} other {# personas}}", + "poll.total_votes": "{count, plural, one {# voto} other {# votos}}", + "poll.vote": "Votar", + "poll.voted": "Tu ha votate pro iste responsa", + "poll.votes": "{votes, plural, one {# voto} other {# votos}}", + "poll_button.add_poll": "Adder un inquesta", + "poll_button.remove_poll": "Remover un inquesta", + "privacy.change": "Cambiar le confidentialitate del message", + "privacy.direct.long": "Tote le personas mentionate in le message", + "privacy.direct.short": "Personas specific", + "privacy.private.long": "Solmente tu sequitores", + "privacy.private.short": "Sequitores", + "privacy.public.long": "Quicunque, sur Mastodon o non", "privacy.public.short": "Public", + "privacy.unlisted.additional": "Isto es exactemente como public, excepte que le message non apparera in fluxos in directo, in hashtags, in Explorar, o in le recerca de Mastodon, mesmo si tu ha optate pro render tote le conto discoperibile.", + "privacy.unlisted.long": "Minus fanfares algorithmic", + "privacy.unlisted.short": "Public, non listate", "privacy_policy.last_updated": "Ultime actualisation {date}", "privacy_policy.title": "Politica de confidentialitate", + "recommended": "Recommendate", + "refresh": "Refrescar", + "regeneration_indicator.label": "Cargamento…", + "regeneration_indicator.sublabel": "Tu fluxo de initio es in preparation!", + "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# die} other {# dies}} retro", + "relative_time.full.hours": "{number, plural, one {# hora} other {# horas}} retro", + "relative_time.full.just_now": "justo ora", + "relative_time.full.minutes": "{number, plural, one {# minuta} other {# minutas}} retro", + "relative_time.full.seconds": "{number, plural, one {# secunda} other {# secundas}} retro", + "relative_time.hours": "{number}h", "relative_time.just_now": "ora", + "relative_time.minutes": "{number}m", + "relative_time.seconds": "{number}s", "relative_time.today": "hodie", + "reply_indicator.attachments": "{count, plural, one {# annexo} other {# annexos}}", "reply_indicator.cancel": "Cancellar", + "reply_indicator.poll": "Inquesta", "report.block": "Blocar", + "report.block_explanation": "Tu non videra le messages de iste persona. Ille non potera vider tu messages o sequer te. Ille potera saper de esser blocate.", + "report.categories.legal": "Juridic", "report.categories.other": "Alteres", + "report.categories.spam": "Spam", + "report.categories.violation": "Le contento viola un o plus regulas del servitor", + "report.category.subtitle": "Elige le option plus adequate", + "report.category.title": "Describe le problema con iste {type}", "report.category.title_account": "profilo", "report.category.title_status": "message", - "report.close": "Preste", + "report.close": "Facite", + "report.comment.title": "Ha il altere cosas que nos deberea saper?", + "report.forward": "Reinviar a {target}", + "report.forward_hint": "Le conto es de un altere servitor. Inviar un copia anonymisate del signalation a illo tamben?", "report.mute": "Silentiar", + "report.mute_explanation": "Tu non videra le messages de iste persona. Ille pote totevia sequer te e vider tu messages e non sapera de esser silentiate.", "report.next": "Sequente", "report.placeholder": "Commentos additional", "report.reasons.dislike": "Non me place", + "report.reasons.dislike_description": "Non es qualcosa que tu vole vider", + "report.reasons.legal": "Es illegal", + "report.reasons.legal_description": "Tu crede que viola le lege de tu pais o del pais del servitor", + "report.reasons.other": "Es altere cosa", + "report.reasons.other_description": "Le problema non entra in altere categorias", + "report.reasons.spam": "Es spam", + "report.reasons.spam_description": "Ligamines malevolente, interaction false, o responsas repetitive", + "report.reasons.violation": "Viola le regulas del servitor", + "report.reasons.violation_description": "Tu sape que viola regulas specific", + "report.rules.subtitle": "Selige tote le responsas appropriate", + "report.rules.title": "Qual regulas es violate?", + "report.statuses.subtitle": "Selige tote le responsas appropriate", + "report.statuses.title": "Existe alcun messages que appoia iste reporto?", + "report.submit": "Submitter", + "report.target": "Signalamento de {target}", + "report.thanks.take_action": "Ecce tu optiones pro controlar lo que tu vide sur Mastodon:", + "report.thanks.take_action_actionable": "Durante que nos revide isto, tu pote prender mesuras contra @{name}:", + "report.thanks.title": "Non vole vider isto?", + "report.thanks.title_actionable": "Gratias pro signalar, nos investigara isto.", + "report.unfollow": "Cessar de sequer @{name}", + "report.unfollow_explanation": "Tu seque iste conto. Pro non plus vider su messages in tu fluxo de initio, cessa de sequer lo.", + "report_notification.attached_statuses": "{count, plural, one {{count} message} other {{count} messages}} annexate", + "report_notification.categories.legal": "Juridic", "report_notification.categories.other": "Alteres", + "report_notification.categories.spam": "Spam", + "report_notification.categories.violation": "Violation del regulas", "report_notification.open": "Aperir reporto", "search.no_recent_searches": "Nulle recercas recente", + "search.placeholder": "Cercar", + "search.quick_action.account_search": "Profilos correspondente a {x}", "search.quick_action.go_to_account": "Vader al profilo {x}", "search.quick_action.go_to_hashtag": "Vader al hashtag {x}", "search.quick_action.open_url": "Aperir URL in Mastodon", + "search.quick_action.status_search": "Messages correspondente a {x}", + "search.search_or_paste": "Cerca o colla un URL", "search_popout.full_text_search_disabled_message": "Non disponibile sur {domain}.", + "search_popout.full_text_search_logged_out_message": "Solmente disponibile al initiar le session.", "search_popout.language_code": "Codice de lingua ISO", "search_popout.options": "Optiones de recerca", "search_popout.quick_actions": "Actiones rapide", "search_popout.recent": "Recercas recente", + "search_popout.specific_date": "data specific", "search_popout.user": "usator", "search_results.accounts": "Profilos", + "search_results.all": "Toto", "search_results.hashtags": "Hashtags", + "search_results.nothing_found": "Nihil trovate pro iste terminos de recerca", "search_results.see_all": "Vider toto", "search_results.statuses": "Messages", + "search_results.title": "Cercar {q}", + "server_banner.about_active_users": "Personas que ha usate iste servitor in le ultime 30 dies (usatores active per mense)", "server_banner.active_users": "usatores active", + "server_banner.administered_by": "Administrate per:", + "server_banner.introduction": "{domain} face parte del rete social decentralisate actionate per {mastodon}.", "server_banner.learn_more": "Apprender plus", "server_banner.server_stats": "Statos del servitor:", "sign_in_banner.create_account": "Crear un conto", - "sign_in_banner.sign_in": "Initiar le session", + "sign_in_banner.sign_in": "Aperir session", + "sign_in_banner.sso_redirect": "Aperir session o crear conto", + "sign_in_banner.text": "Aperi session pro sequer profilos o hashtags, marcar messages como favorite, e condivider e responder a messages. Tu pote etiam interager desde tu conto sur un altere servitor.", + "status.admin_account": "Aperir le interfacie de moderation pro @{name}", + "status.admin_domain": "Aperir le interfacie de moderation pro {domain}", + "status.admin_status": "Aperir iste message in le interfacie de moderation", "status.block": "Blocar @{name}", + "status.bookmark": "Adder al marcapaginas", + "status.cancel_reblog_private": "Disfacer impulso", + "status.cannot_reblog": "Iste message non pote esser impulsate", "status.copy": "Copiar ligamine a message", "status.delete": "Deler", - "status.direct": "Mentionar privatemente a @{name}", + "status.detailed_status": "Vista detaliate del conversation", + "status.direct": "Mentionar privatemente @{name}", "status.direct_indicator": "Mention private", "status.edit": "Modificar", - "status.edited_x_times": "Modificate {count, plural, one {{count} tempore} other {{count} tempores}}", + "status.edited": "Ultime modification le {date}", + "status.edited_x_times": "Modificate {count, plural, one {{count} vice} other {{count} vices}}", + "status.embed": "Incastrar", "status.favourite": "Adder al favoritos", + "status.favourites": "{count, plural, one {favorite} other {favorites}}", "status.filter": "Filtrar iste message", + "status.filtered": "Filtrate", "status.hide": "Celar le message", "status.history.created": "create per {name} le {date}", "status.history.edited": "modificate per {name} le {date}", + "status.load_more": "Cargar plus", "status.media.open": "Clicca pro aperir", "status.media.show": "Clicca pro monstrar", + "status.media_hidden": "Medios celate", + "status.mention": "Mentionar @{name}", "status.more": "Plus", + "status.mute": "Silentiar @{name}", "status.mute_conversation": "Silentiar conversation", + "status.open": "Expander iste message", + "status.pin": "Fixar sur profilo", + "status.pinned": "Message fixate", "status.read_more": "Leger plus", + "status.reblog": "Impulsar", + "status.reblog_private": "Impulsar con visibilitate original", + "status.reblogged_by": "Impulsate per {name}", + "status.reblogs": "{count, plural, one {impulso} other {impulsos}}", + "status.reblogs.empty": "Necuno ha ancora impulsate iste message. Quando alcuno lo face, le impulsos apparera hic.", + "status.redraft": "Deler e reconciper", + "status.remove_bookmark": "Remover marcapagina", + "status.replied_to": "Respondite a {name}", + "status.reply": "Responder", + "status.replyAll": "Responder al discussion", + "status.report": "Signalar @{name}", + "status.sensitive_warning": "Contento sensibile", "status.share": "Compartir", + "status.show_filter_reason": "Monstrar in omne caso", "status.show_less": "Monstrar minus", + "status.show_less_all": "Monstrar minus pro totes", "status.show_more": "Monstrar plus", + "status.show_more_all": "Monstrar plus pro totes", + "status.show_original": "Monstrar original", + "status.title.with_attachments": "{user} ha publicate {attachmentCount, plural, one {un annexo} other {{attachmentCount} annexos}}", "status.translate": "Traducer", "status.translated_from_with": "Traducite ab {lang} usante {provider}", "status.uncached_media_warning": "Previsualisation non disponibile", + "status.unmute_conversation": "Non plus silentiar conversation", + "status.unpin": "Disfixar del profilo", + "subscribed_languages.lead": "Solmente le messages in le linguas seligite apparera in tu chronologias de initio e de listas post le cambiamento. Selige necun pro reciper messages in tote le linguas.", "subscribed_languages.save": "Salveguardar le cambiamentos", + "subscribed_languages.target": "Cambiar le linguas subscribite pro {target}", "tabs_bar.home": "Initio", "tabs_bar.notifications": "Notificationes", + "time_remaining.days": "{number, plural, one {# die} other {# dies}} restante", + "time_remaining.hours": "{number, plural, one {# hora} other {# horas}} restante", + "time_remaining.minutes": "{number, plural, one {# minuta} other {# minutas}} restante", + "time_remaining.moments": "Qualque momentos restante", + "time_remaining.seconds": "{number, plural, one {# secunda} other {# secundas}} restante", + "timeline_hint.remote_resource_not_displayed": "Le {resource} de altere servitores non appare hic.", + "timeline_hint.resources.followers": "Sequitores", + "timeline_hint.resources.follows": "Sequites", "timeline_hint.resources.statuses": "Messages ancian", + "trends.counter_by_accounts": "{count, plural, one {{counter} persona} other {{counter} personas}} in le passate {days, plural, one {die} other {{days} dies}}", "trends.trending_now": "Ora in tendentias", + "ui.beforeunload": "Tu esbosso essera predite si tu exi de Mastodon.", + "units.short.billion": "{count}B", + "units.short.million": "{count}M", + "units.short.thousand": "{count}K", + "upload_area.title": "Traher e deponer pro incargar", "upload_button.label": "Adde imagines, un video o un file de audio", + "upload_error.limit": "Limite de incargamento de files excedite.", + "upload_error.poll": "Incargamento de files non permittite con sondages.", + "upload_form.audio_description": "Describe lo pro le gente con difficultates auditive", + "upload_form.description": "Describe lo pro le gente con difficultates visual", + "upload_form.edit": "Modificar", + "upload_form.thumbnail": "Cambiar le miniatura", + "upload_form.video_description": "Describe lo pro le gente con difficultates auditive o visual", + "upload_modal.analyzing_picture": "Analysa imagine…", + "upload_modal.apply": "Applicar", + "upload_modal.applying": "Applicante…", "upload_modal.choose_image": "Seliger un imagine", - "upload_modal.detect_text": "Deteger texto ab un pictura", + "upload_modal.description_placeholder": "Cinque expertos del zoo jam bibeva whisky frigide", + "upload_modal.detect_text": "Deteger texto de un imagine", + "upload_modal.edit_media": "Modificar le medio", + "upload_modal.hint": "Clicca o trahe le circulo sur le previsualisation pro eliger le puncto focal que essera sempre visibile sur tote le miniaturas.", + "upload_modal.preparing_ocr": "Preparation del OCR…", + "upload_modal.preview_label": "Previsualisation ({ratio})", + "upload_progress.label": "Incargante...", + "upload_progress.processing": "Processante…", + "username.taken": "Iste nomine de usator es ja in uso. Proba con un altere", "video.close": "Clauder le video", "video.download": "Discargar le file", + "video.exit_fullscreen": "Sortir del schermo plen", + "video.expand": "Expander video", "video.fullscreen": "Schermo plen", "video.hide": "Celar video", "video.mute": "Silentiar le sono", diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json index 764c08111..33161f888 100644 --- a/app/javascript/mastodon/locales/id.json +++ b/app/javascript/mastodon/locales/id.json @@ -21,6 +21,7 @@ "account.blocked": "Terblokir", "account.browse_more_on_origin_server": "Lihat lebih lanjut di profil asli", "account.cancel_follow_request": "Batalkan permintaan ikut", + "account.copy": "Salin tautan ke profil", "account.direct": "Sebut secara pribadi @{name}", "account.disable_notifications": "Berhenti memberitahu saya ketika @{name} memposting", "account.domain_blocked": "Domain diblokir", @@ -31,6 +32,7 @@ "account.featured_tags.last_status_never": "Tidak ada kiriman", "account.featured_tags.title": "Tagar {name} yang difiturkan", "account.follow": "Ikuti", + "account.follow_back": "Ikuti balik", "account.followers": "Pengikut", "account.followers.empty": "Pengguna ini belum ada pengikut.", "account.followers_counter": "{count, plural, other {{counter} Pengikut}}", @@ -51,6 +53,7 @@ "account.mute_notifications_short": "Senyapkan Notifikasi", "account.mute_short": "Senyapkan", "account.muted": "Dibisukan", + "account.mutual": "Saling ikuti", "account.no_bio": "Tidak ada deskripsi yang diberikan.", "account.open_original_page": "Buka halaman asli", "account.posts": "Kiriman", @@ -75,6 +78,10 @@ "admin.dashboard.retention.average": "Rata-rata", "admin.dashboard.retention.cohort": "Bulan pendaftaran", "admin.dashboard.retention.cohort_size": "Pengguna baru", + "admin.impact_report.instance_accounts": "Akun profil yang akan terhapus", + "admin.impact_report.instance_followers": "Pengikut yang akan kehilangan oleh pengguna kita", + "admin.impact_report.instance_follows": "Pengikut yang akan kehilangan oleh pengguna lain", + "admin.impact_report.title": "Ringkasan dampak", "alert.rate_limited.message": "Mohon ulangi setelah {retry_time, time, medium}.", "alert.rate_limited.title": "Jumlah akses dibatasi", "alert.unexpected.message": "Terjadi kesalahan yang tidak terduga.", @@ -82,6 +89,14 @@ "announcement.announcement": "Pengumuman", "attachments_list.unprocessed": "(tidak diproses)", "audio.hide": "Sembunyikan audio", + "block_modal.remote_users_caveat": "Kami akan meminta {domain} server untuk menghargai keputusan Anda. Namun, kepatuhan tak dapat dipastikan karena beberapa server dapat menangani blokir secara beragam. Postingan publik masih dapat terlihat oleh pengguna tanpa masuk.", + "block_modal.show_less": "Tampilkan lebih sedikit", + "block_modal.show_more": "Tampilkan lebih banyak", + "block_modal.they_cant_mention": "Mereka tidak dapat menyebut atau mengikuti Anda.", + "block_modal.they_cant_see_posts": "Mereka tidak dapat melihat postingan Anda dan Anda tidak dapat melihat postingan mereka.", + "block_modal.they_will_know": "Mereka dapat melihat bahwa mereka diblokir.", + "block_modal.title": "Blokir pengguna?", + "block_modal.you_wont_see_mentions": "Anda tidak akan melihat kiriman yang menyebutkan mereka.", "boost_modal.combo": "Anda dapat menekan {combo} untuk melewati ini", "bundle_column_error.copy_stacktrace": "Salin laporan kesalahan", "bundle_column_error.error.body": "Laman yang diminta tidak dapat ditampilkan. Mungkin karena sebuah kutu dalam kode kami, atau masalah kompatibilitas peramban.", @@ -104,8 +119,11 @@ "column.blocks": "Pengguna yang diblokir", "column.bookmarks": "Markah", "column.community": "Linimasa Lokal", + "column.direct": "Sebut secara pribadi", "column.directory": "Jelajahi profil", "column.domain_blocks": "Domain tersembunyi", + "column.favourites": "Favorit", + "column.firehose": "Feed yang sedang berlangsung", "column.follow_requests": "Permintaan mengikuti", "column.home": "Beranda", "column.lists": "List", @@ -126,7 +144,9 @@ "community.column_settings.remote_only": "Hanya jarak jauh", "compose.language.change": "Ganti bahasa", "compose.language.search": "Telusuri bahasa...", + "compose.published.body": "Postingan diterbitkan.", "compose.published.open": "Buka", + "compose.saved.body": "Postingan tersimpan.", "compose_form.direct_message_warning_learn_more": "Pelajari lebih lanjut", "compose_form.encryption_warning": "Kiriman di Mastodon tidak dienkripsi secara end-to-end. Jangan bagikan informasi sensitif melalui Mastodon.", "compose_form.hashtag_warning": "Kiriman ini tidak akan didaftarkan di bawah tagar apapun selama tidak diatur ke publik. Hanya kiriman publik yang dapat dicari dengan tagar.", @@ -134,11 +154,19 @@ "compose_form.lock_disclaimer.lock": "terkunci", "compose_form.placeholder": "Apa yang ada di pikiran Anda?", "compose_form.poll.duration": "Durasi japat", + "compose_form.poll.multiple": "Pilihan ganda", + "compose_form.poll.option_placeholder": "Opsi {number}", + "compose_form.poll.single": "Pilih Satu", "compose_form.poll.switch_to_multiple": "Ubah japat menjadi pilihan ganda", "compose_form.poll.switch_to_single": "Ubah japat menjadi pilihan tunggal", + "compose_form.poll.type": "Gaya", + "compose_form.publish": "Postingan", "compose_form.publish_form": "Terbitkan", + "compose_form.reply": "Balas", + "compose_form.save_changes": "Perbarui", "compose_form.spoiler.marked": "Hapus peringatan tentang isi konten", "compose_form.spoiler.unmarked": "Tambahkan peringatan tentang isi konten", + "compose_form.spoiler_placeholder": "Peringatan konten (opsional)", "confirmation_modal.cancel": "Batal", "confirmations.block.confirm": "Blokir", "confirmations.cancel_follow_request.confirm": "Batalkan permintaan", @@ -149,12 +177,15 @@ "confirmations.delete_list.message": "Apakah Anda yakin untuk menghapus daftar ini secara permanen?", "confirmations.discard_edit_media.confirm": "Buang", "confirmations.discard_edit_media.message": "Anda belum menyimpan perubahan deskripsi atau pratinjau media, buang saja?", + "confirmations.domain_block.confirm": "Blokir server", "confirmations.domain_block.message": "Apakah Anda benar-benar yakin untuk memblokir keseluruhan {domain}? Dalam kasus tertentu beberapa pemblokiran atau penyembunyian lebih baik.", "confirmations.edit.confirm": "Ubah", + "confirmations.edit.message": "Mengubah akan menimpa pesan yang sedang anda tulis. Apakah anda yakin ingin melanjutkan?", "confirmations.logout.confirm": "Keluar", "confirmations.logout.message": "Apakah Anda yakin ingin keluar?", "confirmations.mute.confirm": "Bisukan", "confirmations.redraft.confirm": "Hapus dan susun ulang", + "confirmations.redraft.message": "Apakah anda yakin ingin menghapus postingan ini dan menyusun ulang postingan ini? Favorit dan peningkatan akan hilang, dan balasan ke postingan asli tidak akan terhubung ke postingan manapun.", "confirmations.reply.confirm": "Balas", "confirmations.reply.message": "Membalas sekarang akan menimpa pesan yang sedang Anda buat. Anda yakin ingin melanjutkan?", "confirmations.unfollow.confirm": "Berhenti mengikuti", @@ -163,6 +194,7 @@ "conversation.mark_as_read": "Tandai sudah dibaca", "conversation.open": "Lihat percakapan", "conversation.with": "Dengan {names}", + "copy_icon_button.copied": "Disalin ke clipboard", "copypaste.copied": "Disalin", "copypaste.copy_to_clipboard": "Salin ke clipboard", "directory.federated": "Dari fediverse yang dikenal", @@ -174,7 +206,27 @@ "dismissable_banner.community_timeline": "Ini adalah kiriman publik terkini dari orang yang akunnya berada di {domain}.", "dismissable_banner.dismiss": "Abaikan", "dismissable_banner.explore_links": "Cerita berita ini sekarang sedang dibicarakan oleh orang di server ini dan lainnya dalam jaringan terdesentralisasi.", + "dismissable_banner.explore_statuses": "Ini adalah postingan dari seluruh web sosial yang mendapatkan daya tarik saat ini. Postingan baru dengan lebih banyak peningkatan dan favorit memiliki peringkat lebih tinggi.", "dismissable_banner.explore_tags": "Tagar ini sekarang sedang tren di antara orang di server ini dan lainnya dalam jaringan terdesentralisasi.", + "dismissable_banner.public_timeline": "Ini adalah postingan publik dari orang-orang di web sosial yang diikuti oleh {domain}.", + "domain_block_modal.block": "Blokir server", + "domain_block_modal.block_account_instead": "Blokir @{name} saja", + "domain_block_modal.they_can_interact_with_old_posts": "Orang-orang dari server ini dapat berinteraksi dengan kiriman lama anda.", + "domain_block_modal.they_cant_follow": "Tidak ada seorangpun dari server ini yang dapat mengikuti anda.", + "domain_block_modal.they_wont_know": "Mereka tidak akan tahu bahwa mereka diblokir.", + "domain_block_modal.title": "Blokir domain?", + "domain_block_modal.you_will_lose_followers": "Semua pengikut anda dari server ini akan dihapus.", + "domain_block_modal.you_wont_see_posts": "Anda tidak akan melihat postingan atau notifikasi dari pengguna di server ini.", + "domain_pill.activitypub_lets_connect": "Ini memungkinkan anda terhubung dan berinteraksi dengan orang-orang tidak hanya di Mastodon, tetapi juga di berbagai aplikasi sosial.", + "domain_pill.activitypub_like_language": "ActivityPub seperti bahasa yang digunakan Mastodon dengan jejaring sosial lainnya.", + "domain_pill.server": "Server", + "domain_pill.their_handle": "Nama penggunanya:", + "domain_pill.their_server": "Rumah digital mereka, di mana semua postingan mereka tersedia.", + "domain_pill.their_username": "Pengenal unik mereka di server tersebut. Itu memungkinkan dapat mencari pengguna dengan nama yang sama di server lain.", + "domain_pill.username": "Nama pengguna", + "domain_pill.whats_in_a_handle": "Apa itu nama pengguna?", + "domain_pill.who_they_are": "Karena nama pengguna menunjukkan siapa seseorang dan di mana server mereka berada, anda dapat berinteraksi dengan orang-orang di seluruh web sosial .", + "domain_pill.your_handle": "Nama pengguna anda:", "embed.instructions": "Sematkan kiriman ini di situs web Anda dengan menyalin kode di bawah ini.", "embed.preview": "Tampilan akan seperti ini nantinya:", "emoji_button.activity": "Aktivitas", @@ -243,6 +295,10 @@ "follow_request.authorize": "Izinkan", "follow_request.reject": "Tolak", "follow_requests.unlocked_explanation": "Meskipun akun Anda tidak dikunci, staf {domain} menyarankan Anda untuk meninjau permintaan mengikuti dari akun-akun ini secara manual.", + "follow_suggestions.curated_suggestion": "Pilihan staf", + "follow_suggestions.dismiss": "Jangan tampilkan lagi", + "follow_suggestions.hints.featured": "Profil ini telah dipilih sendiri oleh tim {domain}.", + "follow_suggestions.hints.friends_of_friends": "Profil ini populer di kalangan orang yang anda ikuti.", "followed_tags": "Tagar yang diikuti", "footer.about": "Tentang", "footer.directory": "Direktori profil", diff --git a/app/javascript/mastodon/locales/ie.json b/app/javascript/mastodon/locales/ie.json index 17f312418..8d491412c 100644 --- a/app/javascript/mastodon/locales/ie.json +++ b/app/javascript/mastodon/locales/ie.json @@ -91,6 +91,9 @@ "audio.hide": "Celar audio", "block_modal.show_less": "Monstrar minu", "block_modal.show_more": "Monstrar plu", + "block_modal.they_cant_mention": "Ne posse mentionar ni sequer te.", + "block_modal.they_cant_see_posts": "Ne posse vider tui postas e inversi.", + "block_modal.they_will_know": "Va esser conscient que tu ha bloccat.", "block_modal.title": "Bloccar usator?", "block_modal.you_wont_see_mentions": "Tu ne va vider postas mentionant li usator.", "boost_modal.combo": "Li proxim vez tu posse pressar {combo} por passar to-ci", @@ -206,6 +209,16 @@ "dismissable_banner.explore_tags": "Tis-ci es hashtags queles es popular che li social retage hodie. Hashtags usat de plu mult persones diferent es monstrat plu alt.", "dismissable_banner.public_timeline": "Tis-ci es li max recent public postas de persones che li social retage quem gente che {domain} seque.", "domain_block_modal.block": "Bloccar servitor", + "domain_block_modal.block_account_instead": "Altrimen, bloccar @{name}", + "domain_block_modal.they_can_interact_with_old_posts": "Persones de ti servitor posse interacter con tui old postas.", + "domain_block_modal.they_cant_follow": "Nequi de ti-ci servitor posse sequer te.", + "domain_pill.activitypub_like_language": "ActivityPub es li lingue usat de Mastodon por parlar con altri social retages.", + "domain_pill.server": "Servitor", + "domain_pill.their_handle": "Identificator:", + "domain_pill.their_server": "Su digital hem e omni su postas.", + "domain_pill.username": "Usator-nómine", + "domain_pill.whats_in_a_handle": "Ex quo consiste un identificator?", + "domain_pill.your_handle": "Tui identificator:", "embed.instructions": "Inbedar ti-ci posta per copiar li code in infra.", "embed.preview": "Vi qualmen it va aspecter:", "emoji_button.activity": "Activitá", @@ -242,6 +255,7 @@ "empty_column.list": "Ancor ne hay quocunc in ti-ci liste. Quande membres de ti-ci liste publica nov postas, ili va aparir ci.", "empty_column.lists": "Tu ancor have null listes. Quande tu crea un, it va aparir ci.", "empty_column.mutes": "Tu ancor ha silentiat null usatores.", + "empty_column.notification_requests": "Omnicos clar! Hay necos ci. Nov notificationes va venir ci quande tu recive les secun tui parametres.", "empty_column.notifications": "Tu have null notificationes. Quande altri persones interacte con te, tu va vider it ci.", "empty_column.public": "Hay nullcos ci! Scri alquo publicmen, o manualmen seque usatores de altri servitores por plenar to-ci", "error.unexpected_crash.explanation": "Pro un error in nor code o un problema de compatibilitá in li navigator, ti-ci págine ne posset esser monstrat correctmen.", @@ -272,6 +286,8 @@ "filter_modal.select_filter.subtitle": "Usar un existent categorie o crear nov", "filter_modal.select_filter.title": "Filtrar ti-ci posta", "filter_modal.title.status": "Filtrar un posta", + "filtered_notifications_banner.pending_requests": "Notificationes de {count, plural, =0 {nequi} one {un person} other {# persones}} quel tu possibilmen conosse", + "filtered_notifications_banner.title": "Filtrat notificationes", "firehose.all": "Omno", "firehose.local": "Ti-ci servitor", "firehose.remote": "Altri servitores", @@ -400,6 +416,13 @@ "loading_indicator.label": "Cargant…", "media_gallery.toggle_visible": "{number, plural, one {Celar image} other {Celar images}}", "moved_to_account_banner.text": "Tui conto {disabledAccount} es actualmen desactivisat pro que tu movet te a {movedToAccount}.", + "mute_modal.hide_from_notifications": "Celar de notificationes", + "mute_modal.hide_options": "Celar optiones", + "mute_modal.indefinite": "Til quande yo dessilentia li usator", + "mute_modal.show_options": "Monstrar optiones", + "mute_modal.they_can_mention_and_follow": "Posse mentionar e sequer te, ma va esser ínvisibil a te.", + "mute_modal.they_wont_know": "Ne va esser conscient pri li silentation.", + "mute_modal.title": "Silentiar usator?", "navigation_bar.about": "Information", "navigation_bar.advanced_interface": "Aperter in li web-interfacie avansat", "navigation_bar.blocks": "Bloccat usatores", @@ -435,14 +458,20 @@ "notification.own_poll": "Tui balotation ha finit", "notification.poll": "Un balotation in quel tu votat ha finit", "notification.reblog": "{name} boostat tui posta", + "notification.relationships_severance_event.learn_more": "Aprender plu", "notification.status": "{name} just postat", "notification.update": "{name} modificat un posta", + "notification_requests.accept": "Acceptar", + "notification_requests.dismiss": "Demisser", + "notification_requests.notifications_from": "Notificationes de {name}", + "notification_requests.title": "Filtrat notificationes", "notifications.clear": "Aclarar notificationes", "notifications.clear_confirmation": "Vole tu vermen permanentmen aclarar omni tui notificationes?", "notifications.column_settings.admin.report": "Nov raportas:", "notifications.column_settings.admin.sign_up": "Nov registrationes:", "notifications.column_settings.alert": "Notificationes sur li computator", "notifications.column_settings.favourite": "Favorites:", + "notifications.column_settings.filter_bar.advanced": "Monstrar omni categories", "notifications.column_settings.follow": "Nov sequitores:", "notifications.column_settings.follow_request": "Nov petitiones de sequer:", "notifications.column_settings.mention": "Mentiones:", @@ -468,6 +497,15 @@ "notifications.permission_denied": "Notificationes sur li computator es índisponibil pro que on ha previamen rejectet un petition por navigator-permissiones", "notifications.permission_denied_alert": "Notificationes sur li computator ne posse esser activisat, pro que navigator-permission ha esset previamen rejectet", "notifications.permission_required": "Notificationes sur li computator es índisponibil pro que li besonat permission ne ha esset dat.", + "notifications.policy.filter_new_accounts.hint": "Creat durant li passat {days, plural, one {un die} other {# dies}}", + "notifications.policy.filter_new_accounts_title": "Nov contos", + "notifications.policy.filter_not_followers_hint": "Includente tis qui ha sequet te minu quam {days, plural, one {un die} other {# dies}}", + "notifications.policy.filter_not_followers_title": "Persones qui ne seque te", + "notifications.policy.filter_not_following_hint": "Til quande tu manualmen aproba", + "notifications.policy.filter_not_following_title": "Persones queles tu ne seque", + "notifications.policy.filter_private_mentions_hint": "Filtrat except si it es un response a tui propri mention o si tu seque li missor", + "notifications.policy.filter_private_mentions_title": "Ínsolicitat privat mentiones", + "notifications.policy.title": "Filtrar notificationes de…", "notifications_permission_banner.enable": "Activisar notificationes sur li computator", "notifications_permission_banner.how_to_control": "Por reciver notificationes quande Mastodon ne es apert, activisa notificationes sur li computator. Tu posse decider precisimen quel species de interactiones genera notificationes per li buton {icon} in-supra quande ili es activisat.", "notifications_permission_banner.title": "Nequande preterlassa quocunc", @@ -644,9 +682,11 @@ "status.direct": "Privatmen mentionar @{name}", "status.direct_indicator": "Privat mention", "status.edit": "Modificar", + "status.edited": "Ultimmen actualisat ye {date}", "status.edited_x_times": "Modificat {count, plural, one {{count} vez} other {{count} vezes}}", "status.embed": "Inbedar", "status.favourite": "Favoritisar", + "status.favourites": "{count, plural, one {favorit} other {favorites}}", "status.filter": "Filtrar ti-ci posta", "status.filtered": "Filtrat", "status.hide": "Celar posta", diff --git a/app/javascript/mastodon/locales/ig.json b/app/javascript/mastodon/locales/ig.json index a9b300fa4..90253743f 100644 --- a/app/javascript/mastodon/locales/ig.json +++ b/app/javascript/mastodon/locales/ig.json @@ -20,6 +20,7 @@ "column.bookmarks": "Ebenrụtụakā", "column.home": "Be", "column.lists": "Ndepụta", + "column.notifications": "Nziọkwà", "column.pins": "Pinned post", "column_header.pin": "Gbado na profaịlụ gị", "column_subheading.settings": "Mwube", @@ -42,17 +43,28 @@ "confirmations.reply.confirm": "Zaa", "confirmations.unfollow.confirm": "Kwụsị iso", "conversation.delete": "Hichapụ nkata", + "disabled_account_banner.account_settings": "Mwube akaụntụ", "dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.", "dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.", + "domain_pill.username": "Ahaojiaru", "embed.instructions": "Embed this status on your website by copying the code below.", + "emoji_button.activity": "Mmemme", + "emoji_button.label": "Tibanye emoji", "emoji_button.search": "Chọọ...", + "emoji_button.symbols": "Ọdịmara", "empty_column.account_timeline": "No posts found", "empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}", "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.", "errors.unexpected_crash.report_issue": "Kpesa nsogbu", + "explore.trending_links": "Akụkọ", + "firehose.all": "Ha niine", + "follow_request.authorize": "Nye ikike", "footer.privacy_policy": "Iwu nzuzu", "getting_started.heading": "Mbido", "hashtag.column_settings.tag_toggle": "Include additional tags in this column", + "home.column_settings.show_replies": "Gosi nzaghachị", + "home.hide_announcements": "Zoo ọkwa", + "home.show_announcements": "Gosi ọkwa", "keyboard_shortcuts.back": "to navigate back", "keyboard_shortcuts.blocked": "to open blocked users list", "keyboard_shortcuts.boost": "to boost", diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json index d050aa031..f5bf7c328 100644 --- a/app/javascript/mastodon/locales/is.json +++ b/app/javascript/mastodon/locales/is.json @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Notaðu fyrirliggjandi flokk eða útbúðu nýjan", "filter_modal.select_filter.title": "Sía þessa færslu", "filter_modal.title.status": "Sía færslu", + "filtered_notifications_banner.mentions": "{count, plural, one {tilvísun} other {tilvísanir}}", "filtered_notifications_banner.pending_requests": "Tilkynningar frá {count, plural, =0 {engum} one {einum aðila} other {# aðilum}} sem þú gætir þekkt", "filtered_notifications_banner.title": "Síaðar tilkynningar", "firehose.all": "Allt", @@ -307,6 +308,8 @@ "follow_requests.unlocked_explanation": "Jafnvel þótt aðgangurinn þinn sé ekki læstur, hafa umsjónarmenn {domain} ímyndað sér að þú gætir viljað yfirfara handvirkt fylgjendabeiðnir frá þessum notendum.", "follow_suggestions.curated_suggestion": "Úrval starfsfólks", "follow_suggestions.dismiss": "Ekki birta þetta aftur", + "follow_suggestions.featured_longer": "Handvalið af {domain}-teyminu", + "follow_suggestions.friends_of_friends_longer": "Vinsælt hjá fólki sem þú fylgist með", "follow_suggestions.hints.featured": "Þetta notandasnið hefur verið handvalið af {domain}-teyminu.", "follow_suggestions.hints.friends_of_friends": "Þetta notandasnið er vinsælt hjá fólki sem þú fylgist með.", "follow_suggestions.hints.most_followed": "Þetta notandasnið er eitt af þeim sem mest er fylgst með á {domain}.", @@ -314,6 +317,8 @@ "follow_suggestions.hints.similar_to_recently_followed": "Þetta notandasnið er líkt þeim sniðum sem þú hefur valið að fylgjast með að undanförnu.", "follow_suggestions.personalized_suggestion": "Persónuaðlöguð tillaga", "follow_suggestions.popular_suggestion": "Vinsæl tillaga", + "follow_suggestions.popular_suggestion_longer": "Vinsælt á {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Svipar til notenda sem þú hefur nýlega farið að fylgjast með", "follow_suggestions.view_all": "Skoða allt", "follow_suggestions.who_to_follow": "Hverjum á að fylgjast með", "followed_tags": "Myllumerki sem fylgst er með", @@ -468,9 +473,23 @@ "notification.follow": "{name} fylgist með þér", "notification.follow_request": "{name} hefur beðið um að fylgjast með þér", "notification.mention": "{name} minntist á þig", + "notification.moderation-warning.learn_more": "Kanna nánar", + "notification.moderation_warning": "Þú hefur fengið aðvörun frá umsjónarmanni", + "notification.moderation_warning.action_delete_statuses": "Sumar færslurnar þínar hafa verið fjarlægðar.", + "notification.moderation_warning.action_disable": "Aðgangurinn þinn hefur verið gerður óvirkur.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Sumar færslurnar þínar hafa verið merktar sem viðkvæmt efni.", + "notification.moderation_warning.action_none": "Aðgangurinn þinn hefur fengið aðvörun frá umsjónarmanni.", + "notification.moderation_warning.action_sensitive": "Færslur þínar á verða héðan í frá merktar sem viðkvæmar.", + "notification.moderation_warning.action_silence": "Notandaaðgangurinn þinn hefur verið takmarkaður.", + "notification.moderation_warning.action_suspend": "Notandaaðgangurinn þinn hefur verið settur í frysti.", "notification.own_poll": "Könnuninni þinni er lokið", "notification.poll": "Könnun sem þú tókst þátt í er lokið", "notification.reblog": "{name} endurbirti færsluna þína", + "notification.relationships_severance_event": "Missti tengingar við {name}", + "notification.relationships_severance_event.account_suspension": "Stjórnandi á {from} hefur fryst {target}, sem þýðir að þú færð ekki lengur skilaboð frá viðkomandi né átt í samskiptum við viðkomandi.", + "notification.relationships_severance_event.domain_block": "Stjórnandi á {from} hefur lokað á {target} og þar með {followersCount} fylgjendur þína auk {followingCount, plural, one {# aðgangs} other {# aðganga}} sem þú fylgist með.", + "notification.relationships_severance_event.learn_more": "Kanna nánar", + "notification.relationships_severance_event.user_domain_block": "Þú hefur lokað á {target} og þar með fjarlægt {followersCount} fylgjendur þína auk {followingCount, plural, one {# aðgangs} other {# aðganga}} sem þú fylgist með.", "notification.status": "{name} sendi inn rétt í þessu", "notification.update": "{name} breytti færslu", "notification_requests.accept": "Samþykkja", @@ -483,6 +502,8 @@ "notifications.column_settings.admin.sign_up": "Nýjar skráningar:", "notifications.column_settings.alert": "Tilkynningar á skjáborði", "notifications.column_settings.favourite": "Eftirlæti:", + "notifications.column_settings.filter_bar.advanced": "Birta alla flokka", + "notifications.column_settings.filter_bar.category": "Skyndisíustika", "notifications.column_settings.follow": "Nýir fylgjendur:", "notifications.column_settings.follow_request": "Nýjar beiðnir um að fylgjast með:", "notifications.column_settings.mention": "Tilvísanir:", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index 7d5df9198..8ab5db1b1 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -83,7 +83,7 @@ "admin.impact_report.instance_follows": "I seguaci che i loro utenti perderebbero", "admin.impact_report.title": "Riepilogo dell'impatto", "alert.rate_limited.message": "Sei pregato di riprovare dopo le {retry_time, time, medium}.", - "alert.rate_limited.title": "Tasso limitato", + "alert.rate_limited.title": "Limitazione per eccesso di richieste", "alert.unexpected.message": "Si è verificato un errore imprevisto.", "alert.unexpected.title": "Oops!", "announcement.announcement": "Annuncio", @@ -174,7 +174,7 @@ "confirmations.delete.confirm": "Elimina", "confirmations.delete.message": "Sei sicuro di voler eliminare questo post?", "confirmations.delete_list.confirm": "Elimina", - "confirmations.delete_list.message": "Sei sicuro di voler eliminare permanentemente questa lista?", + "confirmations.delete_list.message": "Sei sicuro/a di voler eliminare permanentemente questo elenco?", "confirmations.discard_edit_media.confirm": "Scarta", "confirmations.discard_edit_media.message": "Hai delle modifiche non salvate alla descrizione o anteprima del media, scartarle comunque?", "confirmations.domain_block.confirm": "Blocca il server", @@ -263,8 +263,8 @@ "empty_column.followed_tags": "Non hai ancora seguito alcun hashtag. Quando lo farai, appariranno qui.", "empty_column.hashtag": "Non c'è ancora nulla in questo hashtag.", "empty_column.home": "La cronologia della tua home è vuota! Segui altre persone per riempirla. {suggestions}", - "empty_column.list": "Non c'è ancora nulla in questa lista. Quando i membri di questa lista pubblicheranno dei nuovi post, appariranno qui.", - "empty_column.lists": "Non hai ancora alcuna lista. Quando ne creerai una, apparirà qui.", + "empty_column.list": "Non c'è ancora nulla in questo elenco. Quando i membri di questo elenco pubblicheranno nuovi post, appariranno qui.", + "empty_column.lists": "Non hai ancora nessun elenco. Quando ne creerai uno, apparirà qui.", "empty_column.mutes": "Non hai ancora silenziato alcun utente.", "empty_column.notification_requests": "Tutto chiaro! Non c'è niente qui. Quando ricevi nuove notifiche, verranno visualizzate qui in base alle tue impostazioni.", "empty_column.notifications": "Non hai ancora nessuna notifica. Quando altre persone interagiranno con te, le vedrai qui.", @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Usa una categoria esistente o creane una nuova", "filter_modal.select_filter.title": "Filtra questo post", "filter_modal.title.status": "Filtra un post", + "filtered_notifications_banner.mentions": "{count, plural, one {menzione} other {menzioni}}", "filtered_notifications_banner.pending_requests": "Notifiche da {count, plural, =0 {nessuno} one {una persona} other {# persone}} che potresti conoscere", "filtered_notifications_banner.title": "Notifiche filtrate", "firehose.all": "Tutto", @@ -307,6 +308,8 @@ "follow_requests.unlocked_explanation": "Anche se il tuo profilo non è privato, lo staff di {domain} ha pensato che potresti voler revisionare manualmente le richieste di seguirti da questi profili.", "follow_suggestions.curated_suggestion": "Scelta personale", "follow_suggestions.dismiss": "Non visualizzare più", + "follow_suggestions.featured_longer": "Selezionato personalmente dal team di {domain}", + "follow_suggestions.friends_of_friends_longer": "Popolare tra le persone che segui", "follow_suggestions.hints.featured": "Questo profilo è stato selezionato personalmente dal team di {domain}.", "follow_suggestions.hints.friends_of_friends": "Questo profilo è popolare tra le persone che segui.", "follow_suggestions.hints.most_followed": "Questo profilo è uno dei più seguiti su {domain}.", @@ -314,6 +317,8 @@ "follow_suggestions.hints.similar_to_recently_followed": "Questo profilo è simile ai profili che hai seguito più recentemente.", "follow_suggestions.personalized_suggestion": "Suggerimenti personalizzati", "follow_suggestions.popular_suggestion": "Suggerimento frequente", + "follow_suggestions.popular_suggestion_longer": "Popolare su {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Simile ai profili che hai seguito di recente", "follow_suggestions.view_all": "Vedi tutto", "follow_suggestions.who_to_follow": "Chi seguire", "followed_tags": "Hashtag seguiti", @@ -353,7 +358,7 @@ "interaction_modal.description.follow": "Con un profilo di Mastodon, puoi seguire {name} per ricevere i suoi post nel feed della tua home.", "interaction_modal.description.reblog": "Con un profilo di Mastodon, puoi rebloggare questo post per condividerlo con i tuoi seguaci.", "interaction_modal.description.reply": "Con un profilo di Mastodon, puoi rispondere a questo post.", - "interaction_modal.login.action": "Torna all’inizio", + "interaction_modal.login.action": "Portami alla pagina iniziale", "interaction_modal.login.prompt": "Dominio del tuo server principale, ad esempio mastodon.social", "interaction_modal.no_account_yet": "Non su Mastodon?", "interaction_modal.on_another_server": "Su un altro server", @@ -409,20 +414,20 @@ "limited_account_hint.action": "Mostra comunque il profilo", "limited_account_hint.title": "Questo profilo è stato nascosto dai moderatori di {domain}.", "link_preview.author": "Di {name}", - "lists.account.add": "Aggiungi alla lista", - "lists.account.remove": "Togli dalla lista", - "lists.delete": "Elimina lista", - "lists.edit": "Modifica lista", + "lists.account.add": "Aggiungi all'elenco", + "lists.account.remove": "Rimuovi dall'elenco", + "lists.delete": "Elimina elenco", + "lists.edit": "Modifica elenco", "lists.edit.submit": "Cambia il titolo", "lists.exclusive": "Nascondi questi post dalla home", "lists.new.create": "Aggiungi lista", - "lists.new.title_placeholder": "Titolo della nuova lista", + "lists.new.title_placeholder": "Titolo del nuovo elenco", "lists.replies_policy.followed": "Qualsiasi utente seguito", - "lists.replies_policy.list": "Membri della lista", + "lists.replies_policy.list": "Membri dell'elenco", "lists.replies_policy.none": "Nessuno", "lists.replies_policy.title": "Mostra risposte a:", "lists.search": "Cerca tra le persone che segui", - "lists.subheading": "Le tue liste", + "lists.subheading": "I tuoi elenchi", "load_pending": "{count, plural, one {# nuovo oggetto} other {# nuovi oggetti}}", "loading_indicator.label": "Caricamento…", "media_gallery.toggle_visible": "{number, plural, one {Nascondi immagine} other {Nascondi immagini}}", @@ -468,10 +473,23 @@ "notification.follow": "{name} ha iniziato a seguirti", "notification.follow_request": "{name} ha richiesto di seguirti", "notification.mention": "{name} ti ha menzionato", + "notification.moderation-warning.learn_more": "Scopri di più", + "notification.moderation_warning": "Hai ricevuto un avviso di moderazione", + "notification.moderation_warning.action_delete_statuses": "Alcuni dei tuoi post sono stati rimossi.", + "notification.moderation_warning.action_disable": "Il tuo account è stato disattivato.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Alcuni dei tuoi post sono stati contrassegnati come sensibili.", + "notification.moderation_warning.action_none": "Il tuo account ha ricevuto un avviso di moderazione.", + "notification.moderation_warning.action_sensitive": "I tuoi post d'ora in poi saranno contrassegnati come sensibili.", + "notification.moderation_warning.action_silence": "Il tuo account è stato limitato.", + "notification.moderation_warning.action_suspend": "Il tuo account è stato sospeso.", "notification.own_poll": "Il tuo sondaggio è terminato", "notification.poll": "Un sondaggio in cui hai votato è terminato", "notification.reblog": "{name} ha rebloggato il tuo post", - "notification.severed_relationships": "Relazioni interrotte con {name}", + "notification.relationships_severance_event": "Connessioni perse con {name}", + "notification.relationships_severance_event.account_suspension": "Un amministratore da {from} ha sospeso {target}, il che significa che non puoi più ricevere aggiornamenti da loro o interagire con loro.", + "notification.relationships_severance_event.domain_block": "Un amministratore da {from} ha bloccato {target}, inclusi {followersCount} dei tuoi seguaci e {followingCount, plural, one {# account} other {# account}} che segui.", + "notification.relationships_severance_event.learn_more": "Scopri di più", + "notification.relationships_severance_event.user_domain_block": "Tu hai bloccato {target}, rimuovendo {followersCount} dei tuoi seguaci e {followingCount, plural, one {# account} other {# account}} che segui.", "notification.status": "{name} ha appena pubblicato un post", "notification.update": "{name} ha modificato un post", "notification_requests.accept": "Accetta", @@ -484,6 +502,8 @@ "notifications.column_settings.admin.sign_up": "Nuove iscrizioni:", "notifications.column_settings.alert": "Notifiche desktop", "notifications.column_settings.favourite": "Preferiti:", + "notifications.column_settings.filter_bar.advanced": "Mostra tutte le categorie", + "notifications.column_settings.filter_bar.category": "Barra del filtro veloce", "notifications.column_settings.follow": "Nuovi seguaci:", "notifications.column_settings.follow_request": "Nuove richieste di seguirti:", "notifications.column_settings.mention": "Menzioni:", @@ -588,12 +608,6 @@ "refresh": "Ricarica", "regeneration_indicator.label": "Caricamento…", "regeneration_indicator.sublabel": "Il feed della tua home è in preparazione!", - "relationship_severance_notification.purged_data": "rimossi dagli amministratori", - "relationship_severance_notification.relationships": "{count, plural,one {# relazione} other {# relazioni}}", - "relationship_severance_notification.types.account_suspension": "L'account è stato sospeso", - "relationship_severance_notification.types.domain_block": "Il dominio è stato sospeso", - "relationship_severance_notification.types.user_domain_block": "Hai bloccato questo dominio", - "relationship_severance_notification.view": "Visualizza", "relative_time.days": "{number}g", "relative_time.full.days": "{number, plural, one {# giorno} other {# giorni}} fa", "relative_time.full.hours": "{number, plural, one {# ora} other {# ore}} fa", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index 66811eafd..f20d93753 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -89,6 +89,14 @@ "announcement.announcement": "お知らせ", "attachments_list.unprocessed": "(未処理)", "audio.hide": "音声を閉じる", + "block_modal.remote_users_caveat": "このサーバーはあなたのブロックの意思を尊重するように {domain} へ通知します。しかしながら、ブロックの扱い方はサーバーによってさまざまで、相手のサーバーは必ずしもこのブロックを適切に取り扱うものではないことに留意が必要です。また、あなたの公開投稿はサーバーからログアウトすれば誰からも見ることができます。", + "block_modal.show_less": "注意事項を閉じる", + "block_modal.show_more": "注意事項", + "block_modal.they_cant_mention": "相手はあなたへの返信やフォローができなくなります。", + "block_modal.they_cant_see_posts": "相手はあなたの投稿を閲覧できなくなり、あなたも相手の投稿を閲覧できなくなります。", + "block_modal.they_will_know": "ブロックは相手からわかります。", + "block_modal.title": "ユーザーをブロックしますか?", + "block_modal.you_wont_see_mentions": "宛先に相手が入っている投稿も閲覧できなくなります。", "boost_modal.combo": "次からは{combo}を押せばスキップできます", "bundle_column_error.copy_stacktrace": "エラーレポートをコピー", "bundle_column_error.error.body": "要求されたページをレンダリングできませんでした。コードのバグ、またはブラウザの互換性の問題が原因である可能性があります。", @@ -169,6 +177,7 @@ "confirmations.delete_list.message": "本当にこのリストを完全に削除しますか?", "confirmations.discard_edit_media.confirm": "破棄", "confirmations.discard_edit_media.message": "メディアの説明またはプレビューに保存されていない変更があります。それでも破棄しますか?", + "confirmations.domain_block.confirm": "サーバーをブロック", "confirmations.domain_block.message": "本当に{domain}全体を非表示にしますか? 多くの場合は個別にブロックやミュートするだけで充分であり、また好ましいです。公開タイムラインにそのドメインのコンテンツが表示されなくなり、通知も届かなくなります。そのドメインのフォロワーはアンフォローされます。", "confirmations.edit.confirm": "編集", "confirmations.edit.message": "今編集すると現在作成中のメッセージが上書きされます。本当に実行しますか?", @@ -200,6 +209,27 @@ "dismissable_banner.explore_statuses": "ネットワーク上で注目を集めている投稿です。ブーストやお気に入り登録の多い新しい投稿が上位に表示されます。", "dismissable_banner.explore_tags": "ネットワーク上でトレンドになっているハッシュタグです。たくさんのユーザーに使われたタグほど上位に表示されます。", "dismissable_banner.public_timeline": "{domain}のユーザーがリモートフォローしているアカウントからの公開投稿のタイムラインです。", + "domain_block_modal.block": "サーバーをブロック", + "domain_block_modal.block_account_instead": "@{name} さんのみをブロック", + "domain_block_modal.they_can_interact_with_old_posts": "あなたの今までの投稿は、引き続きこのサーバーのユーザーが閲覧できます。", + "domain_block_modal.they_cant_follow": "このサーバーのユーザーはあなたをフォローできなくなります。", + "domain_block_modal.they_wont_know": "ドメインブロックは相手からはわかりません。", + "domain_block_modal.title": "ドメインをブロックしますか?", + "domain_block_modal.you_will_lose_followers": "このサーバーのフォロワーはすべてフォロー解除されます。", + "domain_block_modal.you_wont_see_posts": "このサーバーのユーザーからの投稿や通知が閲覧できなくなります。", + "domain_pill.activitypub_lets_connect": "Mastodonからほかのソーシャルアプリのユーザーへ、そのまた別のアプリのユーザーへと、それぞれが互いにつながり関わり合うことをこのActivityPubの仕組みが実現しています。", + "domain_pill.activitypub_like_language": "ActivityPubとは、Mastodonがほかのサーバーと会話をするときにしゃべる「言葉」のようなものです。", + "domain_pill.server": "サーバー", + "domain_pill.their_handle": "このユーザーのユーザーID:", + "domain_pill.their_server": "ユーザーの仮想の住所です。そのユーザーIDによるすべての投稿を保持しています。", + "domain_pill.their_username": "ユーザーを識別する名前です。ユーザー名はひとつのサーバー内においては唯一無二の名前ですが、ほかのサーバーには同名のユーザーがいることもあります。", + "domain_pill.username": "ユーザー名", + "domain_pill.whats_in_a_handle": "ユーザーIDについて", + "domain_pill.who_they_are": "そのユーザーが「誰であるか」「どこに住んでいるか」はユーザーIDから知ることができます。これによりの集まりからなるネットワークを介してそれぞれのユーザーと関わり合うことができます。", + "domain_pill.who_you_are": "ほかのユーザーはあなたが「誰であるか」「どこに住んでいるか」をユーザーIDから認識でき、これによりの集まりからなるネットワークを介してあなたと関わり合うことができます。", + "domain_pill.your_handle": "あなたのユーザーID:", + "domain_pill.your_server": "あなたの仮想の住所です。投稿した内容はすべてここに保持されます。もし今いるサーバーが気に入っていない場合は、フォロワーを引き継いで別のサーバーに引っ越すこともできます。", + "domain_pill.your_username": "あなたを識別する名前です。ユーザー名はひとつのサーバー内においては唯一無二の名前ですが、ほかのサーバーには同名のユーザーがいることもあります。", "embed.instructions": "下記のコードをコピーしてウェブサイトに埋め込みます。", "embed.preview": "表示例:", "emoji_button.activity": "活動", @@ -267,7 +297,8 @@ "filter_modal.select_filter.subtitle": "既存のカテゴリーを使用するか新規作成します", "filter_modal.select_filter.title": "この投稿をフィルターする", "filter_modal.title.status": "投稿をフィルターする", - "filtered_notifications_banner.pending_requests": "{count, plural, =0 {アカウント} other {#アカウント}}からの通知がブロックされています", + "filtered_notifications_banner.mentions": "{count, plural, one {メンション} other {メンション}}", + "filtered_notifications_banner.pending_requests": "{count, plural, =0 {通知がブロックされているアカウントはありません} other {#アカウントからの通知がブロックされています}}", "filtered_notifications_banner.title": "ブロック済みの通知", "firehose.all": "すべて", "firehose.local": "このサーバー", @@ -397,6 +428,15 @@ "loading_indicator.label": "読み込み中…", "media_gallery.toggle_visible": "{number, plural, one {画像を閉じる} other {画像を閉じる}}", "moved_to_account_banner.text": "あなたのアカウント『{disabledAccount}』は『{movedToAccount}』に移動したため現在無効になっています。", + "mute_modal.hide_from_notifications": "通知をオフにする", + "mute_modal.hide_options": "オプションを閉じる", + "mute_modal.indefinite": "無期限", + "mute_modal.show_options": "オプションを表示", + "mute_modal.they_can_mention_and_follow": "相手はあなたへの返信やフォローができますが、あなたには見えません。", + "mute_modal.they_wont_know": "ミュートは相手からはわかりません。", + "mute_modal.title": "ユーザーをミュートしますか?", + "mute_modal.you_wont_see_mentions": "宛先に相手が入っている投稿も閲覧できなくなります。", + "mute_modal.you_wont_see_posts": "相手はあなたの投稿を今までどおり閲覧できますが、あなたは相手の投稿を閲覧できなくなります。", "navigation_bar.about": "概要", "navigation_bar.advanced_interface": "上級者向けUIに戻る", "navigation_bar.blocks": "ブロックしたユーザー", @@ -432,6 +472,11 @@ "notification.own_poll": "アンケートが終了しました", "notification.poll": "アンケートが終了しました", "notification.reblog": "{name}さんがあなたの投稿をブーストしました", + "notification.relationships_severance_event": "{name} との関係が失われました", + "notification.relationships_severance_event.account_suspension": "{from} の管理者が {target} さんを停止したため、今後このユーザーとの交流や新しい投稿の受け取りができなくなりました。", + "notification.relationships_severance_event.domain_block": "{from} の管理者が {target} をブロックしました。これにより{followersCount}フォロワーと{followingCount, plural, other {#フォロー}}が失われました。", + "notification.relationships_severance_event.learn_more": "詳細を確認", + "notification.relationships_severance_event.user_domain_block": "{target} のブロックにより{followersCount}フォロワーと{followingCount, plural, other {#フォロー}}が解除されました。", "notification.status": "{name}さんが投稿しました", "notification.update": "{name}さんが投稿を編集しました", "notification_requests.accept": "受け入れる", @@ -444,6 +489,8 @@ "notifications.column_settings.admin.sign_up": "新規登録:", "notifications.column_settings.alert": "デスクトップ通知", "notifications.column_settings.favourite": "お気に入り:", + "notifications.column_settings.filter_bar.advanced": "すべてのカテゴリを表示", + "notifications.column_settings.filter_bar.category": "クイックフィルターバー:", "notifications.column_settings.follow": "新しいフォロワー:", "notifications.column_settings.follow_request": "新しいフォローリクエスト:", "notifications.column_settings.mention": "返信:", @@ -654,9 +701,11 @@ "status.direct": "@{name}さんに非公開で投稿", "status.direct_indicator": "非公開の返信", "status.edit": "編集", + "status.edited": "最終更新日 {date}", "status.edited_x_times": "{count}回編集", "status.embed": "埋め込み", "status.favourite": "お気に入り", + "status.favourites": "{count, plural, one {お気に入り} other {お気に入り}}", "status.filter": "この投稿をフィルターする", "status.filtered": "フィルターされました", "status.hide": "投稿を非表示", @@ -677,6 +726,7 @@ "status.reblog": "ブースト", "status.reblog_private": "ブースト", "status.reblogged_by": "{name}さんがブースト", + "status.reblogs": "{count, plural, one {ブースト} other {ブースト}}", "status.reblogs.empty": "まだ誰もブーストしていません。ブーストされるとここに表示されます。", "status.redraft": "削除して下書きに戻す", "status.remove_bookmark": "ブックマークを削除", diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json index fbe60c3bd..9fdf60299 100644 --- a/app/javascript/mastodon/locales/kab.json +++ b/app/javascript/mastodon/locales/kab.json @@ -221,6 +221,7 @@ "filter_modal.select_filter.prompt_new": "Taggayt tamaynutt : {name}", "filter_modal.select_filter.search": "Nadi neɣ snulfu-d", "filter_modal.select_filter.title": "Sizdeg tassufeɣt-a", + "filter_modal.title.status": "Sizdeg tassufeɣt", "firehose.all": "Akk", "firehose.local": "Deg uqeddac-ayi", "firehose.remote": "Iqeddacen nniḍen", @@ -335,6 +336,7 @@ "mute_modal.show_options": "Sken-d tinefrunin", "mute_modal.title": "Sgugem aseqdac?", "navigation_bar.about": "Ɣef", + "navigation_bar.advanced_interface": "Ldi deg ugrudem n web leqqayen", "navigation_bar.blocks": "Iseqdacen yettusḥebsen", "navigation_bar.bookmarks": "Ticraḍ", "navigation_bar.community_timeline": "Tasuddemt tadigant", @@ -364,6 +366,7 @@ "notification.own_poll": "Tafrant-ik·im tfuk", "notification.poll": "Tfukk tefrant ideg tettekkaḍ", "notification.reblog": "{name} yebḍa tajewwiqt-ik i tikelt-nniḍen", + "notification.relationships_severance_event.learn_more": "Issin ugar", "notification.status": "{name} akken i d-yessufeɣ", "notification_requests.accept": "Qbel", "notification_requests.dismiss": "Agi", @@ -372,6 +375,8 @@ "notifications.clear_confirmation": "Tebɣiḍ s tidet ad tekkseḍ akk tilɣa-inek·em i lebda?", "notifications.column_settings.alert": "Tilɣa n tnarit", "notifications.column_settings.favourite": "Imenyafen:", + "notifications.column_settings.filter_bar.advanced": "Sken-d akk taggayin", + "notifications.column_settings.filter_bar.category": "Iri n usizdeg uzrib", "notifications.column_settings.follow": "Imeḍfaṛen imaynuten:", "notifications.column_settings.follow_request": "Isuturen imaynuten n teḍfeṛt:", "notifications.column_settings.mention": "Abdar:", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index da354f391..8628dbb33 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.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 {0 명} one {한 명} other {# 명}}의 사람들로부터의 알림", "filtered_notifications_banner.title": "걸러진 알림", "firehose.all": "모두", @@ -471,7 +472,11 @@ "notification.own_poll": "설문을 마침", "notification.poll": "참여한 설문이 종료됨", "notification.reblog": "{name} 님이 부스트했습니다", - "notification.severed_relationships": "{name} 님과의 관계가 단절되었습니다", + "notification.relationships_severance_event": "{name} 님과의 연결이 끊어졌습니다", + "notification.relationships_severance_event.account_suspension": "{from}의 관리자가 {target}를 정지시켰기 때문에 그들과 더이상 상호작용 할 수 없고 정보를 받아볼 수 없습니다.", + "notification.relationships_severance_event.domain_block": "{from}의 관리자가 {target}를 차단하였고 여기에는 나의 {followersCount} 명의 팔로워와 {followingCount, plural, other {#}} 명의 팔로우가 포함되었습니다.", + "notification.relationships_severance_event.learn_more": "더 알아보기", + "notification.relationships_severance_event.user_domain_block": "내가 {target}를 차단하여 {followersCount} 명의 팔로워와 {followingCount, plural, other {#}} 명의 팔로우가 제거되었습니다.", "notification.status": "{name} 님이 방금 게시물을 올렸습니다", "notification.update": "{name} 님이 게시물을 수정했습니다", "notification_requests.accept": "수락", @@ -484,6 +489,8 @@ "notifications.column_settings.admin.sign_up": "새로운 가입:", "notifications.column_settings.alert": "데스크탑 알림", "notifications.column_settings.favourite": "좋아요:", + "notifications.column_settings.filter_bar.advanced": "모든 범주 표시", + "notifications.column_settings.filter_bar.category": "빠른 필터 막대", "notifications.column_settings.follow": "새 팔로워:", "notifications.column_settings.follow_request": "새 팔로우 요청:", "notifications.column_settings.mention": "멘션:", @@ -588,12 +595,6 @@ "refresh": "새로고침", "regeneration_indicator.label": "불러오는 중…", "regeneration_indicator.sublabel": "홈 피드를 준비하고 있습니다!", - "relationship_severance_notification.purged_data": "관리자에 의해 제거되었습니다", - "relationship_severance_notification.relationships": "{count, plural, other {# 건의 관계}}", - "relationship_severance_notification.types.account_suspension": "계정이 정지되었습니다", - "relationship_severance_notification.types.domain_block": "도메인이 정지되었습니다", - "relationship_severance_notification.types.user_domain_block": "내가 이 도메인을 차단했습니다", - "relationship_severance_notification.view": "보기", "relative_time.days": "{number}일 전", "relative_time.full.days": "{number} 일 전", "relative_time.full.hours": "{number} 시간 전", @@ -700,7 +701,7 @@ "status.direct": "@{name} 님에게 개인적으로 멘션", "status.direct_indicator": "개인적인 멘션", "status.edit": "수정", - "status.edited": "%{date}에 마지막으로 편집됨", + "status.edited": "{date}에 마지막으로 편집됨", "status.edited_x_times": "{count}번 수정됨", "status.embed": "임베드", "status.favourite": "좋아요", diff --git a/app/javascript/mastodon/locales/lad.json b/app/javascript/mastodon/locales/lad.json index 1eb8aa4ab..cf6c3f772 100644 --- a/app/javascript/mastodon/locales/lad.json +++ b/app/javascript/mastodon/locales/lad.json @@ -457,6 +457,8 @@ "notification.own_poll": "Tu anketa eskapo", "notification.poll": "Anketa en ke votates eskapo", "notification.reblog": "{name} repartajo tu publikasyon", + "notification.relationships_severance_event": "Koneksyones pedridas kon {name}", + "notification.relationships_severance_event.learn_more": "Ambezate mas", "notification.status": "{name} publiko algo", "notification.update": "{name} edito una publikasyon", "notification_requests.accept": "Acheta", @@ -469,6 +471,8 @@ "notifications.column_settings.admin.sign_up": "Muevas enrejistrasyones:", "notifications.column_settings.alert": "Avizos de ensimameza", "notifications.column_settings.favourite": "Te plazen:", + "notifications.column_settings.filter_bar.advanced": "Amostra todas las kategorias", + "notifications.column_settings.filter_bar.category": "Vara de filtrado rapido", "notifications.column_settings.follow": "Muevos suivantes:", "notifications.column_settings.follow_request": "Muevas solisitudes de segimiento:", "notifications.column_settings.mention": "Enmentaduras:", @@ -571,8 +575,6 @@ "refresh": "Arefreska", "regeneration_indicator.label": "Eskargando…", "regeneration_indicator.sublabel": "Tu linya de tiempo prinsipala esta preparando!", - "relationship_severance_notification.types.user_domain_block": "Blokates este domeno", - "relationship_severance_notification.view": "Mira", "relative_time.days": "{number} d", "relative_time.full.days": "antes {number, plural, one {# diya} other {# diyas}}", "relative_time.full.hours": "antes {number, plural, one {# ora} other {# oras}}", diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json index f9ef7e242..7b3511cfe 100644 --- a/app/javascript/mastodon/locales/lt.json +++ b/app/javascript/mastodon/locales/lt.json @@ -83,12 +83,15 @@ "admin.impact_report.instance_follows": "Sekėjai, kuriuos prarastų jų naudotojai", "admin.impact_report.title": "Poveikio apibendrinimas", "alert.rate_limited.message": "Pabandyk vėliau po {retry_time, time, medium}.", - "alert.rate_limited.title": "Sparta ribota", + "alert.rate_limited.title": "Sparta ribota.", "alert.unexpected.message": "Įvyko netikėta klaida.", "alert.unexpected.title": "Ups!", "announcement.announcement": "Skelbimas", "attachments_list.unprocessed": "(neapdorotas)", "audio.hide": "Slėpti garsą", + "block_modal.remote_users_caveat": "Paprašysime serverio {domain} gerbti tavo sprendimą. Tačiau atitiktis negarantuojama, nes kai kurie serveriai gali skirtingai tvarkyti blokavimus. Vieši įrašai vis tiek gali būti matomi neprisijungusiems naudotojams.", + "block_modal.show_less": "Rodyti mažiau", + "block_modal.show_more": "Rodyti daugiau", "boost_modal.combo": "Galima paspausti {combo}, kad praleisti kitą kartą.", "bundle_column_error.copy_stacktrace": "Kopijuoti klaidos ataskaitą", "bundle_column_error.error.body": "Paprašytos puslapio nepavyko atvaizduoti. Tai gali būti dėl mūsų kodo klaidos arba naršyklės suderinamumo problemos.", @@ -442,6 +445,8 @@ "notification.own_poll": "Tavo apklausa baigėsi", "notification.poll": "Apklausa, kurioje balsavai, pasibaigė", "notification.reblog": "{name} pakėlė tavo įrašą", + "notification.relationships_severance_event.learn_more": "Sužinoti daugiau", + "notification.relationships_severance_event.user_domain_block": "Tu užblokavai {target}. Pašalinama {followersCount} savo sekėjų ir {followingCount, plural, one {# paskyrą} few {# paskyrai} many {# paskyros} other {# paskyrų}}, kurios seki.", "notification.status": "{name} ką tik paskelbė", "notification.update": "{name} redagavo įrašą", "notification_requests.accept": "Priimti", @@ -454,6 +459,8 @@ "notifications.column_settings.admin.sign_up": "Naujos registracijos:", "notifications.column_settings.alert": "Darbalaukio pranešimai", "notifications.column_settings.favourite": "Mėgstami:", + "notifications.column_settings.filter_bar.advanced": "Rodyti visas kategorijas", + "notifications.column_settings.filter_bar.category": "Spartaus filtro juosta", "notifications.column_settings.follow": "Nauji sekėjai:", "notifications.column_settings.follow_request": "Nauji sekimo prašymai:", "notifications.column_settings.mention": "Paminėjimai:", diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json index 21fa46faa..55ceb564b 100644 --- a/app/javascript/mastodon/locales/lv.json +++ b/app/javascript/mastodon/locales/lv.json @@ -626,7 +626,7 @@ "status.direct_indicator": "Pieminēts privāti", "status.edit": "Labot", "status.edited_x_times": "Labots {count, plural, one {{count} reizi} other {{count} reizes}}", - "status.embed": "Iestrādāt", + "status.embed": "Iegult", "status.favourite": "Izlasē", "status.filter": "Filtrē šo ziņu", "status.filtered": "Filtrēts", @@ -634,7 +634,7 @@ "status.history.created": "{name} izveidoja {date}", "status.history.edited": "{name} laboja {date}", "status.load_more": "Ielādēt vairāk", - "status.media.open": "Noklikšķini, lai atvērtu", + "status.media.open": "Jānoklikšķina, lai atvērtu", "status.media.show": "Noklikšķini, lai parādītu", "status.media_hidden": "Multivides ir paslēpts", "status.mention": "Pieminēt @{name}", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index 4be0808f2..1958e4a6a 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -205,10 +205,10 @@ "disabled_account_banner.text": "Jouw account {disabledAccount} is momenteel uitgeschakeld.", "dismissable_banner.community_timeline": "Dit zijn de meest recente openbare berichten van accounts op {domain}. Je kunt onder 'instellingen > voorkeuren > overig' kiezen welke talen je wilt zien.", "dismissable_banner.dismiss": "Sluiten", - "dismissable_banner.explore_links": "Dit zijn nieuwsberichten die vandaag het meest op het sociale web worden gedeeld. Nieuwere nieuwsberichten die door meer verschillende mensen zijn geplaatst staan hoger op de lijst.", - "dismissable_banner.explore_statuses": "Dit zijn berichten op het sociale web die vandaag aan populariteit winnen. Nieuwere berichten met meer boosts en favorieten staan hoger.", - "dismissable_banner.explore_tags": "Deze hashtags winnen aan populariteit op het sociale web. Hashtags die door meer verschillende mensen worden gebruikt staan hoger.", - "dismissable_banner.public_timeline": "Dit zijn de meest recente openbare berichten van accounts op het sociale web die door mensen op {domain} worden gevolgd.", + "dismissable_banner.explore_links": "Dit zijn nieuwsberichten die vandaag het meest op het sociale web (fediverse) worden gedeeld. Nieuwere nieuwsberichten die door meer verschillende mensen zijn geplaatst staan hoger op de lijst.", + "dismissable_banner.explore_statuses": "Dit zijn berichten op het sociale web (fediverse) die vandaag aan populariteit winnen. Nieuwere berichten met meer boosts en favorieten staan hoger.", + "dismissable_banner.explore_tags": "Deze hashtags winnen aan populariteit op het sociale web (fediverse). Hashtags die door meer verschillende mensen worden gebruikt staan hoger.", + "dismissable_banner.public_timeline": "Dit zijn de meest recente openbare berichten van accounts op het sociale web (fediverse) die door mensen op {domain} worden gevolgd.", "domain_block_modal.block": "Server blokkeren", "domain_block_modal.block_account_instead": "In plaats hiervan {name} blokkeren", "domain_block_modal.they_can_interact_with_old_posts": "Mensen op deze server kunnen interactie hebben met jouw oude berichten.", @@ -220,14 +220,14 @@ "domain_pill.activitypub_lets_connect": "Het zorgt ervoor dat je niet alleen maar kunt verbinden en communiceren met mensen op Mastodon, maar ook met andere sociale apps.", "domain_pill.activitypub_like_language": "ActivityPub is de taal die Mastodon met andere sociale netwerken spreekt.", "domain_pill.server": "Server", - "domain_pill.their_handle": "Hun Mastodon-adres:", + "domain_pill.their_handle": "Hun fediverse-adres:", "domain_pill.their_server": "Hun digitale thuis, waar al hun berichten zich bevinden.", "domain_pill.their_username": "Hun unieke identificatie-adres op hun server. Het is mogelijk dat er gebruikers met dezelfde gebruikersnaam op verschillende servers te vinden zijn.", "domain_pill.username": "Gebruikersnaam", - "domain_pill.whats_in_a_handle": "Wat is een Mastodon-adres?", - "domain_pill.who_they_are": "Omdat je aan een Mastodon-adres kunt zien wie iemand is en waar die zich bevindt, kun je met mensen op het door sociale web communiceren.", - "domain_pill.who_you_are": "Omdat je aan jouw Mastodon-adres kunt zien wie jij bent is en waar je je bevindt, kunnen mensen op het door sociale web met jou communiceren.", - "domain_pill.your_handle": "Jouw Mastodon-adres:", + "domain_pill.whats_in_a_handle": "Wat is een fediverse-adres?", + "domain_pill.who_they_are": "Omdat je aan een fediverse-adres kunt zien hoe iemand heet en op welke server die zich bevindt, kun je met mensen op het door sociale web (fediverse) communiceren.", + "domain_pill.who_you_are": "Omdat je aan jouw fediverse-adres kunt zien hoe je heet en op welke server je je bevindt, kunnen mensen op het door sociale web (fediverse) met jou communiceren.", + "domain_pill.your_handle": "Jouw fediverse-adres:", "domain_pill.your_server": "Jouw digitale thuis, waar al jouw berichten zich bevinden. Is deze server toch niet naar jouw wens? Dan kun je op elk moment naar een andere server verhuizen en ook jouw volgers overbrengen.", "domain_pill.your_username": "Jouw unieke identificatie-adres op deze server. Het is mogelijk dat er gebruikers met dezelfde gebruikersnaam op verschillende servers te vinden zijn.", "embed.instructions": "Embed dit bericht op jouw website door de onderstaande code te kopiëren.", @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Een bestaande categorie gebruiken of een nieuwe aanmaken", "filter_modal.select_filter.title": "Dit bericht filteren", "filter_modal.title.status": "Een bericht filteren", + "filtered_notifications_banner.mentions": "{count, plural, one {vermelding} other {vermeldingen}}", "filtered_notifications_banner.pending_requests": "Meldingen van {count, plural, =0 {niemand} one {één persoon} other {# mensen}} die je misschien kent", "filtered_notifications_banner.title": "Gefilterde meldingen", "firehose.all": "Alles", @@ -307,13 +308,17 @@ "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.", "follow_suggestions.curated_suggestion": "Speciaal geselecteerd", "follow_suggestions.dismiss": "Niet meer weergeven", - "follow_suggestions.hints.featured": "Deze gebruiker is geselecteerd door het team van {domain}.", + "follow_suggestions.featured_longer": "Handmatig geselecteerd door het team van {domain}", + "follow_suggestions.friends_of_friends_longer": "Populair onder mensen die je volgt", + "follow_suggestions.hints.featured": "Deze gebruiker is handmatig geselecteerd door het team van {domain}.", "follow_suggestions.hints.friends_of_friends": "Deze gebruiker is populair onder de mensen die jij volgt.", "follow_suggestions.hints.most_followed": "Deze gebruiker is een van de meest gevolgde gebruikers op {domain}.", "follow_suggestions.hints.most_interactions": "Deze gebruiker is de laatste tijd erg populair op {domain}.", "follow_suggestions.hints.similar_to_recently_followed": "Deze gebruiker is vergelijkbaar met gebruikers die je recentelijk hebt gevolgd.", "follow_suggestions.personalized_suggestion": "Gepersonaliseerde aanbeveling", "follow_suggestions.popular_suggestion": "Populaire aanbeveling", + "follow_suggestions.popular_suggestion_longer": "Populair op {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Vergelijkbaar met accounts die je recentelijk bent gaan volgen", "follow_suggestions.view_all": "Alles weergeven", "follow_suggestions.who_to_follow": "Wie te volgen", "followed_tags": "Gevolgde hashtags", @@ -468,10 +473,23 @@ "notification.follow": "{name} volgt jou nu", "notification.follow_request": "{name} wil jou graag volgen", "notification.mention": "{name} vermeldde jou", + "notification.moderation-warning.learn_more": "Meer informatie", + "notification.moderation_warning": "Je hebt een moderatie-waarschuwing ontvangen", + "notification.moderation_warning.action_delete_statuses": "Sommige van je berichten zijn verwijderd.", + "notification.moderation_warning.action_disable": "Je account is uitgeschakeld.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Sommige van je berichten zijn gemarkeerd als gevoelig.", + "notification.moderation_warning.action_none": "Jouw account heeft een moderatie-waarschuwing ontvangen.", + "notification.moderation_warning.action_sensitive": "Je berichten worden vanaf nu als gevoelig gemarkeerd.", + "notification.moderation_warning.action_silence": "Jouw account is beperkt.", + "notification.moderation_warning.action_suspend": "Jouw account is opgeschort.", "notification.own_poll": "Jouw peiling is beëindigd", "notification.poll": "Een peiling waaraan jij hebt meegedaan is beëindigd", "notification.reblog": "{name} boostte jouw bericht", - "notification.severed_relationships": "Volgrelaties met {name} verbroken", + "notification.relationships_severance_event": "Verloren verbindingen met {name}", + "notification.relationships_severance_event.account_suspension": "Een beheerder van {from} heeft {target} geschorst, wat betekent dat je geen updates meer van hen kunt ontvangen of met hen kunt communiceren.", + "notification.relationships_severance_event.domain_block": "Een beheerder van {from} heeft {target} geblokkeerd, inclusief {followersCount} van jouw volgers en {followingCount, plural, one {# account} other {# accounts}} die jij volgt.", + "notification.relationships_severance_event.learn_more": "Meer informatie", + "notification.relationships_severance_event.user_domain_block": "Je hebt {target} geblokkeerd, waarmee je {followersCount} van je volgers en {followingCount, plural, one {# account} other {# accounts}} die jij volgt, bent verloren.", "notification.status": "{name} heeft zojuist een bericht geplaatst", "notification.update": "{name} heeft een bericht bewerkt", "notification_requests.accept": "Accepteren", @@ -484,6 +502,8 @@ "notifications.column_settings.admin.sign_up": "Nieuwe registraties:", "notifications.column_settings.alert": "Desktopmeldingen", "notifications.column_settings.favourite": "Favorieten:", + "notifications.column_settings.filter_bar.advanced": "Alle categorieën tonen", + "notifications.column_settings.filter_bar.category": "Snelle filterbalk", "notifications.column_settings.follow": "Nieuwe volgers:", "notifications.column_settings.follow_request": "Nieuw volgverzoek:", "notifications.column_settings.mention": "Vermeldingen:", @@ -588,12 +608,6 @@ "refresh": "Vernieuwen", "regeneration_indicator.label": "Aan het laden…", "regeneration_indicator.sublabel": "Jouw starttijdlijn wordt aangemaakt!", - "relationship_severance_notification.purged_data": "verwijderd door beheerders", - "relationship_severance_notification.relationships": "{count, plural, one {# volgrelatie} other {# volgrelaties}}", - "relationship_severance_notification.types.account_suspension": "Account is opgeschort", - "relationship_severance_notification.types.domain_block": "Domein is opgeschort", - "relationship_severance_notification.types.user_domain_block": "Je hebt dit domein geblokkeerd", - "relationship_severance_notification.view": "Weergeven", "relative_time.days": "{number}d", "relative_time.full.days": "{number, plural, one {# dag} other {# dagen}} geleden", "relative_time.full.hours": "{number, plural, one {# uur} other {# uur}} geleden", @@ -704,7 +718,7 @@ "status.edited_x_times": "{count, plural, one {{count} keer} other {{count} keer}} bewerkt", "status.embed": "Embedden", "status.favourite": "Favoriet", - "status.favourites": "{count, plural, one {# favoriet} other {# favorieten}}", + "status.favourites": "{count, plural, one {favoriet} other {favorieten}}", "status.filter": "Dit bericht filteren", "status.filtered": "Gefilterd", "status.hide": "Bericht verbergen", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json index 7742d83e1..14b355233 100644 --- a/app/javascript/mastodon/locales/nn.json +++ b/app/javascript/mastodon/locales/nn.json @@ -468,10 +468,23 @@ "notification.follow": "{name} fylgde deg", "notification.follow_request": "{name} har bedt om å fylgja deg", "notification.mention": "{name} nemnde deg", + "notification.moderation-warning.learn_more": "Lær meir", + "notification.moderation_warning": "Du har mottatt ei moderasjonsåtvaring", + "notification.moderation_warning.action_delete_statuses": "Nokre av innlegga dine har blitt fjerna.", + "notification.moderation_warning.action_disable": "Kontoen din har blitt deaktivert.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Nokre av innlegga dine har blitt markert som sensitive.", + "notification.moderation_warning.action_none": "Kontoen din har mottatt ei moderasjonsåtvaring.", + "notification.moderation_warning.action_sensitive": "Innlegga dine vil bli markerte som sensitive frå no av.", + "notification.moderation_warning.action_silence": "Kontoen din har blitt avgrensa.", + "notification.moderation_warning.action_suspend": "Kontoen din har blitt suspendert.", "notification.own_poll": "Rundspørjinga di er ferdig", "notification.poll": "Ei rundspørjing du har røysta i er ferdig", "notification.reblog": "{name} framheva innlegget ditt", - "notification.severed_relationships": "Forholda med {name} er brotne", + "notification.relationships_severance_event": "Tapte samband med {name}", + "notification.relationships_severance_event.account_suspension": "Ein administrator på {from} har utvist {target}, som tyder at du ikkje lenger får oppdateringar frå dei eller kan samhandla med dei.", + "notification.relationships_severance_event.domain_block": "Ein administrator på {from} har blokkert {target}, inkludert {followersCount} av fylgjarane dine og {followingCount, plural, one {# konto} other {# kontoar}} du fylgjer.", + "notification.relationships_severance_event.learn_more": "Lær meir", + "notification.relationships_severance_event.user_domain_block": "Du har blokkert {target}, fjerna {followersCount} av fylgjarane dine og {followingCount, plural, one {# konto} other {# kontoar}} du fylgjer.", "notification.status": "{name} la nettopp ut", "notification.update": "{name} redigerte eit innlegg", "notification_requests.accept": "Godkjenn", @@ -484,6 +497,8 @@ "notifications.column_settings.admin.sign_up": "Nyleg registrerte:", "notifications.column_settings.alert": "Skrivebordsvarsel", "notifications.column_settings.favourite": "Favorittar:", + "notifications.column_settings.filter_bar.advanced": "Vis alle kategoriar", + "notifications.column_settings.filter_bar.category": "Snøggfilterline", "notifications.column_settings.follow": "Nye fylgjarar:", "notifications.column_settings.follow_request": "Ny fylgjarførespurnader:", "notifications.column_settings.mention": "Omtalar:", @@ -588,12 +603,6 @@ "refresh": "Oppdater", "regeneration_indicator.label": "Lastar…", "regeneration_indicator.sublabel": "Heimetidslina di vert førebudd!", - "relationship_severance_notification.purged_data": "sletta av administratorar", - "relationship_severance_notification.relationships": "{count, plural, one {# forhold} other {# forhold}}", - "relationship_severance_notification.types.account_suspension": "Kontoen er utvist", - "relationship_severance_notification.types.domain_block": "Domenet er utestengt", - "relationship_severance_notification.types.user_domain_block": "Du blokkerte dette domenet", - "relationship_severance_notification.view": "Sjå", "relative_time.days": "{number}dg", "relative_time.full.days": "{number, plural, one {# dag} other {# dagar}} sidan", "relative_time.full.hours": "{number, plural, one {# time} other {# timar}} sidan", diff --git a/app/javascript/mastodon/locales/pa.json b/app/javascript/mastodon/locales/pa.json index e09dd9067..c693c2472 100644 --- a/app/javascript/mastodon/locales/pa.json +++ b/app/javascript/mastodon/locales/pa.json @@ -15,21 +15,32 @@ "account.cancel_follow_request": "ਫ਼ਾਲੋ ਕਰਨ ਨੂੰ ਰੱਦ ਕਰੋ", "account.copy": "ਪਰੋਫਾਇਲ ਲਈ ਲਿੰਕ ਕਾਪੀ ਕਰੋ", "account.direct": "ਨਿੱਜੀ ਜ਼ਿਕਰ @{name}", + "account.domain_blocked": "ਡੋਮੇਨ ਉੱਤੇ ਪਾਬੰਦੀ", "account.edit_profile": "ਪਰੋਫਾਈਲ ਨੂੰ ਸੋਧੋ", + "account.enable_notifications": "ਜਦੋਂ {name} ਪੋਸਟ ਕਰੇ ਤਾਂ ਮੈਨੂੰ ਸੂਚਨਾ ਦਿਓ", + "account.endorse": "ਪਰੋਫਾਇਲ ਉੱਤੇ ਫ਼ੀਚਰ", "account.featured_tags.last_status_at": "{date} ਨੂੰ ਆਖਰੀ ਪੋਸਟ", "account.featured_tags.last_status_never": "ਕੋਈ ਪੋਸਟ ਨਹੀਂ", "account.follow": "ਫ਼ਾਲੋ", + "account.follow_back": "ਵਾਪਸ ਫਾਲ਼ੋ ਕਰੋ", "account.followers": "ਫ਼ਾਲੋਅਰ", "account.followers.empty": "ਇਸ ਵਰਤੋਂਕਾਰ ਨੂੰ ਹਾਲੇ ਕੋਈ ਫ਼ਾਲੋ ਨਹੀਂ ਕਰਦਾ ਹੈ।", + "account.followers_counter": "{count, plural, one {{counter} ਫ਼ਾਲੋਅਰ} other {{counter} ਫ਼ਾਲੋਅਰ}}", "account.following": "ਫ਼ਾਲੋ ਕੀਤਾ", + "account.following_counter": "{count, plural, one {{counter} ਨੂੰ ਫ਼ਾਲੋ} other {{counter} ਨੂੰ ਫ਼ਾਲੋ}}", "account.follows.empty": "ਇਹ ਵਰਤੋਂਕਾਰ ਹਾਲੇ ਕਿਸੇ ਨੂੰ ਫ਼ਾਲੋ ਨਹੀਂ ਕਰਦਾ ਹੈ।", "account.go_to_profile": "ਪਰੋਫਾਇਲ ਉੱਤੇ ਜਾਓ", "account.media": "ਮੀਡੀਆ", "account.muted": "ਮੌਨ ਕੀਤੀਆਂ", + "account.mutual": "ਸਾਂਝੇ", + "account.no_bio": "ਕੋਈ ਵਰਣਨ ਨਹੀਂ ਦਿੱਤਾ।", + "account.open_original_page": "ਅਸਲ ਸਫ਼ੇ ਨੂੰ ਖੋਲ੍ਹੋ", "account.posts": "ਪੋਸਟਾਂ", "account.posts_with_replies": "ਪੋਸਤਾਂ ਅਤੇ ਜਵਾਬ", + "account.report": "{name} ਬਾਰੇ ਰਿਪੋਰਟ ਕਰੋ", "account.requested": "ਮਨਜ਼ੂਰੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ। ਫ਼ਾਲੋ ਬੇਨਤੀਆਂ ਨੂੰ ਰੱਦ ਕਰਨ ਲਈ ਕਲਿੱਕ ਕਰੋ", "account.requested_follow": "{name} ਨੇ ਤੁਹਾਨੂੰ ਫ਼ਾਲੋ ਕਰਨ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਹੈ", + "account.share": "{name} ਦਾ ਪਰੋਫ਼ਾਇਲ ਸਾਂਝਾ ਕਰੋ", "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}", "account.unblock": "@{name} ਤੋਂ ਪਾਬੰਦੀ ਹਟਾਓ", "account.unblock_domain": "{domain} ਡੋਮੇਨ ਤੋਂ ਪਾਬੰਦੀ ਹਟਾਓ", @@ -41,6 +52,9 @@ "admin.dashboard.retention.cohort_size": "ਨਵੇਂ ਵਰਤੋਂਕਾਰ", "alert.unexpected.title": "ਓਹੋ!", "announcement.announcement": "ਹੋਕਾ", + "block_modal.show_less": "ਘੱਟ ਦਿਖਾਓ", + "block_modal.show_more": "ਵੱਧ ਦਿਖਾਓ", + "block_modal.title": "ਵਰਤੋਂਕਾਰ ਉੱਤੇ ਪਾਬੰਦੀ ਲਾਉਣੀ ਹੈ?", "bundle_column_error.error.title": "ਓਹ ਹੋ!", "bundle_column_error.network.title": "ਨੈੱਟਵਰਕ ਦੀ ਸਮੱਸਿਆ", "bundle_column_error.retry": "ਮੁੜ-ਕੋਸ਼ਿਸ਼ ਕਰੋ", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index 782ea9d76..b763f740a 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Użyj istniejącej kategorii lub utwórz nową", "filter_modal.select_filter.title": "Filtruj ten wpis", "filter_modal.title.status": "Filtruj wpis", + "filtered_notifications_banner.mentions": "{count, plural, one {wzmianka} few {wzmianki} other {wzmianek}}", "filtered_notifications_banner.pending_requests": "Powiadomienia od {count, plural, =0 {żadnej osoby którą możesz znać} one {# osoby którą możesz znać} other {# osób które możesz znać}}", "filtered_notifications_banner.title": "Powiadomienia filtrowane", "firehose.all": "Wszystko", @@ -307,6 +308,8 @@ "follow_requests.unlocked_explanation": "Mimo że Twoje konto nie jest zablokowane, zespół {domain} uznał że możesz chcieć ręcznie przejrzeć prośby o możliwość obserwacji.", "follow_suggestions.curated_suggestion": "Wybrane przez personel", "follow_suggestions.dismiss": "Nie pokazuj ponownie", + "follow_suggestions.featured_longer": "Wybrane przez zespół {domain}", + "follow_suggestions.friends_of_friends_longer": "Popularni wśród ludzi których obserwujesz", "follow_suggestions.hints.featured": "Ten profil został wybrany przez zespół {domain}.", "follow_suggestions.hints.friends_of_friends": "Ten profil jest popularny w gronie użytkowników, których obserwujesz.", "follow_suggestions.hints.most_followed": "Ten profil jest jednym z najczęściej obserwowanych na {domain}.", @@ -314,6 +317,8 @@ "follow_suggestions.hints.similar_to_recently_followed": "Ten profil jest podobny do profili ostatnio przez ciebie zaobserwowanych.", "follow_suggestions.personalized_suggestion": "Sugestia spersonalizowana", "follow_suggestions.popular_suggestion": "Sugestia popularna", + "follow_suggestions.popular_suggestion_longer": "Popularni na {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Podobne do ostatnio zaobserwowanych przez ciebie profilów", "follow_suggestions.view_all": "Pokaż wszystkie", "follow_suggestions.who_to_follow": "Kogo obserwować", "followed_tags": "Obserwowane hasztagi", @@ -468,9 +473,22 @@ "notification.follow": "{name} obserwuje Cię", "notification.follow_request": "{name} chce cię zaobserwować", "notification.mention": "Wspomniało o Tobie przez {name}", + "notification.moderation-warning.learn_more": "Dowiedz się więcej", + "notification.moderation_warning": "Otrzymałeś/-łaś ostrzeżenie moderacyjne", + "notification.moderation_warning.action_delete_statuses": "Niektóre twoje wpisy zostały usunięte.", + "notification.moderation_warning.action_disable": "Twoje konto zostało wyłączone.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Niektóre twoje wpisy zostały oznaczone jako wrażliwe.", + "notification.moderation_warning.action_none": "Twoje konto otrzymało ostrzeżenie moderacyjne.", + "notification.moderation_warning.action_sensitive": "Twoje wpisy będą od teraz oznaczane jako wrażliwe.", + "notification.moderation_warning.action_silence": "Twoje konto zostało ograniczone.", + "notification.moderation_warning.action_suspend": "Twoje konto zostało zawieszone.", "notification.own_poll": "Twoje głosowanie zakończyło się", "notification.poll": "Głosowanie w którym brałeś(-aś) udział zakończyło się", "notification.reblog": "Twój post został podbity przez {name}", + "notification.relationships_severance_event": "Utracone związki z {name}", + "notification.relationships_severance_event.account_suspension": "Administrator z {from} zawiesił {target}, więc nie dostaniesz wieści ani nie wejdziesz w interakcje z użytkownikami z tego serwera.", + "notification.relationships_severance_event.domain_block": "Administrator z {from} zablokował {target}, w tym {followersCount} z Twoich obserwujących i {followingCount, plural, one {# konto} other {# konta}} które obserwujesz.", + "notification.relationships_severance_event.learn_more": "Dowiedz się więcej", "notification.status": "{name} opublikował(a) nowy wpis", "notification.update": "{name} edytował(a) post", "notification_requests.accept": "Akceptuj", @@ -483,6 +501,8 @@ "notifications.column_settings.admin.sign_up": "Nowe rejestracje:", "notifications.column_settings.alert": "Powiadomienia na pulpicie", "notifications.column_settings.favourite": "Ulubione:", + "notifications.column_settings.filter_bar.advanced": "Wyświetl wszystkie kategorie", + "notifications.column_settings.filter_bar.category": "Szybkie filtrowanie", "notifications.column_settings.follow": "Nowi obserwujący:", "notifications.column_settings.follow_request": "Nowe prośby o możliwość obserwacji:", "notifications.column_settings.mention": "Wspomnienia:", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index 28a18667a..6bda11058 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -89,8 +89,12 @@ "announcement.announcement": "Comunicados", "attachments_list.unprocessed": "(não processado)", "audio.hide": "Ocultar áudio", + "block_modal.remote_users_caveat": "Pediremos ao servidor {domínio} que respeite sua decisão. No entanto, a conformidade não é garantida pois alguns servidores podem lidar com os blocos de maneira diferente. As postagens públicas ainda podem estar visíveis para usuários não logados.", "block_modal.show_less": "Mostrar menos", "block_modal.show_more": "Mostrar mais", + "block_modal.they_cant_mention": "Eles não podem mencionar ou seguir você.", + "block_modal.they_cant_see_posts": "Eles não podem ver suas postagens e você não verá as deles.", + "block_modal.they_will_know": "Eles podem ver que estão bloqueados.", "block_modal.title": "Bloquear usuário?", "block_modal.you_wont_see_mentions": "Você não verá publicações que os mencionem.", "boost_modal.combo": "Pressione {combo} para pular isso na próxima vez", @@ -173,6 +177,7 @@ "confirmations.delete_list.message": "Você tem certeza de que deseja excluir esta lista?", "confirmations.discard_edit_media.confirm": "Descartar", "confirmations.discard_edit_media.message": "Há mudanças não salvas na descrição ou pré-visualização da mídia. Descartar assim mesmo?", + "confirmations.domain_block.confirm": "Servidor de blocos", "confirmations.domain_block.message": "Você tem certeza de que deseja bloquear tudo de {domain}? Você não verá mais o conteúdo desta instância em nenhuma linha do tempo pública ou nas suas notificações. Seus seguidores desta instância serão removidos.", "confirmations.edit.confirm": "Editar", "confirmations.edit.message": "Editar agora irá substituir a mensagem que está sendo criando. Tem certeza de que deseja continuar?", @@ -204,8 +209,27 @@ "dismissable_banner.explore_statuses": "Estas são postagens de toda a rede social que estão ganhando tração hoje. Postagens mais recentes com mais impulsos e favoritos têm classificações mais altas.", "dismissable_banner.explore_tags": "Estas hashtags estão ganhando popularidade no momento entre as pessoas deste e de outros servidores da rede descentralizada.", "dismissable_banner.public_timeline": "Estas são as publicações públicas mais recentes de pessoas na rede social que pessoas em {domain} seguem.", + "domain_block_modal.block": "Servidor de blocos.", + "domain_block_modal.block_account_instead": "Bloco @(nome)", "domain_block_modal.they_can_interact_with_old_posts": "Pessoas deste servidor podem interagir com suas publicações antigas.", "domain_block_modal.they_cant_follow": "Ninguém deste servidor pode lhe seguir.", + "domain_block_modal.they_wont_know": "Eles não saberão que foram bloqueados.", + "domain_block_modal.title": "Dominio do bloco", + "domain_block_modal.you_will_lose_followers": "Todos os seus seguidores deste servidor serão removidos.", + "domain_block_modal.you_wont_see_posts": "Você não verá postagens ou notificações de usuários neste servidor.", + "domain_pill.activitypub_lets_connect": "Ele permite que você se conecte e interaja com pessoas não apenas no Mastodon, mas também em diferentes aplicativos sociais.", + "domain_pill.activitypub_like_language": "ActivityPub é como a linguagem que o Mastodon fala com outras redes sociais.", + "domain_pill.server": "Servidor", + "domain_pill.their_handle": "Seu identificador:", + "domain_pill.their_server": "Sua casa digital, onde ficam todas as suas postagens.", + "domain_pill.their_username": "Seu identificador exclusivo em seu servidor. É possível encontrar usuários com o mesmo nome de usuário em servidores diferentes.", + "domain_pill.username": "Nome de usuário", + "domain_pill.whats_in_a_handle": "O que há em uma alça?", + "domain_pill.who_they_are": "Como os identificadores indicam quem alguém é e onde está, você pode interagir com pessoas na web social de .", + "domain_pill.who_you_are": "Como seu identificador indica quem você é e onde está, as pessoas podem interagir com você nas redes sociais das .", + "domain_pill.your_handle": "Seu identificador:", + "domain_pill.your_server": "Sua casa digital, onde ficam todas as suas postagens. Não gosta deste? Transfira servidores a qualquer momento e traga seus seguidores também.", + "domain_pill.your_username": "Seu identificador exclusivo neste servidor. É possível encontrar usuários com o mesmo nome de usuário em servidores diferentes.", "embed.instructions": "Incorpore este toot no seu site ao copiar o código abaixo.", "embed.preview": "Aqui está como vai ficar:", "emoji_button.activity": "Atividade", @@ -273,6 +297,8 @@ "filter_modal.select_filter.subtitle": "Use uma categoria existente ou crie uma nova", "filter_modal.select_filter.title": "Filtrar esta publicação", "filter_modal.title.status": "Filtrar uma publicação", + "filtered_notifications_banner.mentions": "{count, plural, one {menção} other {menções}}", + "filtered_notifications_banner.pending_requests": "Notificações de {count, plural, =0 {no one} one {one person} other {# people}} que você talvez conheça", "filtered_notifications_banner.title": "Notificações filtradas", "firehose.all": "Tudo", "firehose.local": "Este servidor", @@ -402,7 +428,9 @@ "loading_indicator.label": "Carregando…", "media_gallery.toggle_visible": "{number, plural, one {Ocultar mídia} other {Ocultar mídias}}", "moved_to_account_banner.text": "Sua conta {disabledAccount} está desativada porque você a moveu para {movedToAccount}.", + "mute_modal.hide_from_notifications": "Ocultar das notificações", "mute_modal.hide_options": "Ocultar opções", + "mute_modal.indefinite": "Até que eu os ative", "mute_modal.show_options": "Mostrar opções", "mute_modal.they_can_mention_and_follow": "Eles podem mencionar e seguir você, mas você não os verá.", "mute_modal.they_wont_know": "Eles não saberão que foram silenciados.", @@ -444,6 +472,11 @@ "notification.own_poll": "Sua enquete terminou", "notification.poll": "Uma enquete que você votou terminou", "notification.reblog": "{name} deu boost no teu toot", + "notification.relationships_severance_event": "Conexões perdidas com {name}", + "notification.relationships_severance_event.account_suspension": "Um administrador de {from} suspendeu {target}, o que significa que você não pode mais receber atualizações deles ou interagir com eles.", + "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": "Saber mais", + "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} acabou de tootar", "notification.update": "{name} editou uma publicação", "notification_requests.accept": "Aceitar", @@ -456,6 +489,8 @@ "notifications.column_settings.admin.sign_up": "Novas inscrições:", "notifications.column_settings.alert": "Notificações no computador", "notifications.column_settings.favourite": "Favoritos:", + "notifications.column_settings.filter_bar.advanced": "Exibir todas as categorias", + "notifications.column_settings.filter_bar.category": "Barra de filtro rápido", "notifications.column_settings.follow": "Seguidores:", "notifications.column_settings.follow_request": "Seguidores pendentes:", "notifications.column_settings.mention": "Menções:", @@ -481,7 +516,9 @@ "notifications.permission_denied": "Navegador não tem permissão para ativar notificações no computador.", "notifications.permission_denied_alert": "Verifique a permissão do navegador para ativar notificações no computador.", "notifications.permission_required": "Ativar notificações no computador exige permissão do navegador.", + "notifications.policy.filter_new_accounts.hint": "Created within the past {days, plural, one {one day} other {# days}}", "notifications.policy.filter_new_accounts_title": "Novas contas", + "notifications.policy.filter_not_followers_hint": "Including people who have been following you fewer than {days, plural, one {one day} other {# days}}", "notifications.policy.filter_not_followers_title": "Pessoas que não estão te seguindo", "notifications.policy.filter_not_following_hint": "Até que você os aprove manualmente", "notifications.policy.filter_not_following_title": "Pessoas que você não segue", @@ -569,6 +606,7 @@ "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "hoje", + "reply_indicator.attachments": "{count, plural, one {# attachment} other {# attachments}}", "reply_indicator.cancel": "Cancelar", "reply_indicator.poll": "Enquete", "report.block": "Bloquear", @@ -667,6 +705,7 @@ "status.edited_x_times": "Editado {count, plural, one {{count} hora} other {{count} vezes}}", "status.embed": "Incorporar", "status.favourite": "Favorita", + "status.favourites": "{count, plural, one {favorite} other {favorites}}", "status.filter": "Filtrar esta publicação", "status.filtered": "Filtrado", "status.hide": "Ocultar publicação", @@ -687,6 +726,7 @@ "status.reblog": "Dar boost", "status.reblog_private": "Dar boost para o mesmo público", "status.reblogged_by": "{name} deu boost", + "status.reblogs": "{count, plural, one {boost} other {boosts}}", "status.reblogs.empty": "Nada aqui. Quando alguém der boost, o usuário aparecerá aqui.", "status.redraft": "Excluir e rascunhar", "status.remove_bookmark": "Remover do Salvos", diff --git a/app/javascript/mastodon/locales/pt-PT.json b/app/javascript/mastodon/locales/pt-PT.json index d4b37ffe6..70903065d 100644 --- a/app/javascript/mastodon/locales/pt-PT.json +++ b/app/javascript/mastodon/locales/pt-PT.json @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Utilize uma categoria existente ou crie uma nova", "filter_modal.select_filter.title": "Filtrar esta publicação", "filter_modal.title.status": "Filtrar uma publicação", + "filtered_notifications_banner.mentions": "{count, plural, one {menção} other {menções}}", "filtered_notifications_banner.pending_requests": "Notificações de {count, plural, =0 {ninguém} one {uma pessoa} other {# pessoas}} que talvez conheça", "filtered_notifications_banner.title": "Notificações filtradas", "firehose.all": "Todas", @@ -307,6 +308,8 @@ "follow_requests.unlocked_explanation": "Apesar de a sua não ser privada, a administração de {domain} pensa que poderá querer rever manualmente os pedidos de seguimento dessas contas.", "follow_suggestions.curated_suggestion": "Escolha da equipe", "follow_suggestions.dismiss": "Não mostrar novamente", + "follow_suggestions.featured_longer": "Escolhido a dedo pela equipa de {domain}", + "follow_suggestions.friends_of_friends_longer": "Popular entre as pessoas que segue", "follow_suggestions.hints.featured": "Este perfil foi escolhido a dedo pela equipe {domain}.", "follow_suggestions.hints.friends_of_friends": "Este perfil é popular entre as pessoas que você segue.", "follow_suggestions.hints.most_followed": "Este perfil é um dos mais seguidos no {domain}.", @@ -314,6 +317,8 @@ "follow_suggestions.hints.similar_to_recently_followed": "Este perfil é semelhante aos perfis que você seguiu mais recentemente.", "follow_suggestions.personalized_suggestion": "Sugestão personalizada", "follow_suggestions.popular_suggestion": "Sugestão popular", + "follow_suggestions.popular_suggestion_longer": "Popular em {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Semelhantes aos perfis que seguiu recentemente", "follow_suggestions.view_all": "Ver tudo", "follow_suggestions.who_to_follow": "Quem seguir", "followed_tags": "Hashtags seguidas", @@ -468,9 +473,23 @@ "notification.follow": "{name} começou a seguir-te", "notification.follow_request": "{name} pediu para segui-lo", "notification.mention": "{name} mencionou-te", + "notification.moderation-warning.learn_more": "Saber mais", + "notification.moderation_warning": "Recebeu um aviso de moderação", + "notification.moderation_warning.action_delete_statuses": "Algumas das suas publicações foram removidas.", + "notification.moderation_warning.action_disable": "A sua conta foi desativada.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Algumas das suas publicações foram assinaladas como sensíveis.", + "notification.moderation_warning.action_none": "A sua conta recebeu um aviso de moderação.", + "notification.moderation_warning.action_sensitive": "As suas publicações serão, a partir de agora, assinaladas como sensíveis.", + "notification.moderation_warning.action_silence": "A sua conta foi limitada.", + "notification.moderation_warning.action_suspend": "A sua conta foi suspensa.", "notification.own_poll": "A sua votação terminou", "notification.poll": "Uma votação em que participaste chegou ao fim", "notification.reblog": "{name} reforçou a tua publicação", + "notification.relationships_severance_event": "Perdeu as ligações com {name}", + "notification.relationships_severance_event.account_suspension": "Um administrador de {from} suspendeu {target}, o que significa que já não pode receber atualizações dele ou interagir com ele.", + "notification.relationships_severance_event.domain_block": "Um administrador de {from} bloqueou {target}, incluindo {followersCount} dos seus seguidores e {followingCount, plural, one {# conta} other {# contas}} que segue.", + "notification.relationships_severance_event.learn_more": "Saber mais", + "notification.relationships_severance_event.user_domain_block": "Bloqueou {target}, removendo {followersCount} dos seus seguidores e {followingCount, plural, one {# conta} other {# contas}} que segue.", "notification.status": "{name} acabou de publicar", "notification.update": "{name} editou uma publicação", "notification_requests.accept": "Aceitar", @@ -483,6 +502,8 @@ "notifications.column_settings.admin.sign_up": "Novas inscrições:", "notifications.column_settings.alert": "Notificações no ambiente de trabalho", "notifications.column_settings.favourite": "Favoritos:", + "notifications.column_settings.filter_bar.advanced": "Mostrar todas as categorias", + "notifications.column_settings.filter_bar.category": "Barra de filtros rápidos", "notifications.column_settings.follow": "Novos seguidores:", "notifications.column_settings.follow_request": "Novos pedidos de seguidor:", "notifications.column_settings.mention": "Menções:", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index 7a60f3bb7..cd09a505b 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -89,6 +89,14 @@ "announcement.announcement": "Объявление", "attachments_list.unprocessed": "(не обработан)", "audio.hide": "Скрыть аудио", + "block_modal.remote_users_caveat": "Мы попросим сервер {domain} уважать ваше решение. Однако, соблюдение требований не гарантировано, поскольку некоторые серверы могут работать с блокировками по-разному. Публичные записи по-прежнему могут быть видны неавторизованным пользователям.", + "block_modal.show_less": "Показать меньше", + "block_modal.show_more": "Показать больше", + "block_modal.they_cant_mention": "Он не может упоминать или подписываться на вас.", + "block_modal.they_cant_see_posts": "Он не может видеть ваши сообщения, и вы не увидите его.", + "block_modal.they_will_know": "Он может видеть, что он заблокирован.", + "block_modal.title": "Заблокировать пользователя?", + "block_modal.you_wont_see_mentions": "Вы не увидите записи, которые упоминают его.", "boost_modal.combo": "{combo}, чтобы пропустить это в следующий раз", "bundle_column_error.copy_stacktrace": "Скопировать отчет об ошибке", "bundle_column_error.error.body": "Запрошенная страница не может быть отображена. Это может быть вызвано ошибкой в нашем коде или проблемой совместимости браузера.", @@ -169,6 +177,7 @@ "confirmations.delete_list.message": "Вы действительно хотите навсегда удалить этот список?", "confirmations.discard_edit_media.confirm": "Отменить", "confirmations.discard_edit_media.message": "У вас есть несохранённые изменения описания мультимедиа или предпросмотра, отменить их?", + "confirmations.domain_block.confirm": "Заблокировать сервер", "confirmations.domain_block.message": "Вы точно уверены, что хотите заблокировать {domain} полностью? В большинстве случаев нескольких блокировок и игнорирований вполне достаточно. Вы перестанете видеть публичную ленту и уведомления оттуда. Ваши подписчики из этого домена будут удалены.", "confirmations.edit.confirm": "Редактировать", "confirmations.edit.message": "В данный момент, редактирование перезапишет составляемое вами сообщение. Вы уверены, что хотите продолжить?", @@ -200,6 +209,27 @@ "dismissable_banner.explore_statuses": "Эти сообщения со связанных серверов сети сейчас набирают популярность.", "dismissable_banner.explore_tags": "Эти хэштеги привлекают людей на этом и других серверах децентрализованной сети прямо сейчас.", "dismissable_banner.public_timeline": "Это самые последние публичные сообщения от людей в социальной сети, за которыми подписались пользователи {domain}.", + "domain_block_modal.block": "Заблокировать сервер", + "domain_block_modal.block_account_instead": "Заблокировать @{name} вместо", + "domain_block_modal.they_can_interact_with_old_posts": "Люди с этого сервера могут взаимодействовать с вашими старыми записями.", + "domain_block_modal.they_cant_follow": "Никто из этого сервера не может подписываться на вас.", + "domain_block_modal.they_wont_know": "Он не будет знать, что его заблокировали.", + "domain_block_modal.title": "Заблокировать домен?", + "domain_block_modal.you_will_lose_followers": "Все ваши подписчики с этого сервера будут удалены.", + "domain_block_modal.you_wont_see_posts": "Вы не будете видеть записи или уведомления от пользователей на этом сервере.", + "domain_pill.activitypub_lets_connect": "Это позволяет вам общаться и взаимодействовать с людьми не только на Mastodon, но и в различных социальных приложениях.", + "domain_pill.activitypub_like_language": "ActivityPub как язык Mastodon говорит с другими социальными сетями.", + "domain_pill.server": "Сервер", + "domain_pill.their_handle": "Его бейдж:", + "domain_pill.their_server": "Цифровой дом, где находятся все записи.", + "domain_pill.their_username": "Уникальный идентификатор на сервере. Возможно найти пользователей с одним и тем же именем пользователя на разных серверах.", + "domain_pill.username": "Имя пользователя", + "domain_pill.whats_in_a_handle": "Что такое бейдж?", + "domain_pill.who_they_are": "Поскольку бейджи говорят о том, кто и где находится, вы можете взаимодействовать с людьми в социальной сети .", + "domain_pill.who_you_are": "Поскольку ваш бейдж говорит о том, кто вы и где находитесь, люди могут взаимодействовать с вами через социальную сеть .", + "domain_pill.your_handle": "Ваш бейдж:", + "domain_pill.your_server": "Сервер, где живут все ваши посты. Этот не нравится? Поменяй сервер в любое время вместе со своими подписчиками.", + "domain_pill.your_username": "Ваш уникальный идентификатор на этом сервере. Вы можете найти пользователей с одним именем пользователя на разных серверах.", "embed.instructions": "Встройте этот пост на свой сайт, скопировав следующий код:", "embed.preview": "Так это будет выглядеть:", "emoji_button.activity": "Занятия", @@ -236,6 +266,7 @@ "empty_column.list": "В этом списке пока ничего нет.", "empty_column.lists": "У вас ещё нет списков. Созданные вами списки будут показаны здесь.", "empty_column.mutes": "Вы ещё никого не добавляли в список игнорируемых.", + "empty_column.notification_requests": "Здесь ничего нет! Когда вы получите новые уведомления, они здесь появятся согласно вашим настройкам.", "empty_column.notifications": "У вас пока нет уведомлений. Взаимодействуйте с другими, чтобы завести разговор.", "empty_column.public": "Здесь ничего нет! Опубликуйте что-нибудь или подпишитесь на пользователей с других узлов, чтобы заполнить ленту", "error.unexpected_crash.explanation": "Из-за несовместимого браузера или ошибки в нашем коде, эта страница не может быть корректно отображена.", @@ -266,13 +297,21 @@ "filter_modal.select_filter.subtitle": "Используйте существующую категорию или создайте новую", "filter_modal.select_filter.title": "Фильтровать этот пост", "filter_modal.title.status": "Фильтровать пост", + "filtered_notifications_banner.pending_requests": "Уведомления от {count, plural, =0 {никого} one {# человека} other {# других людей, с кем вы можете быть знакомы}}", + "filtered_notifications_banner.title": "Отфильтрованные уведомления", "firehose.all": "Все", "firehose.local": "Текущий сервер", "firehose.remote": "Другие серверы", "follow_request.authorize": "Авторизовать", "follow_request.reject": "Отказать", "follow_requests.unlocked_explanation": "Хотя ваша учетная запись не закрыта, команда {domain} подумала, что вы захотите просмотреть запросы от этих учетных записей вручную.", + "follow_suggestions.curated_suggestion": "Выбор администрации", "follow_suggestions.dismiss": "Больше не показывать", + "follow_suggestions.hints.featured": "Этот профиль был вручную выбран командой {domain}.", + "follow_suggestions.hints.friends_of_friends": "Этот профиль популярен среди людей, на которых вы подписаны.", + "follow_suggestions.hints.most_followed": "Этот профиль один из самых отслеживаемых на {domain}.", + "follow_suggestions.hints.most_interactions": "Этот профиль в последнее время привлекает много внимания на {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Этот профиль похож на другие профили, на которые вы подписывались в последнее время.", "follow_suggestions.personalized_suggestion": "Персонализированное предложение", "follow_suggestions.popular_suggestion": "Популярное предложение", "follow_suggestions.view_all": "Посмотреть все", @@ -388,6 +427,15 @@ "loading_indicator.label": "Загрузка…", "media_gallery.toggle_visible": "Показать/скрыть {number, plural, =1 {изображение} other {изображения}}", "moved_to_account_banner.text": "Ваша учетная запись {disabledAccount} в настоящее время заморожена, потому что вы переехали на {movedToAccount}.", + "mute_modal.hide_from_notifications": "Скрыть из уведомлений", + "mute_modal.hide_options": "Скрыть параметры", + "mute_modal.indefinite": "Пока я не разблокирую их", + "mute_modal.show_options": "Показать опции", + "mute_modal.they_can_mention_and_follow": "Они могут упоминать и следить за вами, но вы не будете их видеть.", + "mute_modal.they_wont_know": "Они не будут знать, что их заглушили.", + "mute_modal.title": "Заглушить пользователя?", + "mute_modal.you_wont_see_mentions": "Вы не увидите постов, которые их упоминают.", + "mute_modal.you_wont_see_posts": "Они по-прежнему смогут видеть ваши посты, но вы не сможете видеть их посты.", "navigation_bar.about": "О проекте", "navigation_bar.advanced_interface": "Включить многоколоночный интерфейс", "navigation_bar.blocks": "Заблокированные пользователи", @@ -423,8 +471,17 @@ "notification.own_poll": "Ваш опрос закончился", "notification.poll": "Опрос, в котором вы приняли участие, завершился", "notification.reblog": "{name} продвинул(а) ваш пост", + "notification.relationships_severance_event": "Потеряно соединение с {name}", + "notification.relationships_severance_event.account_suspension": "Администратор {from} заблокировал {target}, что означает, что вы больше не сможете получать обновления от них или взаймодествовать с ними.", + "notification.relationships_severance_event.domain_block": "Администратор {from} заблокировал {target} включая {followersCount} ваших подписчиков и {followingCount, plural, one {# аккаунт} few {# аккаунта} other {# аккаунтов}}, на которые вы подписаны.", + "notification.relationships_severance_event.learn_more": "Узнать больше", + "notification.relationships_severance_event.user_domain_block": "Вы заблокировали {target} включая {followersCount} ваших подписчиков и {followingCount, plural, one {# аккаунт} few {# аккаунта} other {# аккаунтов}}, на которые вы подписаны.", "notification.status": "{name} только что запостил", "notification.update": "{name} изменил(а) пост", + "notification_requests.accept": "Принять", + "notification_requests.dismiss": "Отклонить", + "notification_requests.notifications_from": "Уведомления от {name}", + "notification_requests.title": "Отфильтрованные уведомления", "notifications.clear": "Очистить уведомления", "notifications.clear_confirmation": "Вы уверены, что хотите очистить все уведомления?", "notifications.column_settings.admin.report": "Новые жалобы:", @@ -456,6 +513,7 @@ "notifications.permission_denied": "Уведомления на рабочем столе недоступны, так как вы запретили их отправку в браузере. Проверьте настройки для сайта, чтобы включить их обратно.", "notifications.permission_denied_alert": "Уведомления на рабочем столе недоступны, так как вы ранее отклонили запрос на их отправку.", "notifications.permission_required": "Чтобы включить уведомления на рабочем столе, необходимо разрешить их в браузере.", + "notifications.policy.filter_new_accounts_title": "Новые учётные записи", "notifications_permission_banner.enable": "Включить уведомления", "notifications_permission_banner.how_to_control": "Получайте уведомления даже когда Mastodon закрыт, включив уведомления на рабочем столе. А чтобы лишний шум не отвлекал, вы можете настроить какие уведомления вы хотите получать, нажав на кнопку {icon} выше.", "notifications_permission_banner.title": "Будьте в курсе происходящего", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index dd21d3030..d143fda52 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -406,6 +406,7 @@ "loading_indicator.label": "Načítavanie…", "media_gallery.toggle_visible": "{number, plural, one {Skryť obrázok} other {Skryť obrázky}}", "moved_to_account_banner.text": "Váš účet {disabledAccount} je momentálne deaktivovaný, pretože ste sa presunuli na {movedToAccount}.", + "mute_modal.hide_from_notifications": "Ukryť z upozornení", "mute_modal.hide_options": "Skryť možnosti", "mute_modal.show_options": "Zobraziť možnosti", "mute_modal.title": "Stíšiť užívateľa?", @@ -444,6 +445,7 @@ "notification.own_poll": "Vaša anketa sa skončila", "notification.poll": "Anketa, v ktorej ste hlasovali, sa skončila", "notification.reblog": "{name} zdieľa váš príspevok", + "notification.relationships_severance_event.learn_more": "Zisti viac", "notification.status": "{name} uverejňuje niečo nové", "notification.update": "{name} upravuje príspevok", "notification_requests.accept": "Prijať", @@ -456,6 +458,7 @@ "notifications.column_settings.admin.sign_up": "Nové registrácie:", "notifications.column_settings.alert": "Upozornenia na ploche", "notifications.column_settings.favourite": "Ohviezdičkované:", + "notifications.column_settings.filter_bar.advanced": "Zobraziť všetky kategórie", "notifications.column_settings.follow": "Nové sledovania od:", "notifications.column_settings.follow_request": "Nové žiadosti o sledovanie od:", "notifications.column_settings.mention": "Označenia:", @@ -555,7 +558,6 @@ "refresh": "Obnoviť", "regeneration_indicator.label": "Načítavanie…", "regeneration_indicator.sublabel": "Váš domovský kanál sa pripravuje.", - "relationship_severance_notification.view": "Zobraziť", "relative_time.days": "{number} dní", "relative_time.full.days": "Pred {number, plural, one {# dňom} other {# dňami}}", "relative_time.full.hours": "Pred {number, plural, one {# hodinou} other {# hodinami}}", diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json index d31b41080..ed4fa8dfa 100644 --- a/app/javascript/mastodon/locales/sl.json +++ b/app/javascript/mastodon/locales/sl.json @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Uporabite obstoječo kategorijo ali ustvarite novo", "filter_modal.select_filter.title": "Filtriraj to objavo", "filter_modal.title.status": "Filtrirajte objavo", + "filtered_notifications_banner.mentions": "{count, plural, one {omemba} two {omembi} few {omembe} other {omemb}}", "filtered_notifications_banner.pending_requests": "Obvestila od {count, plural, =0 {nikogar, ki bi ga} one {# človeka, ki bi ga} two {# ljudi, ki bi ju} few {# ljudi, ki bi jih} other {# ljudi, ki bi jih}} lahko poznali", "filtered_notifications_banner.title": "Filtrirana obvestila", "firehose.all": "Vse", @@ -471,7 +472,11 @@ "notification.own_poll": "Vaša anketa je zaključena", "notification.poll": "Anketa, v kateri ste sodelovali, je zaključena", "notification.reblog": "{name} je izpostavila/a vašo objavo", - "notification.severed_relationships": "Veze z {name} prekinjene", + "notification.relationships_severance_event": "Povezave z {name} prekinjene", + "notification.relationships_severance_event.account_suspension": "Skrbnik na {from} je suspendiral račun {target}, kar pomeni, da od računa ne morete več prejemati posodobitev ali imeti z njim interakcij.", + "notification.relationships_severance_event.domain_block": "Skrbnik na {from} je blokiral domeno {target}, vključno z vašimi sledilci ({followersCount}) in {followingCount, plural, one {# računom, ki mu sledite} two {# računoma, ki jima sledite} few {# računi, ki jim sledite} other {# računi, ki jim sledite}}.", + "notification.relationships_severance_event.learn_more": "Več o tem", + "notification.relationships_severance_event.user_domain_block": "Blokirali ste domeno {target}, vključno z vašimi sledilci ({followersCount}) in {followingCount, plural, one {# računom, ki mu sledite} two {# računoma, ki jima sledite} few {# računi, ki jim sledite} other {# računi, ki jim sledite}}.", "notification.status": "{name} je pravkar objavil/a", "notification.update": "{name} je uredil(a) objavo", "notification_requests.accept": "Sprejmi", @@ -484,6 +489,8 @@ "notifications.column_settings.admin.sign_up": "Novi vpisi:", "notifications.column_settings.alert": "Namizna obvestila", "notifications.column_settings.favourite": "Priljubljeni:", + "notifications.column_settings.filter_bar.advanced": "Prikaži vse kategorije", + "notifications.column_settings.filter_bar.category": "Vrstica za hitro filtriranje", "notifications.column_settings.follow": "Novi sledilci:", "notifications.column_settings.follow_request": "Nove prošnje za sledenje:", "notifications.column_settings.mention": "Omembe:", @@ -588,12 +595,6 @@ "refresh": "Osveži", "regeneration_indicator.label": "Nalaganje …", "regeneration_indicator.sublabel": "Vaš domači vir se pripravlja!", - "relationship_severance_notification.purged_data": "očistili skrbniki", - "relationship_severance_notification.relationships": "{count, plural, one {# veza} two {# vezi} few {# veze} other {# vez}}", - "relationship_severance_notification.types.account_suspension": "Račun je bil suspendiran", - "relationship_severance_notification.types.domain_block": "Domena je bila suspendirana", - "relationship_severance_notification.types.user_domain_block": "Domeno ste blokirali", - "relationship_severance_notification.view": "Pogled", "relative_time.days": "{number} d", "relative_time.full.days": "{number, plural, one {pred # dnem} two {pred # dnevoma} few {pred # dnevi} other {pred # dnevi}}", "relative_time.full.hours": "{number, plural, one {pred # uro} two {pred # urama} few {pred # urami} other {pred # urami}}", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index a5122d098..da35b3d43 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Përdorni një kategori ekzistuese, ose krijoni një të re", "filter_modal.select_filter.title": "Filtroje këtë postim", "filter_modal.title.status": "Filtroni një postim", + "filtered_notifications_banner.pending_requests": "Njoftime prej {count, plural, =0 {askujt} one {një personi} other {# vetësh}} që mund të njihni", "filtered_notifications_banner.title": "Njoftime të filtruar", "firehose.all": "Krejt", "firehose.local": "Këtë shërbyes", @@ -470,7 +471,11 @@ "notification.own_poll": "Pyetësori juaj ka përfunduar", "notification.poll": "Ka përfunduar një pyetësor ku keni votuar", "notification.reblog": "{name} përforcoi mesazhin tuaj", - "notification.severed_relationships": "Marrëdhëniet me {name} u ndërprenë", + "notification.relationships_severance_event": "Lidhje të humbura me {name}", + "notification.relationships_severance_event.account_suspension": "Një përgjegjës nga {from} ka pezulluar {target}, që do të thotë se s’mund të merrni më përditësime prej tij, apo të ndërveproni me të.", + "notification.relationships_severance_event.domain_block": "Një përgjegjës nga {from} ka bllokuar {target}, përfshi {followersCount} të ndjekësve tuaj dhe {followingCount, plural, one {# llogari} other {# llogari}} që ndiqni.", + "notification.relationships_severance_event.learn_more": "Mësoni më tepër", + "notification.relationships_severance_event.user_domain_block": "Keni bllokuar {target}, duke hequr {followersCount} nga ndjekësit tuaj dhe {followingCount, plural, one {# llogari} other {# llogari}} që ndiqni.", "notification.status": "{name} sapo postoi", "notification.update": "{name} përpunoi një postim", "notification_requests.accept": "Pranoje", @@ -483,6 +488,8 @@ "notifications.column_settings.admin.sign_up": "Regjistrime të reja:", "notifications.column_settings.alert": "Njoftime desktopi", "notifications.column_settings.favourite": "Të parapëlqyer:", + "notifications.column_settings.filter_bar.advanced": "Shfaq krejt kategoritë", + "notifications.column_settings.filter_bar.category": "Shtyllë filtrimesh të shpejta", "notifications.column_settings.follow": "Ndjekës të rinj:", "notifications.column_settings.follow_request": "Kërkesa të reja për ndjekje:", "notifications.column_settings.mention": "Përmendje:", @@ -508,7 +515,9 @@ "notifications.permission_denied": "S’merren dot njoftime në desktop, ngaqë më herët shfletuesit i janë mohuar lejet për këtë", "notifications.permission_denied_alert": "S’mund të aktivizohen njoftimet në desktop, ngaqë lejet e shfletuesit për këtë janë mohuar më herët", "notifications.permission_required": "S’merren dot njoftime desktop, ngaqë s’është akorduar leja përkatëse.", + "notifications.policy.filter_new_accounts.hint": "Krijuar brenda {days, plural, one {një dite} other {# ditësh}} të shkuara", "notifications.policy.filter_new_accounts_title": "Llogari të reja", + "notifications.policy.filter_not_followers_hint": "Përfshi persona që ju kanë ndjekur brenda më pak se {days, plural, one {një dite} other {# ditësh}}", "notifications.policy.filter_not_followers_title": "Persona që s’ju ndjekin", "notifications.policy.filter_not_following_hint": "Deri sa t’i miratoni dorazi", "notifications.policy.filter_not_following_title": "Persona që s’i ndiqni", @@ -585,12 +594,6 @@ "refresh": "Rifreskoje", "regeneration_indicator.label": "Po ngarkohet…", "regeneration_indicator.sublabel": "Prurja juaj vetjake po përgatitet!", - "relationship_severance_notification.purged_data": "spastruar nga përgjegjës", - "relationship_severance_notification.relationships": "{count, plural, one {# marrëdhënie} other {# marrëdhënie}}", - "relationship_severance_notification.types.account_suspension": "Llogaria është pezulluar", - "relationship_severance_notification.types.domain_block": "Përkatësia është pezulluar", - "relationship_severance_notification.types.user_domain_block": "E bllokuat këtë përkatësi", - "relationship_severance_notification.view": "Shiheni", "relative_time.days": "{number}d", "relative_time.full.days": "{number, plural, one {# ditë} other {# ditë}} më parë", "relative_time.full.hours": "{number, plural, one {# orë} other {# orë}} më parë", diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json index 2d795c76c..3eea87d5e 100644 --- a/app/javascript/mastodon/locales/sr-Latn.json +++ b/app/javascript/mastodon/locales/sr-Latn.json @@ -13,14 +13,14 @@ "about.rules": "Pravila servera", "account.account_note_header": "Napomena", "account.add_or_remove_from_list": "Dodaj ili ukloni sa lista", - "account.badges.bot": "Bot", + "account.badges.bot": "Automatizovano", "account.badges.group": "Grupa", "account.block": "Blokiraj @{name}", "account.block_domain": "Blokiraj domen {domain}", "account.block_short": "Blokiraj", "account.blocked": "Blokiran", "account.browse_more_on_origin_server": "Pregledajte još na originalnom profilu", - "account.cancel_follow_request": "Povuci zahtev za praćenje", + "account.cancel_follow_request": "Otkaži praćenje", "account.copy": "Kopiraj vezu u profil", "account.direct": "Privatno pomeni @{name}", "account.disable_notifications": "Zaustavi obaveštavanje za objave korisnika @{name}", @@ -89,6 +89,14 @@ "announcement.announcement": "Najava", "attachments_list.unprocessed": "(neobrađeno)", "audio.hide": "Sakrij audio", + "block_modal.remote_users_caveat": "Zamolićemo server {domain} da poštuje vašu odluku. Međutim, usklađenost nije zagarantovana jer neki serveri mogu drugačije da obrađuju blokove. Javne objave mogu i dalje biti vidljive korisnicima koji nisu prijavljeni.", + "block_modal.show_less": "Prikaži manje", + "block_modal.show_more": "Prikaži više", + "block_modal.they_cant_mention": "Ne mogu da vas pominju ili prate.", + "block_modal.they_cant_see_posts": "Ne mogu da vide vaše objave, a vi nećete videti njihove.", + "block_modal.they_will_know": "Mogu da vide da su blokirani.", + "block_modal.title": "Blokirati korisnika?", + "block_modal.you_wont_see_mentions": "Nećete videti objave koje ih pominju.", "boost_modal.combo": "Možete pritisnuti {combo} da preskočite ovo sledeći put", "bundle_column_error.copy_stacktrace": "Kopiraj izveštaj o grešci", "bundle_column_error.error.body": "Nije moguće prikazati traženu stranicu. Razlog može biti greška u našem kodu ili problem sa kompatibilnošću pretraživača.", @@ -153,7 +161,7 @@ "compose_form.poll.switch_to_single": "Promenite anketu da biste omogućili jedan izbor", "compose_form.poll.type": "Stil", "compose_form.publish": "Objavi", - "compose_form.publish_form": "Objavi", + "compose_form.publish_form": "Nova objava", "compose_form.reply": "Odgovori", "compose_form.save_changes": "Ažuriraj", "compose_form.spoiler.marked": "Ukloni upozorenje o sadržaju", @@ -169,6 +177,7 @@ "confirmations.delete_list.message": "Da li ste sigurni da želite da trajno izbrišete ovu listu?", "confirmations.discard_edit_media.confirm": "Odbaci", "confirmations.discard_edit_media.message": "Imate nesačuvane promene u opisu ili pregledu medija, da li ipak hoćete da ih odbacite?", + "confirmations.domain_block.confirm": "Blokiraj server", "confirmations.domain_block.message": "Da li ste zaista sigurni da želite da blokirate ceo domen {domain}? U većini slučajeva, dovoljno je i poželjno nekoliko ciljanih blokiranja ili ignorisanja. Nećete videti sadržaj sa tog domena ni u jednoj javnoj vremenskoj liniji ili u vašim obaveštenjima. Vaši pratioci sa tog domena će biti uklonjeni.", "confirmations.edit.confirm": "Uredi", "confirmations.edit.message": "Uređivanjem će se obrisati poruka koju trenutno sastavljate. Da li ste sigurni da želite da nastavite?", @@ -196,10 +205,31 @@ "disabled_account_banner.text": "Vaš nalog {disabledAccount} je trenutno onemogućen.", "dismissable_banner.community_timeline": "Ovo su najnovije javne objave ljudi čije naloge hostuje {domain}.", "dismissable_banner.dismiss": "Odbaci", - "dismissable_banner.explore_links": "O ovim vestima trenutno razgovaraju ljudi na ovom i drugim serverima decentralizovane mreže.", + "dismissable_banner.explore_links": "Ovo su vesti koje se danas najviše dele na društvenoj mreži. Novije vesti koje je objavilo više različitih ljudi su bolje rangirane.", "dismissable_banner.explore_statuses": "Ovo su objave širom društvenog veba koje danas postaju sve popularnije. Novije objave sa više podržavanja i omiljene su rangirane više.", - "dismissable_banner.explore_tags": "Ove heš oznake postaju sve popularnije među ljudima na ovom i drugim serverima decentralizovane mreže.", + "dismissable_banner.explore_tags": "Ovo su heš oznake koje danas postaju sve popularnije na društvenoj mreži. Heš oznake koje koristi više različitih ljudi su rangirane više.", "dismissable_banner.public_timeline": "Ovo su najnovije javne objave ljudi sa društvenog veba koje ljudi na {domain}-u prate.", + "domain_block_modal.block": "Blokiraj server", + "domain_block_modal.block_account_instead": "Umesto toga, blokiraj @{name}", + "domain_block_modal.they_can_interact_with_old_posts": "Ljudi sa ovog servera mogu da imaju interakciju sa vašim starim objavama.", + "domain_block_modal.they_cant_follow": "Niko sa ovog servera ne može da vas prati.", + "domain_block_modal.they_wont_know": "Neće znati da su blokirani.", + "domain_block_modal.title": "Blokirati domen?", + "domain_block_modal.you_will_lose_followers": "Svi vaši pratioci sa ovog servera će biti uklonjeni.", + "domain_block_modal.you_wont_see_posts": "Nećete videti objave ili obaveštenja korisnika na ovom serveru.", + "domain_pill.activitypub_lets_connect": "Omogućuje vam da se povežete i komunicirate sa ljudima ne samo na Mastodon-u, već i u različitim društvenim aplikacijama.", + "domain_pill.activitypub_like_language": "ActivityPub je kao jezik kojim Mastodon govori sa drugim društvenim mrežama.", + "domain_pill.server": "Server", + "domain_pill.their_handle": "Njegov regulator:", + "domain_pill.their_server": "Njihov digitalni dom, gde žive sve njihove objave.", + "domain_pill.their_username": "Njihov jedinstveni identifikator na njihovom serveru. Moguće je pronaći korisnike sa istim korisničkim imenom na različitim serverima.", + "domain_pill.username": "Korisničko ime", + "domain_pill.whats_in_a_handle": "Šta je regulator?", + "domain_pill.who_they_are": "Pošto regulatori govore ko je neko i gde se nalazi, možete da komunicirate sa ljudima širom društvenog veba na .", + "domain_pill.who_you_are": "Pošto vaši regulatori govori ko ste i gde ste, ljudi mogu da komuniciraju sa vama širom društvenog veba na .", + "domain_pill.your_handle": "Vaš regulator:", + "domain_pill.your_server": "Vaš digitalni dom, gde žive sve vaše objave. Ne sviđa vam se ovaj? Prenesite servere u bilo koje vreme i dovedite i svoje pratioce.", + "domain_pill.your_username": "Njihov jedinstveni identifikator na njihovom serveru. Moguće je pronaći korisnike sa istim korisničkim imenom na različitim serverima.", "embed.instructions": "Ugradite ovu objavu na svoj veb sajt kopiranjem koda ispod.", "embed.preview": "Evo kako će to izgledati:", "emoji_button.activity": "Aktivnosti", @@ -232,11 +262,11 @@ "empty_column.follow_requests": "Još uvek nemate nijedan zahtev za praćenje. Kada primite zahtev, on će se pojaviti ovde.", "empty_column.followed_tags": "Još uvek niste zapratili nijednu heš oznaku. Kada to uradite, one će se pojaviti ovde.", "empty_column.hashtag": "Još uvek nema ničega u ovoj heš oznaci.", - "empty_column.home": "Vaša početna vremenska linija je prazna! Pratite više ljudi da biste je popunili. {suggestions}", + "empty_column.home": "Vaša početna vremenska linija je prazna! Pratite više ljudi da biste je popunili.", "empty_column.list": "U ovoj listi još nema ničega. Kada članovi ove liste objave nešto novo, pojaviće se ovde.", "empty_column.lists": "Još uvek nemate nijednu listu. Kada napravite jednu, ona će se pojaviti ovde.", "empty_column.mutes": "Još uvek ne ignorišete nijednog korisnika.", - "empty_column.notification_requests": "Sve je čisto! Ovde nema ničega. Kada dobijete nova obaveštenja, ona će se pojaviti ovde u skladu sa vašim podešavanjima.", + "empty_column.notification_requests": "Sve je čisto! Ovde nema ničega. Kada dobijete nova obaveštenja, ona će se pojaviti ovde u skladu sa vašim podešavanjima.", "empty_column.notifications": "Još uvek nemate nikakva obaveštenja. Kada drugi ljudi budu u interakciji sa vama, videćete to ovde.", "empty_column.public": "Ovde nema ničega! Napišite nešto javno ili ručno pratite korisnike sa drugih servera da biste ovo popunili", "error.unexpected_crash.explanation": "Zbog greške u našem kodu ili problema sa kompatibilnošću pregledača, ova stranica se nije mogla pravilno prikazati.", @@ -267,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Koristite postojeću kategoriju ili kreirajte novu", "filter_modal.select_filter.title": "Filtriraj ovu objavu", "filter_modal.title.status": "Filtriraj objavu", + "filtered_notifications_banner.mentions": "{count, plural, one {pominjanje} few {pominjanja} other {pominjanja}}", "filtered_notifications_banner.pending_requests": "Obaveštenja od {count, plural, =0 {nikoga koga možda poznajete} one {# osobe koju možda poznajete} few {# osobe koje možda poznajete} other {# osoba koje možda poznajete}}", "filtered_notifications_banner.title": "Filtrirana obaveštenja", "firehose.all": "Sve", @@ -279,7 +310,7 @@ "follow_suggestions.dismiss": "Ne prikazuj ponovo", "follow_suggestions.hints.featured": "Ovaj profil je ručno izabrao tim {domain}.", "follow_suggestions.hints.friends_of_friends": "Ovaj profil je popularan među ljudima koje pratite.", - "follow_suggestions.hints.most_followed": "Ovaj profil je jedan od najpraćenijih na {domain}.", + "follow_suggestions.hints.most_followed": "Ovaj profil je jedan od najpraćenijih na {domain}.", "follow_suggestions.hints.most_interactions": "Ovaj profil je nedavno dobio veliku pažnju na {domain}.", "follow_suggestions.hints.similar_to_recently_followed": "Ovaj profil je sličan profilima koje ste nedavno zapratili.", "follow_suggestions.personalized_suggestion": "Personalizovani predlog", @@ -315,7 +346,7 @@ "home.column_settings.show_reblogs": "Prikaži podržavanja", "home.column_settings.show_replies": "Prikaži odgovore", "home.hide_announcements": "Sakrij najave", - "home.pending_critical_update.body": "Ažurirajte svoj Mastodon server što je pre moguće!", + "home.pending_critical_update.body": "Ažurirajte svoj Mastodon server što je pre moguće!", "home.pending_critical_update.link": "Pogledajte ažuriranja", "home.pending_critical_update.title": "Dostupno je kritično bezbednosno ažuriranje!", "home.show_announcements": "Prijaži najave", @@ -329,7 +360,7 @@ "interaction_modal.on_another_server": "Na drugom serveru", "interaction_modal.on_this_server": "Na ovom serveru", "interaction_modal.sign_in": "Niste prijavljeni na ovaj server. Gde je hostovan vaš nalog?", - "interaction_modal.sign_in_hint": "Savet: To je veb sajt na kome ste se registrovali. Ako se ne sećate, potražite e-poruku dobrodošlice u svom prijemnom sandučetu. Takođe možete uneti svoje puno korisničko ime! (npr. @Mastodon@mastodon.social)", + "interaction_modal.sign_in_hint": "Savet: To je veb sajt na kome ste se registrovali. Ako se ne sećate, potražite e-poruku dobrodošlice u svom prijemnom sandučetu. Takođe možete uneti svoje puno korisničko ime! (npr. @Mastodon@mastodon.social)", "interaction_modal.title.favourite": "Označi objavu korisnika {name} kao omiljenu", "interaction_modal.title.follow": "Zaprati {name}", "interaction_modal.title.reblog": "Podrži objavu korisnika {name}", @@ -397,6 +428,15 @@ "loading_indicator.label": "Učitavanje…", "media_gallery.toggle_visible": "{number, plural, one {Sakrij sliku} few {Sakrij slike} other {Sakrij slike}}", "moved_to_account_banner.text": "Vaš nalog {disabledAccount} je trenutno onemogućen jer ste prešli na {movedToAccount}.", + "mute_modal.hide_from_notifications": "Sakrij iz obaveštenja", + "mute_modal.hide_options": "Sakrij opcije", + "mute_modal.indefinite": "Dok ih ne uklonim iz ignorisanih", + "mute_modal.show_options": "Prikaži opcije", + "mute_modal.they_can_mention_and_follow": "Mogu da vas pominju i prate, ali ih nećete videti.", + "mute_modal.they_wont_know": "Neće znati da su ignorisani.", + "mute_modal.title": "Ignorisati korisnika?", + "mute_modal.you_wont_see_mentions": "Nećete videti objave koje ga pominju.", + "mute_modal.you_wont_see_posts": "I dalje može da vidi vaše objave, ali vi nećete videti njegove.", "navigation_bar.about": "Osnovni podaci", "navigation_bar.advanced_interface": "Otvori u naprednom veb okruženju", "navigation_bar.blocks": "Blokirani korisnici", @@ -432,6 +472,11 @@ "notification.own_poll": "Vaša anketa je završena", "notification.poll": "Završena je anketa u kojoj ste glasali", "notification.reblog": "{name} je podržao vašu objavu", + "notification.relationships_severance_event": "Izgubljena veza sa {name}", + "notification.relationships_severance_event.account_suspension": "Administrator sa {from} je suspendovao {target}, što znači da više ne možete da primate ažuriranja od njih niti da komunicirate sa njima.", + "notification.relationships_severance_event.domain_block": "Administrator sa {from} je blokirao {target}, uključujući vaše pratioce: {followersCount} i {followingCount, plural, one {# nalog} few {# naloga} other {# naloga}} koje pratite.", + "notification.relationships_severance_event.learn_more": "Saznajte više", + "notification.relationships_severance_event.user_domain_block": "Blokirači ste {target}, uključujući vaše pratioce: {followersCount} i {followingCount, plural, one {# nalog} few {# naloga} other {# naloga}} koje pratite.", "notification.status": "{name} je upravo objavio", "notification.update": "{name} je uredio objavu", "notification_requests.accept": "Prihvati", @@ -444,6 +489,8 @@ "notifications.column_settings.admin.sign_up": "Nove ragistracije:", "notifications.column_settings.alert": "Obaveštenja na radnoj površini", "notifications.column_settings.favourite": "Omiljeno:", + "notifications.column_settings.filter_bar.advanced": "Prikaži sve kategorije", + "notifications.column_settings.filter_bar.category": "Traka za brzo filtriranje", "notifications.column_settings.follow": "Novi pratioci:", "notifications.column_settings.follow_request": "Novi zahtevi za praćenje:", "notifications.column_settings.mention": "Pominjanja:", @@ -471,7 +518,7 @@ "notifications.permission_required": "Obaveštenja na radnoj površini nisu dostupna jer potrebna dozvola nije dodeljena.", "notifications.policy.filter_new_accounts.hint": "Kreirano {days, plural, one {u poslednjeg # dana} few {u poslednja # dana} other {u poslednjih # dana}}", "notifications.policy.filter_new_accounts_title": "Novi nalozi", - "notifications.policy.filter_not_followers_hint": "Uključujući ljude koji su vas pratili manje od {days, plural, one {# dana} few {# dana} other {# dana}}", + "notifications.policy.filter_not_followers_hint": "Uključujući ljude koji su vas pratili manje od {days, plural, one {# dana} few {# dana} other {# dana}}", "notifications.policy.filter_not_followers_title": "Ljudi koji vas ne prate", "notifications.policy.filter_not_following_hint": "Dok ih ručno ne odobrite", "notifications.policy.filter_not_following_title": "Ljudi koje ne pratite", @@ -483,14 +530,14 @@ "notifications_permission_banner.title": "Nikada ništa ne propustite", "onboarding.action.back": "Vrati me nazad", "onboarding.actions.back": "Vrati me nazad", - "onboarding.actions.go_to_explore": "Pogledaj šta je u trendu", - "onboarding.actions.go_to_home": "Idi na početnu stranicu", + "onboarding.actions.go_to_explore": "Odvedi me u trending", + "onboarding.actions.go_to_home": "Odvedi me na početnu stranicu", "onboarding.compose.template": "Zdravo #Mastodon!", "onboarding.follows.empty": "Nažalost, trenutno se ne mogu prikazati rezultati. Možete pokušati sa korišćenjem pretrage ili pregledanjem stranice za istraživanje da biste pronašli ljude koje ćete pratiti ili pokušajte ponovo kasnije.", - "onboarding.follows.lead": "Vi sami birate svoju početnu stranicu. Što više ljudi pratite, to će biti aktivnije i zanimljivije. Ovi profili mogu biti dobra polazna tačka—uvek možete da ih prestanete pratiti kasnije!", + "onboarding.follows.lead": "Vaša početna stranica je primarni način da doživite Mastodon. Što više ljudi budete pratili, to će biti aktivnije i zanimljivije. Da biste započeli, evo nekoliko predloga:", "onboarding.follows.title": "Personalizujte svoju početnu stranicu", "onboarding.profile.discoverable": "Neka se moj profil može otkriti drugima", - "onboarding.profile.discoverable_hint": "Kada omogućite mogućnost otkrivanja na Mastodon-u, vaše objave se mogu pojaviti u rezultatima pretrage i u trendu, a vaš profil može biti predložen ljudima sa sličnim interesovanjima.", + "onboarding.profile.discoverable_hint": "Kada omogućite mogućnost otkrivanja na Mastodon-u, vaše objave se mogu pojaviti u rezultatima pretrage i u trendu, a vaš profil može biti predložen ljudima sa sličnim interesovanjima.", "onboarding.profile.display_name": "Ime za prikaz", "onboarding.profile.display_name_hint": "Vaše puno ime ili nadimak…", "onboarding.profile.lead": "Ovo možete uvek dovršiti kasnije u podešavanjima, gde je dostupno još više opcija prilagođavanja.", @@ -504,17 +551,17 @@ "onboarding.share.message": "Ja sam {username} na #Mastodon-u! Pratite me na {url}", "onboarding.share.next_steps": "Mogući sledeći koraci:", "onboarding.share.title": "Podelite svoj profil", - "onboarding.start.lead": "Vaš novi Mastodon nalog je spreman. Evo kako to možete iskoristiti na najbolji način:", - "onboarding.start.skip": "Želite da preskočite?", + "onboarding.start.lead": "Sada ste deo Mastodon-a, jedinstvene, decentralizovane platforme društvenih medija na kojoj vi – a ne algoritam – birate svoje iskustvo. Hajde da počnemo na ovoj novoj društvenoj granici:", + "onboarding.start.skip": "Ne treba vam pomoć za početak?", "onboarding.start.title": "Uspeli ste!", - "onboarding.steps.follow_people.body": "Vi sami birate svoju početnu stranicu. Hajde da ga ispunimo zanimljivim ljudima.", + "onboarding.steps.follow_people.body": "Praćenje zanimljivih ljudi je ono o čemu se radi u Mastodon-u.", "onboarding.steps.follow_people.title": "Personalizujte svoju početnu stranicu", - "onboarding.steps.publish_status.body": "Reci zdravo svetu.", + "onboarding.steps.publish_status.body": "Pozdravite svet tekstom, slikama, video snimcima ili anketama {emoji}", "onboarding.steps.publish_status.title": "Napišite svoju prvu objavu", - "onboarding.steps.setup_profile.body": "Veća je verovatnoća da će drugi komunicirati sa vama sa popunjenim profilom.", - "onboarding.steps.setup_profile.title": "Prilagodite svoj profil", + "onboarding.steps.setup_profile.body": "Pojačajte svoje interakcije tako što ćete imati sveobuhvatan profil.", + "onboarding.steps.setup_profile.title": "Personalizujte svoj profil", "onboarding.steps.share_profile.body": "Neka vaši prijatelji znaju kako da vas pronađu na Mastodon-u!", - "onboarding.steps.share_profile.title": "Podelite svoj profil", + "onboarding.steps.share_profile.title": "Podelite svoj Mastodon profil", "onboarding.tips.2fa": "Da li ste znali? Možete da zaštitite svoj nalog podešavanjem dvostruke potvrde identiteta u podešavanjima naloga. Radi sa bilo kojom TOTP aplikacijom po vašem izboru, nije potreban broj telefona!", "onboarding.tips.accounts_from_other_servers": "Da li ste znali? Pošto je Mastodon decentralizovan, neki profili na koje naiđete biće smešteni na serverima različitim od vašeg. A ipak možete da komunicirate sa njima besprekorno! Njihov server je u drugoj polovini njihovog korisničkog imena!", "onboarding.tips.migration": "Da li ste znali? Ako smatrate da {domain} nije odličan izbor servera za vas u budućnosti, možete da pređete na drugi Mastodon server bez gubitka pratilaca. Možete čak i da hostujete sopstveni server!", @@ -539,7 +586,7 @@ "privacy.private.short": "Pratioci", "privacy.public.long": "Bilo ko na Mastodon-u i van njega", "privacy.public.short": "Javno", - "privacy.unlisted.additional": "Ovo se ponaša potpuno kao javno, osim što se objava neće pojavljivati u izvorima uživo ili heš oznakama, istraživanjima ili pretrazi Mastodon-a, čak i ako ste uključeni u celom nalogu.", + "privacy.unlisted.additional": "Ovo se ponaša potpuno kao javno, osim što se objava neće pojavljivati u izvorima uživo ili heš oznakama, istraživanjima ili pretrazi Mastodon-a, čak i ako ste uključeni u celom nalogu.", "privacy.unlisted.long": "Manje algoritamskih fanfara", "privacy.unlisted.short": "Tiha javnost", "privacy_policy.last_updated": "Poslednje ažuriranje {date}", diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json index 347a3f65a..69f755a0b 100644 --- a/app/javascript/mastodon/locales/sr.json +++ b/app/javascript/mastodon/locales/sr.json @@ -220,7 +220,16 @@ "domain_pill.activitypub_lets_connect": "Омогућује вам да се повежете и комуницирате са људима не само на Mastodon-у, већ и у различитим друштвеним апликацијама.", "domain_pill.activitypub_like_language": "ActivityPub је као језик којим Mastodon говори са другим друштвеним мрежама.", "domain_pill.server": "Сервер", + "domain_pill.their_handle": "Његов регулатор:", + "domain_pill.their_server": "Њихов дигитални дом, где живе све њихове објаве.", + "domain_pill.their_username": "Њихов јединствени идентификатор на њиховом серверу. Могуће је пронаћи кориснике са истим корисничким именом на различитим серверима.", "domain_pill.username": "Корисничко име", + "domain_pill.whats_in_a_handle": "Шта је регулатор?", + "domain_pill.who_they_are": "Пошто регулатори говоре ко је неко и где се налази, можете да комуницирате са људима широм друштвеног веба на .", + "domain_pill.who_you_are": "Пошто ваши регулатори говори ко сте и где сте, људи могу да комуницирају са вама широм друштвеног веба на .", + "domain_pill.your_handle": "Ваш регулатор:", + "domain_pill.your_server": "Ваш дигитални дом, где живе све ваше објаве. Не свиђа вам се овај? Пренесите сервере у било које време и доведите и своје пратиоце.", + "domain_pill.your_username": "Њихов јединствени идентификатор на њиховом серверу. Могуће је пронаћи кориснике са истим корисничким именом на различитим серверима.", "embed.instructions": "Уградите ову објаву на свој веб сајт копирањем кода испод.", "embed.preview": "Ево како ће то изгледати:", "emoji_button.activity": "Активности", @@ -288,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Користите постојећу категорију или креирајте нову", "filter_modal.select_filter.title": "Филтрирај ову објаву", "filter_modal.title.status": "Филтрирај објаву", + "filtered_notifications_banner.mentions": "{count, plural, one {помињање} few {помињања} other {помињања}}", "filtered_notifications_banner.pending_requests": "Обавештења од {count, plural, =0 {никога кога можда познајете} one {# особе коју можда познајете} few {# особе које можда познајете} other {# особа које можда познајете}}", "filtered_notifications_banner.title": "Филтрирана обавештења", "firehose.all": "Све", @@ -462,6 +472,11 @@ "notification.own_poll": "Ваша анкета је завршена", "notification.poll": "Завршена је анкета у којој сте гласали", "notification.reblog": "{name} је подржао вашу објаву", + "notification.relationships_severance_event": "Изгубљена веза са {name}", + "notification.relationships_severance_event.account_suspension": "Администратор са {from} је суспендовао {target}, што значи да више не можете да примате ажурирања од њих нити да комуницирате са њима.", + "notification.relationships_severance_event.domain_block": "Администратор са {from} је блокирао {target}, укључујући ваше пратиоце: {followersCount} и {followingCount, plural, one {# налог} few {# налогa} other {# налога}} које пратите.", + "notification.relationships_severance_event.learn_more": "Сазнајте више", + "notification.relationships_severance_event.user_domain_block": "Блокирачи сте {target}, укључујући ваше пратиоце: {followersCount} и {followingCount, plural, one {# налог} few {# налогa} other {# налога}} које пратите.", "notification.status": "{name} је управо објавио", "notification.update": "{name} је уредио објаву", "notification_requests.accept": "Прихвати", @@ -474,6 +489,8 @@ "notifications.column_settings.admin.sign_up": "Нове рагистрације:", "notifications.column_settings.alert": "Обавештења на радној површини", "notifications.column_settings.favourite": "Омиљено:", + "notifications.column_settings.filter_bar.advanced": "Прикажи све категорије", + "notifications.column_settings.filter_bar.category": "Трака за брзо филтрирање", "notifications.column_settings.follow": "Нови пратиоци:", "notifications.column_settings.follow_request": "Нови захтеви за праћење:", "notifications.column_settings.mention": "Помињања:", diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json index 016007f49..c2dd5297d 100644 --- a/app/javascript/mastodon/locales/sv.json +++ b/app/javascript/mastodon/locales/sv.json @@ -220,8 +220,15 @@ "domain_pill.activitypub_lets_connect": "Det låter dig ansluta och interagera med människor inte bara på Mastodon, men även på andra sociala appar.", "domain_pill.activitypub_like_language": "ActivityPub är som språket Mastodon talar med andra sociala nätverk.", "domain_pill.server": "Server", + "domain_pill.their_handle": "Deras handtag:", + "domain_pill.their_server": "Deras digitala hem, där alla deras tjänster bor.", "domain_pill.their_username": "Deras unika identifierare på deras server. Det är möjligt att hitta användare med samma användarnamn på olika servrar.", "domain_pill.username": "Användarnamn", + "domain_pill.whats_in_a_handle": "Vad finns i ett handtag?", + "domain_pill.who_they_are": "Eftersom handtag säger vem någon är och var de är, kan du interagera med människor på det sociala nätet av .", + "domain_pill.who_you_are": "Eftersom handtag säger vem någon är och var de är, kan människor interagera med dig på det sociala nätet av .", + "domain_pill.your_handle": "Ditt handtag:", + "domain_pill.your_server": "Ditt digitala hem, där alla dina inlägg bor. Gillar du inte just denna? Byt server när som helst och ta med dina anhängare också.", "domain_pill.your_username": "Din unika identifierare på denna server. Det är möjligt att hitta användare med samma användarnamn på olika servrar.", "embed.instructions": "Bädda in detta inlägg på din webbplats genom att kopiera koden nedan.", "embed.preview": "Så här kommer det att se ut:", @@ -259,6 +266,7 @@ "empty_column.list": "Det finns inget i denna lista än. När listmedlemmar publicerar nya inlägg kommer de synas här.", "empty_column.lists": "Du har inga listor än. När skapar en kommer den dyka upp här.", "empty_column.mutes": "Du har ännu inte tystat några användare.", + "empty_column.notification_requests": "Allt klart! Det finns inget mer här. När du får nya meddelanden visas de här enligt dina inställningar.", "empty_column.notifications": "Du har inga meddelanden än. Interagera med andra för att starta konversationen.", "empty_column.public": "Det finns inget här! Skriv något offentligt, eller följ manuellt användarna från andra instanser för att fylla på det", "error.unexpected_crash.explanation": "På grund av en bugg i vår kod eller kompatiblitetsproblem i webbläsaren kan den här sidan inte visas korrekt.", @@ -289,6 +297,8 @@ "filter_modal.select_filter.subtitle": "Använd en befintlig kategori eller skapa en ny", "filter_modal.select_filter.title": "Filtrera detta inlägg", "filter_modal.title.status": "Filtrera ett inlägg", + "filtered_notifications_banner.pending_requests": "Aviseringar från {count, plural, =0 {ingen} one {en person} other {# personer}} du kanske känner", + "filtered_notifications_banner.title": "Filtrerade aviseringar", "firehose.all": "Allt", "firehose.local": "Denna server", "firehose.remote": "Andra servrar", @@ -417,7 +427,9 @@ "loading_indicator.label": "Laddar…", "media_gallery.toggle_visible": "Växla synlighet", "moved_to_account_banner.text": "Ditt konto {disabledAccount} är för närvarande inaktiverat eftersom du flyttat till {movedToAccount}.", + "mute_modal.hide_from_notifications": "Dölj från aviseringslistan", "mute_modal.hide_options": "Dölj alternativ", + "mute_modal.indefinite": "Tills jag avtystar dem", "mute_modal.show_options": "Visa alternativ", "mute_modal.they_can_mention_and_follow": "De kan nämna och följa dig, men du ser dem inte.", "mute_modal.they_wont_know": "De vet inte att de har blivit tysta.", @@ -456,9 +468,19 @@ "notification.follow": "{name} följer dig", "notification.follow_request": "{name} har begärt att följa dig", "notification.mention": "{name} nämnde dig", + "notification.moderation-warning.learn_more": "Läs mer", + "notification.moderation_warning.action_delete_statuses": "Några av dina inlägg har tagits bort.", + "notification.moderation_warning.action_disable": "Ditt konto har inaktiverats.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Några av dina inlägg har markerats som känsliga.", + "notification.moderation_warning.action_silence": "Ditt konto har begränsats.", "notification.own_poll": "Din röstning har avslutats", "notification.poll": "En omröstning du röstat i har avslutats", "notification.reblog": "{name} boostade ditt inlägg", + "notification.relationships_severance_event": "Förlorade kontakter med {name}", + "notification.relationships_severance_event.account_suspension": "En administratör från {from} har stängt av {target}, vilket innebär att du inte längre kan ta emot uppdateringar från dem eller interagera med dem.", + "notification.relationships_severance_event.domain_block": "En administratör från {from} har blockerat {target}, inklusive {followersCount} av dina följare och {followingCount, plural, one {# konto} other {# konton}} du följer.", + "notification.relationships_severance_event.learn_more": "Läs mer", + "notification.relationships_severance_event.user_domain_block": "Du har blockerat {target} och tar därmed bort {followersCount} av dina följare samt {followingCount, plural, one {# konto} other {# konton}} du följer.", "notification.status": "{name} publicerade just ett inlägg", "notification.update": "{name} redigerade ett inlägg", "notification_requests.accept": "Godkänn", @@ -471,6 +493,8 @@ "notifications.column_settings.admin.sign_up": "Nya registreringar:", "notifications.column_settings.alert": "Skrivbordsaviseringar", "notifications.column_settings.favourite": "Favoriter:", + "notifications.column_settings.filter_bar.advanced": "Visa alla kategorier", + "notifications.column_settings.filter_bar.category": "Snabbfilter", "notifications.column_settings.follow": "Nya följare:", "notifications.column_settings.follow_request": "Ny följ-förfrågan:", "notifications.column_settings.mention": "Omnämningar:", @@ -498,8 +522,11 @@ "notifications.permission_required": "Skrivbordsaviseringar är otillgängliga eftersom att rättigheten som krävs inte har godkänts.", "notifications.policy.filter_new_accounts.hint": "Skapad inom de senaste {days, plural, one {dagen} other {# dagarna}}", "notifications.policy.filter_new_accounts_title": "Nya konton", + "notifications.policy.filter_not_followers_hint": "Inklusive personer som har följt dig kortare än {days, plural, one {en dag} other {# dagar}}", "notifications.policy.filter_not_followers_title": "Personer som inte följer dig", + "notifications.policy.filter_not_following_hint": "Tills du manuellt godkänner dem", "notifications.policy.filter_not_following_title": "Personer du inte följer", + "notifications.policy.filter_private_mentions_hint": "Filtrerat om det inte är som svar på ditt eget omnämnande eller om du följer avsändaren", "notifications.policy.filter_private_mentions_title": "Oombedda privata omnämnanden", "notifications.policy.title": "Filtrera ut aviseringar från…", "notifications_permission_banner.enable": "Aktivera skrivbordsaviseringar", @@ -572,11 +599,6 @@ "refresh": "Läs om", "regeneration_indicator.label": "Laddar…", "regeneration_indicator.sublabel": "Ditt hemmaflöde förbereds!", - "relationship_severance_notification.purged_data": "rensad av administratörer", - "relationship_severance_notification.types.account_suspension": "Ditt konto har blivit avstängt", - "relationship_severance_notification.types.domain_block": "Domänen har stängts av", - "relationship_severance_notification.types.user_domain_block": "Du blockerade denna domän", - "relationship_severance_notification.view": "Visa", "relative_time.days": "{number}d", "relative_time.full.days": "{number, plural, one {# dag} other {# dagar}} sedan", "relative_time.full.hours": "{number, plural, one {# timme} other {# timmar}} sedan", @@ -708,6 +730,7 @@ "status.reblog": "Boosta", "status.reblog_private": "Boosta med ursprunglig synlighet", "status.reblogged_by": "{name} boostade", + "status.reblogs": "{count, plural, one {# röst} other {# röster}}", "status.reblogs.empty": "Ingen har boostat detta inlägg än. När någon gör det kommer de synas här.", "status.redraft": "Radera & gör om", "status.remove_bookmark": "Ta bort bokmärke", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index ce3b4eaa2..379aebbb1 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": "ทั้งหมด", @@ -471,6 +472,11 @@ "notification.own_poll": "การสำรวจความคิดเห็นของคุณได้สิ้นสุดแล้ว", "notification.poll": "การสำรวจความคิดเห็นที่คุณได้ลงคะแนนได้สิ้นสุดแล้ว", "notification.reblog": "{name} ได้ดันโพสต์ของคุณ", + "notification.relationships_severance_event": "สูญเสียการเชื่อมต่อกับ {name}", + "notification.relationships_severance_event.account_suspension": "ผู้ดูแลจาก {from} ได้ระงับ {target} ซึ่งหมายความว่าคุณจะไม่สามารถรับการอัปเดตจากเขาหรือโต้ตอบกับเขาได้อีกต่อไป", + "notification.relationships_severance_event.domain_block": "ผู้ดูแลจาก {from} ได้ปิดกั้น {target} รวมถึง {followersCount} ผู้ติดตามของคุณและ {followingCount, plural, other {# บัญชี}}ที่คุณติดตาม", + "notification.relationships_severance_event.learn_more": "เรียนรู้เพิ่มเติม", + "notification.relationships_severance_event.user_domain_block": "คุณได้ปิดกั้น {target} เอา {followersCount} ผู้ติดตามของคุณและ {followingCount, plural, other {# บัญชี}}ที่คุณติดตามออก", "notification.status": "{name} เพิ่งโพสต์", "notification.update": "{name} ได้แก้ไขโพสต์", "notification_requests.accept": "ยอมรับ", @@ -483,6 +489,8 @@ "notifications.column_settings.admin.sign_up": "การลงทะเบียนใหม่:", "notifications.column_settings.alert": "การแจ้งเตือนบนเดสก์ท็อป", "notifications.column_settings.favourite": "รายการโปรด:", + "notifications.column_settings.filter_bar.advanced": "แสดงหมวดหมู่ทั้งหมด", + "notifications.column_settings.filter_bar.category": "แถบตัวกรองด่วน", "notifications.column_settings.follow": "ผู้ติดตามใหม่:", "notifications.column_settings.follow_request": "คำขอติดตามใหม่:", "notifications.column_settings.mention": "การกล่าวถึง:", diff --git a/app/javascript/mastodon/locales/tok.json b/app/javascript/mastodon/locales/tok.json index c3f184e15..80d412a20 100644 --- a/app/javascript/mastodon/locales/tok.json +++ b/app/javascript/mastodon/locales/tok.json @@ -36,6 +36,7 @@ "account.go_to_profile": "o tawa lipu jan", "account.hide_reblogs": "o lukin ala e pana toki tan @{name}", "account.in_memoriam": "jan ni li moli. pona o tawa ona.", + "account.joined_short": "li kama", "account.languages": "sina wile lukin e sitelen pi toki seme", "account.locked_info": "sina wile kute e jan ni la ona o toki e ken", "account.media": "sitelen", @@ -70,6 +71,10 @@ "alert.unexpected.title": "pakala a!", "announcement.announcement": "toki suli", "audio.hide": "o len e kalama", + "block_modal.show_less": "o lili e lukin", + "block_modal.show_more": "o mute e lukin", + "block_modal.they_cant_mention": "ona li ken ala toki e sina li ken ala alasa e sina", + "block_modal.title": "o weka ala weka e jan", "boost_modal.combo": "sina ken luka e nena {combo} tawa ni: sina wile ala luka e nena lon tenpo kama", "bundle_column_error.copy_stacktrace": "o awen e sona pakala lon ilo sina", "bundle_column_error.error.body": "ilo li ken ala pana e lipu ni. ni li ken tan pakala ilo.", @@ -86,10 +91,15 @@ "column.about": "sona", "column.blocks": "kulupu pi jan weka", "column.bookmarks": "awen toki", + "column.community": "linja tenpo pi ma ni", + "column.favourites": "ijo pona", + "column.firehose": "toki pi tenpo ni", + "column.follow_requests": "wile alasa pi jan ante", "column.home": "lipu open", "column.lists": "kulupu lipu", "column.mutes": "jan len", "column.pins": "toki sewi", + "column_back_button.label": "o tawa monsi", "column_header.hide_settings": "o len e lawa", "column_header.pin": "o sewi", "column_header.show_settings": "o lukin e lawa", @@ -157,6 +167,9 @@ "dismissable_banner.explore_statuses": "suni ni la jan mute li lukin e toki ni. jan mute li wawa e toki li suli e toki la toki ni li lon sewi. toki li sin la toki ni li lon sewi.", "dismissable_banner.explore_tags": "suni ni la jan mute li lukin e toki pi toki ni. jan mute li kepeken toki la toki ni li lon sewi.", "dismissable_banner.public_timeline": "toki ni li sin. jan li pali e toki ni la jan ante mute pi ma {domain} li kute e jan ni.", + "domain_block_modal.block": "o weka e ma", + "domain_block_modal.you_will_lose_followers": "ma ni la jan alasa ale sina li weka", + "domain_block_modal.you_wont_see_posts": "sina ken ala lukin e toki tan jan pi ma ni", "embed.preview": "ni li jo e sitelen ni:", "emoji_button.activity": "musi", "emoji_button.flags": "len ma", @@ -232,7 +245,7 @@ "keyboard_shortcuts.boost": "o pana sin e toki", "keyboard_shortcuts.down": "o tawa anpa lon lipu", "keyboard_shortcuts.enter": "o lukin e toki", - "keyboard_shortcuts.favourite": "o suli e toki", + "keyboard_shortcuts.favourite": "o sitelen pona e toki", "keyboard_shortcuts.favourites": "o lukin e lipu sina pi toki suli", "keyboard_shortcuts.muted": "o lukin e lipu sina pi jan len", "keyboard_shortcuts.my_profile": "o lukin e lipu sina", @@ -264,7 +277,7 @@ "navigation_bar.about": "sona", "navigation_bar.blocks": "jan weka", "navigation_bar.compose": "o pali e toki sin", - "navigation_bar.favourites": "toki suli", + "navigation_bar.favourites": "ijo pona", "navigation_bar.filters": "nimi len", "navigation_bar.lists": "kulupu lipu", "navigation_bar.mutes": "sina wile ala kute e jan ni", @@ -273,7 +286,7 @@ "navigation_bar.search": "o alasa", "notification.admin.report": "jan {name} li toki e jan {target} tawa lawa", "notification.admin.sign_up": "{name} li kama", - "notification.favourite": "{name} li suli e toki sina", + "notification.favourite": "toki sina li pona tawa {name}", "notification.follow": " {name} li kute e sina", "notification.follow_request": "{name} li wile kute e sina", "notification.mention": "jan {name} li toki e sina", @@ -281,11 +294,13 @@ "notification.reblog": "{name} li wawa e toki sina", "notification.status": "{name} li toki", "notification.update": "{name} li ante e toki", + "notifications.column_settings.favourite": "ijo pona:", "notifications.column_settings.follow": "jan kute sin", "notifications.column_settings.poll": "pana lon pana ni:", "notifications.column_settings.reblog": "wawa:", "notifications.column_settings.update": "ante toki:", "notifications.filter.all": "ale", + "notifications.filter.favourites": "ijo pona", "notifications.filter.polls": "pana lon pana ni", "onboarding.compose.template": "toki a, #Mastodon o!", "onboarding.profile.display_name": "nimi tawa jan ante", @@ -333,7 +348,7 @@ "status.delete": "o weka", "status.edit": "o ante", "status.embed": "ni o lon insa pi lipu ante", - "status.favourite": "o suli", + "status.favourite": "o sitelen pona", "status.hide": "o len", "status.history.created": "{name} li pali e ni lon {date}", "status.history.edited": "{name} li ante lon {date}", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 799400ea3..dc07480ef 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Mevcut bir kategoriyi kullan veya yeni bir tane oluştur", "filter_modal.select_filter.title": "Bu gönderiyi süzgeçle", "filter_modal.title.status": "Bir gönderi süzgeçle", + "filtered_notifications_banner.mentions": "{count, plural, one {bahsetme} other {bahsetme}}", "filtered_notifications_banner.pending_requests": "Bildiğiniz {count, plural, =0 {hiç kimseden} one {bir kişiden} other {# kişiden}} bildirim", "filtered_notifications_banner.title": "Filtrelenmiş bildirimler", "firehose.all": "Tümü", @@ -467,11 +468,15 @@ "notification.favourite": "{name} gönderinizi beğendi", "notification.follow": "{name} seni takip etti", "notification.follow_request": "{name} size takip isteği gönderdi", - "notification.mention": "{name} sana değindi", + "notification.mention": "{name} senden bahsetti", "notification.own_poll": "Anketiniz sona erdi", "notification.poll": "Oy verdiğiniz bir anket sona erdi", "notification.reblog": "{name} gönderini yeniden paylaştı", - "notification.severed_relationships": "{name} ile ilişkiler koptu", + "notification.relationships_severance_event": "{name} ile bağlantılar koptu", + "notification.relationships_severance_event.account_suspension": "{from} yöneticisi, {target} askıya aldı, bunun anlamı onlardan artık güncelleme alamayacak veya etkileşemeyeceksiniz demektir.", + "notification.relationships_severance_event.domain_block": "{from} yöneticisi {target} engelledi, {followersCount} takipçiniz ve takip ettiğiniz {followingCount, plural, one {# hesap} other {# hesap}} buna dahil.", + "notification.relationships_severance_event.learn_more": "Daha fazlası", + "notification.relationships_severance_event.user_domain_block": "{target} engellediniz, takipçilerinizden {followersCount} ve takip eden {followingCount, plural, one {# hesap} other {# hesap}} kaldırılıyor.", "notification.status": "{name} az önce gönderdi", "notification.update": "{name} bir gönderiyi düzenledi", "notification_requests.accept": "Onayla", @@ -484,9 +489,11 @@ "notifications.column_settings.admin.sign_up": "Yeni kayıtlar:", "notifications.column_settings.alert": "Masaüstü bildirimleri", "notifications.column_settings.favourite": "Favorilerin:", + "notifications.column_settings.filter_bar.advanced": "Tüm kategorileri görüntüle", + "notifications.column_settings.filter_bar.category": "Hızlı filtre çubuğu", "notifications.column_settings.follow": "Yeni takipçiler:", "notifications.column_settings.follow_request": "Yeni takip istekleri:", - "notifications.column_settings.mention": "Değinmeler:", + "notifications.column_settings.mention": "Bahsetmeler:", "notifications.column_settings.poll": "Anket sonuçları:", "notifications.column_settings.push": "Anlık bildirimler", "notifications.column_settings.reblog": "Yeniden paylaşanlar:", @@ -500,7 +507,7 @@ "notifications.filter.boosts": "Yeniden paylaşımlar", "notifications.filter.favourites": "Favorilerin", "notifications.filter.follows": "Takip edilenler", - "notifications.filter.mentions": "Değinmeler", + "notifications.filter.mentions": "Bahsetmeler", "notifications.filter.polls": "Anket sonuçları", "notifications.filter.statuses": "Takip ettiğiniz kişilerden gelen güncellemeler", "notifications.grant_permission": "İzin ver.", @@ -588,12 +595,6 @@ "refresh": "Yenile", "regeneration_indicator.label": "Yükleniyor…", "regeneration_indicator.sublabel": "Ana akışın hazırlanıyor!", - "relationship_severance_notification.purged_data": "yöneticiler tarafından temizlendi", - "relationship_severance_notification.relationships": "{count, plural, one {# ilişki} other {# ilişki}}", - "relationship_severance_notification.types.account_suspension": "Hesap askıya alındı", - "relationship_severance_notification.types.domain_block": "Alan adı askıya alındı", - "relationship_severance_notification.types.user_domain_block": "Bu alan adını engellediniz", - "relationship_severance_notification.view": "Görüntüle", "relative_time.days": "{number}d", "relative_time.full.days": "{number, plural, one {# gün} other {# gün}} önce", "relative_time.full.hours": "{number, plural, one {# saat} other {# saat}} önce", @@ -776,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/app/javascript/mastodon/locales/tt.json b/app/javascript/mastodon/locales/tt.json index 82d45205c..9a402472d 100644 --- a/app/javascript/mastodon/locales/tt.json +++ b/app/javascript/mastodon/locales/tt.json @@ -449,9 +449,9 @@ "time_remaining.seconds": "{number, plural, one {# секунд} other {# секунд}} калды", "timeline_hint.resources.statuses": "Older toots", "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}", - "units.short.billion": "{count}Млрд", - "units.short.million": "{count}Млн", - "units.short.thousand": "{count}М", + "units.short.billion": "{count} млрд", + "units.short.million": "{count} млн", + "units.short.thousand": "{count} мең", "upload_form.audio_description": "Describe for people with hearing loss", "upload_form.description": "Describe for the visually impaired", "upload_form.edit": "Үзгәртү", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index 3456327a6..6ae4e162b 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -460,7 +460,9 @@ "notification.own_poll": "Ваше опитування завершилося", "notification.poll": "Опитування, у якому ви голосували, скінчилося", "notification.reblog": "{name} поширює ваш допис", - "notification.severed_relationships": "Зв'язки з {name} розірвані", + "notification.relationships_severance_event": "Втрачено з'єднання з {name}", + "notification.relationships_severance_event.account_suspension": "Адміністратор з {from} призупинив {target}, що означає, що ви більше не можете отримувати оновлення від них або взаємодіяти з ними.", + "notification.relationships_severance_event.learn_more": "Дізнатися більше", "notification.status": "{name} щойно дописує", "notification.update": "{name} змінює допис", "notification_requests.accept": "Прийняти", @@ -473,6 +475,8 @@ "notifications.column_settings.admin.sign_up": "Нові реєстрації:", "notifications.column_settings.alert": "Сповіщення стільниці", "notifications.column_settings.favourite": "Уподобане:", + "notifications.column_settings.filter_bar.advanced": "Показати всі категорії", + "notifications.column_settings.filter_bar.category": "Панель швидкого фільтра", "notifications.column_settings.follow": "Нові підписники:", "notifications.column_settings.follow_request": "Нові запити на підписку:", "notifications.column_settings.mention": "Згадки:", @@ -573,12 +577,6 @@ "refresh": "Оновити", "regeneration_indicator.label": "Завантаження…", "regeneration_indicator.sublabel": "Хвилинку, ми готуємо вашу стрічку!", - "relationship_severance_notification.purged_data": "очищено адміністраторами", - "relationship_severance_notification.relationships": "{count, plural, one {# зв'язок} few {# зв'язки} many {# зв'язків} other {# зв'язок}}", - "relationship_severance_notification.types.account_suspension": "Обліковий запис призупинено", - "relationship_severance_notification.types.domain_block": "Домен призупинено", - "relationship_severance_notification.types.user_domain_block": "Ви заблокували цей домен", - "relationship_severance_notification.view": "Вигляд", "relative_time.days": "{number}д", "relative_time.full.days": "{number, plural, one {# день} few {# дні} other {# днів}} тому", "relative_time.full.hours": "{number, plural, one {# година} few {# години} other {# годин}} тому", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index 9b09d2145..e1f886b1f 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -297,6 +297,7 @@ "filter_modal.select_filter.subtitle": "Sử dụng một danh mục hiện có hoặc tạo một danh mục mới", "filter_modal.select_filter.title": "Lọc tút này", "filter_modal.title.status": "Lọc một tút", + "filtered_notifications_banner.mentions": "{count, plural, other {lượt nhắc}}", "filtered_notifications_banner.pending_requests": "Thông báo từ {count, plural, =0 {không ai} other {# người}} bạn có thể biết", "filtered_notifications_banner.title": "Thông báo đã lọc", "firehose.all": "Toàn bộ", @@ -471,7 +472,11 @@ "notification.own_poll": "Cuộc bình chọn của bạn đã kết thúc", "notification.poll": "Cuộc bình chọn đã kết thúc", "notification.reblog": "{name} đăng lại tút của bạn", - "notification.severed_relationships": "Mối quan hệ với {name} bị cắt đứt", + "notification.relationships_severance_event": "Mất kết nối với {name}", + "notification.relationships_severance_event.account_suspension": "Quản trị viên {from} đã vô hiệu hóa {target}, điều này có nghĩa là bạn không còn có thể nhận được cập nhật từ họ hoặc tương tác với họ nữa.", + "notification.relationships_severance_event.domain_block": "Quản trị viên {from} đã chặn {target}, bao gồm {followersCount} người theo dõi bạn và {followingCount, plural, other {# người}} mà bạn theo dõi.", + "notification.relationships_severance_event.learn_more": "Tìm hiểu thêm", + "notification.relationships_severance_event.user_domain_block": "Bạn đã chặn {target}, xóa {followersCount} người theo dõi bạn và {followingCount, plural, other {# người}} theo dõi bạn.", "notification.status": "{name} đăng tút mới", "notification.update": "{name} đã sửa tút", "notification_requests.accept": "Chấp nhận", @@ -484,6 +489,8 @@ "notifications.column_settings.admin.sign_up": "Người mới tham gia:", "notifications.column_settings.alert": "Báo trên máy tính", "notifications.column_settings.favourite": "Lượt thích:", + "notifications.column_settings.filter_bar.advanced": "Toàn bộ", + "notifications.column_settings.filter_bar.category": "Thanh lọc nhanh", "notifications.column_settings.follow": "Người theo dõi:", "notifications.column_settings.follow_request": "Yêu cầu theo dõi:", "notifications.column_settings.mention": "Lượt nhắc đến:", @@ -588,12 +595,6 @@ "refresh": "Làm mới", "regeneration_indicator.label": "Đang tải…", "regeneration_indicator.sublabel": "Trang chủ của bạn đang được cập nhật!", - "relationship_severance_notification.purged_data": "bị quản trị viên xóa", - "relationship_severance_notification.relationships": "{count, plural, other {# mối quan hệ}}", - "relationship_severance_notification.types.account_suspension": "Người này đã bị vô hiệu hóa", - "relationship_severance_notification.types.domain_block": "Máy chủ này đã bị vô hiệu hóa", - "relationship_severance_notification.types.user_domain_block": "Bạn đã chặn máy chủ này", - "relationship_severance_notification.view": "Chi tiết", "relative_time.days": "{number} ngày", "relative_time.full.days": "{number, plural, other {# ngày}}", "relative_time.full.hours": "{number, plural, other {# giờ}}", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index cc68ab762..ab6fe0bd7 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.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 {0 个人} other {# 个人}}的通知", "filtered_notifications_banner.title": "通知(已过滤)", "firehose.all": "全部", @@ -307,6 +308,8 @@ "follow_requests.unlocked_explanation": "尽管你没有锁嘟,但是 {domain} 的工作人员认为你也许会想手动审核审核这些账号的关注请求。", "follow_suggestions.curated_suggestion": "站务人员精选", "follow_suggestions.dismiss": "不再显示", + "follow_suggestions.featured_longer": "由 {domain} 管理团队精选", + "follow_suggestions.friends_of_friends_longer": "在你关注的人中很受欢迎", "follow_suggestions.hints.featured": "该用户已被 {domain} 管理团队精选。", "follow_suggestions.hints.friends_of_friends": "该用户在您关注的人中很受欢迎。", "follow_suggestions.hints.most_followed": "该用户是 {domain} 上关注度最高的用户之一。", @@ -314,6 +317,8 @@ "follow_suggestions.hints.similar_to_recently_followed": "该用户与您最近关注的用户类似。", "follow_suggestions.personalized_suggestion": "个性化建议", "follow_suggestions.popular_suggestion": "热门建议", + "follow_suggestions.popular_suggestion_longer": "在 {domain} 上很受欢迎", + "follow_suggestions.similar_to_recently_followed_longer": "与你近期关注的用户相似", "follow_suggestions.view_all": "查看全部", "follow_suggestions.who_to_follow": "推荐关注", "followed_tags": "关注的话题标签", @@ -468,10 +473,23 @@ "notification.follow": "{name} 开始关注你", "notification.follow_request": "{name} 向你发送了关注请求", "notification.mention": "{name} 提及了你", + "notification.moderation-warning.learn_more": "了解更多", + "notification.moderation_warning": "你收到了一条管理警告", + "notification.moderation_warning.action_delete_statuses": "你的一些嘟文已被移除。", + "notification.moderation_warning.action_disable": "你的账号已被禁用。", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "你的一些嘟文已被标记为敏感内容。", + "notification.moderation_warning.action_none": "你的账号收到了管理警告。", + "notification.moderation_warning.action_sensitive": "今后你的嘟文都会被标记为敏感内容。", + "notification.moderation_warning.action_silence": "你的账号已被限制。", + "notification.moderation_warning.action_suspend": "你的账号已被封禁.", "notification.own_poll": "你的投票已经结束", "notification.poll": "你参与的一个投票已经结束", "notification.reblog": "{name} 转发了你的嘟文", - "notification.severed_relationships": "与 {name} 的关系已被切断", + "notification.relationships_severance_event": "与 {name} 的联系已断开", + "notification.relationships_severance_event.account_suspension": "一名来自 {from} 的管理员已经封禁了{target},这意味着你将无法再收到他们的更新或与他们互动。", + "notification.relationships_severance_event.domain_block": "一名来自 {from} 的管理员已经屏蔽了 {target},其中包括你的 {followersCount} 个关注者和 {followingCount, plural, other {# 个关注}}。", + "notification.relationships_severance_event.learn_more": "了解更多", + "notification.relationships_severance_event.user_domain_block": "你已经屏蔽了 {target},移除了你的 {followersCount} 个关注者和 {followingCount, plural, other {# 个关注}}。", "notification.status": "{name} 刚刚发布嘟文", "notification.update": "{name} 编辑了嘟文", "notification_requests.accept": "接受", @@ -484,6 +502,8 @@ "notifications.column_settings.admin.sign_up": "新注册:", "notifications.column_settings.alert": "桌面通知", "notifications.column_settings.favourite": "喜欢:", + "notifications.column_settings.filter_bar.advanced": "显示所有类别", + "notifications.column_settings.filter_bar.category": "快速筛选栏", "notifications.column_settings.follow": "新粉丝:", "notifications.column_settings.follow_request": "新关注请求:", "notifications.column_settings.mention": "提及:", @@ -588,12 +608,6 @@ "refresh": "刷新", "regeneration_indicator.label": "加载中…", "regeneration_indicator.sublabel": "你的主页动态正在准备中!", - "relationship_severance_notification.purged_data": "被管理员清除", - "relationship_severance_notification.relationships": "{count, plural, other {# 条关系}}", - "relationship_severance_notification.types.account_suspension": "账户已被封禁", - "relationship_severance_notification.types.domain_block": "域名已被封禁", - "relationship_severance_notification.types.user_domain_block": "你屏蔽了这个域名", - "relationship_severance_notification.view": "查看", "relative_time.days": "{number} 天前", "relative_time.full.days": "{number, plural, one {# 天} other {# 天}}前", "relative_time.full.hours": "{number, plural, one {# 小时} other {# 小时}}前", diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json index 44a1435b2..3ca9a8d11 100644 --- a/app/javascript/mastodon/locales/zh-HK.json +++ b/app/javascript/mastodon/locales/zh-HK.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, one {則提及} other {則提及}}", "filtered_notifications_banner.pending_requests": "來自 {count, plural, =0 {0 位} other {# 位}}你可能認識的人的通知", "filtered_notifications_banner.title": "已過濾之通知", "firehose.all": "全部", @@ -471,6 +472,11 @@ "notification.own_poll": "你的投票已結束", "notification.poll": "你參與過的一個投票已經結束", "notification.reblog": "{name} 轉推你的文章", + "notification.relationships_severance_event": "失去與 {name} 的連結", + "notification.relationships_severance_event.account_suspension": "{from} 的管理員已將 {target} 停權,這表示你無法再收到他們的更新或與他們互動。", + "notification.relationships_severance_event.domain_block": "{from} 的管理員已封鎖 {target},包括你的 {followersCount} 位追蹤者和 {followingCount, plural, other {# 個你追蹤的帳號}}。", + "notification.relationships_severance_event.learn_more": "了解更多", + "notification.relationships_severance_event.user_domain_block": "你已封鎖 {target},並移除了你的 {followersCount} 位追蹤者和你追蹤的 {followingCount, plural, other {# 個帳號}}。", "notification.status": "{name} 剛發表了文章", "notification.update": "{name} 編輯了帖文", "notification_requests.accept": "接受", @@ -483,6 +489,8 @@ "notifications.column_settings.admin.sign_up": "新註冊:", "notifications.column_settings.alert": "顯示桌面通知", "notifications.column_settings.favourite": "最愛:", + "notifications.column_settings.filter_bar.advanced": "顯示所有分類", + "notifications.column_settings.filter_bar.category": "快速篩選欄", "notifications.column_settings.follow": "新追蹤者:", "notifications.column_settings.follow_request": "新的追蹤請求:", "notifications.column_settings.mention": "提及你:", @@ -697,6 +705,7 @@ "status.edited_x_times": "Edited {count, plural, one {{count} 次} other {{count} 次}}", "status.embed": "嵌入", "status.favourite": "最愛", + "status.favourites": "{count, plural, one {則最愛} other {則最愛}}", "status.filter": "篩選此帖文", "status.filtered": "已過濾", "status.hide": "隱藏帖文", @@ -717,6 +726,7 @@ "status.reblog": "轉推", "status.reblog_private": "轉推到原讀者", "status.reblogged_by": "{name} 轉推", + "status.reblogs": "{count, plural, one {則轉推} other {則轉推}}", "status.reblogs.empty": "還未有人轉推。有的話會顯示在這裡。", "status.redraft": "刪除並編輯", "status.remove_bookmark": "移除書籤", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index 228430dd8..f00d62c07 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.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 {0 人} other {# 人}} 之通知", "filtered_notifications_banner.title": "已過濾之通知", "firehose.all": "全部", @@ -307,6 +308,8 @@ "follow_requests.unlocked_explanation": "即便您的帳號未被鎖定,{domain} 的管理員認為您可能想要自己審核這些帳號的跟隨請求。", "follow_suggestions.curated_suggestion": "精選內容", "follow_suggestions.dismiss": "不再顯示", + "follow_suggestions.featured_longer": "{domain} 團隊精選", + "follow_suggestions.friends_of_friends_longer": "受您跟隨之使用者愛戴的風雲人物", "follow_suggestions.hints.featured": "這個個人檔案是 {domain} 管理團隊精心挑選。", "follow_suggestions.hints.friends_of_friends": "這個個人檔案於您跟隨的帳號中很受歡迎。", "follow_suggestions.hints.most_followed": "這個個人檔案是 {domain} 中最受歡迎的帳號之一。", @@ -314,6 +317,8 @@ "follow_suggestions.hints.similar_to_recently_followed": "這個個人檔案與您最近跟隨之帳號類似。", "follow_suggestions.personalized_suggestion": "個人化推薦", "follow_suggestions.popular_suggestion": "熱門推薦", + "follow_suggestions.popular_suggestion_longer": "{domain} 上的人氣王", + "follow_suggestions.similar_to_recently_followed_longer": "與您近日跟隨相近之帳號", "follow_suggestions.view_all": "檢視全部", "follow_suggestions.who_to_follow": "推薦跟隨帳號", "followed_tags": "已跟隨主題標籤", @@ -468,10 +473,23 @@ "notification.follow": "{name} 已跟隨您", "notification.follow_request": "{name} 要求跟隨您", "notification.mention": "{name} 已提到您", + "notification.moderation-warning.learn_more": "了解更多", + "notification.moderation_warning": "您已收到管理員警告", + "notification.moderation_warning.action_delete_statuses": "某些您的嘟文已被刪除。", + "notification.moderation_warning.action_disable": "您的帳號已被停用。", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "某些您的嘟文已被標記為敏感內容。", + "notification.moderation_warning.action_none": "您的帳號已收到管理員警告。", + "notification.moderation_warning.action_sensitive": "即日起,您的嘟文將會被標記為敏感內容。", + "notification.moderation_warning.action_silence": "您的帳號已被限制。", + "notification.moderation_warning.action_suspend": "您的帳號已被停權。", "notification.own_poll": "您的投票已結束", "notification.poll": "您曾投過的投票已經結束", "notification.reblog": "{name} 已轉嘟您的嘟文", - "notification.severed_relationships": "已斷絕與 {name} 之服務關係", + "notification.relationships_severance_event": "與 {name} 失去連結", + "notification.relationships_severance_event.account_suspension": "{from} 之管理員已將 {target} 停權,意味著您將不再收到來自他們的更新或與之互動。", + "notification.relationships_severance_event.domain_block": "{from} 之管理員已將 {target} 封鎖,包含 {followersCount} 名您的跟隨者及 {followingCount, plural, other {#}} 名您跟隨的帳號。", + "notification.relationships_severance_event.learn_more": "了解更多", + "notification.relationships_severance_event.user_domain_block": "您已將 {target} 封鎖,將移除 {followersCount} 名您的跟隨者及 {followingCount, plural, other {#}} 名您跟隨的帳號。", "notification.status": "{name} 剛剛嘟文", "notification.update": "{name} 已編輯嘟文", "notification_requests.accept": "接受", @@ -484,6 +502,8 @@ "notifications.column_settings.admin.sign_up": "新註冊帳號:", "notifications.column_settings.alert": "桌面通知", "notifications.column_settings.favourite": "最愛:", + "notifications.column_settings.filter_bar.advanced": "顯示所有分類", + "notifications.column_settings.filter_bar.category": "快速過濾器", "notifications.column_settings.follow": "新的跟隨者:", "notifications.column_settings.follow_request": "新的跟隨請求:", "notifications.column_settings.mention": "提及:", @@ -588,12 +608,6 @@ "refresh": "重新整理", "regeneration_indicator.label": "載入中…", "regeneration_indicator.sublabel": "您的首頁時間軸正在準備中!", - "relationship_severance_notification.purged_data": "已被管理員清除", - "relationship_severance_notification.relationships": "{count, plural, other {# 個服務關係}}", - "relationship_severance_notification.types.account_suspension": "該帳號已被停權", - "relationship_severance_notification.types.domain_block": "該網域已被停權", - "relationship_severance_notification.types.user_domain_block": "您已封鎖此網域", - "relationship_severance_notification.view": "檢視", "relative_time.days": "{number} 天", "relative_time.full.days": "{number, plural, other {# 天}}前", "relative_time.full.hours": "{number, plural, one {# 小時} other {# 小時}}前", @@ -729,7 +743,7 @@ "status.reblogs.empty": "還沒有人轉嘟過這則嘟文。當有人轉嘟時,它將於此顯示。", "status.redraft": "刪除並重新編輯", "status.remove_bookmark": "移除書籤", - "status.replied_to": "回覆給 {name}", + "status.replied_to": "回覆 {name}", "status.reply": "回覆", "status.replyAll": "回覆討論串", "status.report": "檢舉 @{name}", diff --git a/app/javascript/mastodon/models/status.ts b/app/javascript/mastodon/models/status.ts new file mode 100644 index 000000000..7907fc34f --- /dev/null +++ b/app/javascript/mastodon/models/status.ts @@ -0,0 +1,4 @@ +export type { StatusVisibility } from 'mastodon/api_types/statuses'; + +// Temporary until we type it correctly +export type Status = Immutable.Map; diff --git a/app/javascript/mastodon/reducers/boosts.js b/app/javascript/mastodon/reducers/boosts.js deleted file mode 100644 index d0d825057..000000000 --- a/app/javascript/mastodon/reducers/boosts.js +++ /dev/null @@ -1,25 +0,0 @@ -import Immutable from 'immutable'; - -import { - BOOSTS_INIT_MODAL, - BOOSTS_CHANGE_PRIVACY, -} from 'mastodon/actions/boosts'; - -const initialState = Immutable.Map({ - new: Immutable.Map({ - privacy: 'public', - }), -}); - -export default function mutes(state = initialState, action) { - switch (action.type) { - case BOOSTS_INIT_MODAL: - return state.withMutations((state) => { - state.setIn(['new', 'privacy'], action.privacy); - }); - case BOOSTS_CHANGE_PRIVACY: - return state.setIn(['new', 'privacy'], action.privacy); - default: - return state; - } -} diff --git a/app/javascript/mastodon/reducers/index.ts b/app/javascript/mastodon/reducers/index.ts index 3d42cc83f..6296ef202 100644 --- a/app/javascript/mastodon/reducers/index.ts +++ b/app/javascript/mastodon/reducers/index.ts @@ -7,7 +7,6 @@ import { accountsReducer } from './accounts'; import accounts_map from './accounts_map'; import alerts from './alerts'; import announcements from './announcements'; -import boosts from './boosts'; import compose from './compose'; import contexts from './contexts'; import conversations from './conversations'; @@ -21,14 +20,14 @@ import history from './history'; import listAdder from './list_adder'; import listEditor from './list_editor'; import lists from './lists'; -import markers from './markers'; +import { markersReducer } from './markers'; import media_attachments from './media_attachments'; import meta from './meta'; import { modalReducer } from './modal'; import { notificationPolicyReducer } from './notification_policy'; import { notificationRequestsReducer } from './notification_requests'; import notifications from './notifications'; -import picture_in_picture from './picture_in_picture'; +import { pictureInPictureReducer } from './picture_in_picture'; import polls from './polls'; import push_notifications from './push_notifications'; import { relationshipsReducer } from './relationships'; @@ -60,7 +59,6 @@ const reducers = { relationships: relationshipsReducer, settings, push_notifications, - boosts, server, contexts, compose, @@ -77,8 +75,8 @@ const reducers = { suggestions, polls, trends, - markers, - picture_in_picture, + markers: markersReducer, + picture_in_picture: pictureInPictureReducer, history, tags, followed_tags, diff --git a/app/javascript/mastodon/reducers/markers.js b/app/javascript/mastodon/reducers/markers.js deleted file mode 100644 index c7c5d99f6..000000000 --- a/app/javascript/mastodon/reducers/markers.js +++ /dev/null @@ -1,26 +0,0 @@ -import { Map as ImmutableMap } from 'immutable'; - -import { - MARKERS_SUBMIT_SUCCESS, -} from '../actions/markers'; - - -const initialState = ImmutableMap({ - home: '0', - notifications: '0', -}); - -export default function markers(state = initialState, action) { - switch(action.type) { - case MARKERS_SUBMIT_SUCCESS: - if (action.home) { - state = state.set('home', action.home); - } - if (action.notifications) { - state = state.set('notifications', action.notifications); - } - return state; - default: - return state; - } -} diff --git a/app/javascript/mastodon/reducers/markers.ts b/app/javascript/mastodon/reducers/markers.ts new file mode 100644 index 000000000..ec85d0f17 --- /dev/null +++ b/app/javascript/mastodon/reducers/markers.ts @@ -0,0 +1,18 @@ +import { createReducer } from '@reduxjs/toolkit'; + +import { submitMarkersAction } from 'mastodon/actions/markers'; + +const initialState = { + home: '0', + notifications: '0', +}; + +export const markersReducer = createReducer(initialState, (builder) => { + builder.addCase( + submitMarkersAction.fulfilled, + (state, { payload: { home, notifications } }) => { + if (home) state.home = home; + if (notifications) state.notifications = notifications; + }, + ); +}); diff --git a/app/javascript/mastodon/reducers/notifications.js b/app/javascript/mastodon/reducers/notifications.js index bc8593643..64cddcb66 100644 --- a/app/javascript/mastodon/reducers/notifications.js +++ b/app/javascript/mastodon/reducers/notifications.js @@ -13,7 +13,7 @@ import { unfocusApp, } from '../actions/app'; import { - MARKERS_FETCH_SUCCESS, + fetchMarkers, } from '../actions/markers'; import { notificationsUpdate, @@ -56,6 +56,7 @@ export const notificationToMap = notification => ImmutableMap({ status: notification.status ? notification.status.id : null, report: notification.report ? fromJS(notification.report) : null, event: notification.event ? fromJS(notification.event) : null, + moderation_warning: notification.moderation_warning ? fromJS(notification.moderation_warning) : null, }); const normalizeNotification = (state, notification, usePendingItems) => { @@ -255,8 +256,8 @@ const recountUnread = (state, last_read_id) => { export default function notifications(state = initialState, action) { switch(action.type) { - case MARKERS_FETCH_SUCCESS: - return action.markers.notifications ? recountUnread(state, action.markers.notifications.last_read_id) : state; + case fetchMarkers.fulfilled.type: + return action.payload.markers.notifications ? recountUnread(state, action.payload.markers.notifications.last_read_id) : state; case NOTIFICATIONS_MOUNT: return updateMounted(state); case NOTIFICATIONS_UNMOUNT: diff --git a/app/javascript/mastodon/reducers/picture_in_picture.js b/app/javascript/mastodon/reducers/picture_in_picture.js deleted file mode 100644 index 6824ad930..000000000 --- a/app/javascript/mastodon/reducers/picture_in_picture.js +++ /dev/null @@ -1,26 +0,0 @@ -import { PICTURE_IN_PICTURE_DEPLOY, PICTURE_IN_PICTURE_REMOVE } from 'mastodon/actions/picture_in_picture'; - -import { TIMELINE_DELETE } from '../actions/timelines'; - -const initialState = { - statusId: null, - accountId: null, - type: null, - src: null, - muted: false, - volume: 0, - currentTime: 0, -}; - -export default function pictureInPicture(state = initialState, action) { - switch(action.type) { - case PICTURE_IN_PICTURE_DEPLOY: - return { statusId: action.statusId, accountId: action.accountId, type: action.playerType, ...action.props }; - case PICTURE_IN_PICTURE_REMOVE: - return { ...initialState }; - case TIMELINE_DELETE: - return (state.statusId === action.id) ? { ...initialState } : state; - default: - return state; - } -} diff --git a/app/javascript/mastodon/reducers/picture_in_picture.ts b/app/javascript/mastodon/reducers/picture_in_picture.ts new file mode 100644 index 000000000..0feddcb70 --- /dev/null +++ b/app/javascript/mastodon/reducers/picture_in_picture.ts @@ -0,0 +1,56 @@ +import type { Reducer } from '@reduxjs/toolkit'; + +import { + deployPictureInPictureAction, + removePictureInPicture, +} from 'mastodon/actions/picture_in_picture'; + +import { TIMELINE_DELETE } from '../actions/timelines'; + +export interface PIPMediaProps { + src: string; + muted: boolean; + volume: number; + currentTime: number; + poster: string; + backgroundColor: string; + foregroundColor: string; + accentColor: string; +} + +interface PIPStateWithValue extends Partial { + statusId: string; + accountId: string; + type: 'audio' | 'video'; +} + +interface PIPStateEmpty extends Partial { + type: null; +} + +type PIPState = PIPStateWithValue | PIPStateEmpty; + +const initialState = { + type: null, + muted: false, + volume: 0, + currentTime: 0, +}; + +export const pictureInPictureReducer: Reducer = ( + state = initialState, + action, +) => { + if (deployPictureInPictureAction.match(action)) + return { + statusId: action.payload.statusId, + accountId: action.payload.accountId, + type: action.payload.playerType, + ...action.payload.props, + }; + else if (removePictureInPicture.match(action)) return initialState; + else if (action.type === TIMELINE_DELETE) + if (state.type && state.statusId === action.id) return initialState; + + return state; +}; diff --git a/app/javascript/mastodon/selectors/index.js b/app/javascript/mastodon/selectors/index.js index b1c60403e..bd9b53919 100644 --- a/app/javascript/mastodon/selectors/index.js +++ b/app/javascript/mastodon/selectors/index.js @@ -60,7 +60,7 @@ export const makeGetStatus = () => { export const makeGetPictureInPicture = () => { return createSelector([ - (state, { id }) => state.get('picture_in_picture').statusId === id, + (state, { id }) => state.picture_in_picture.statusId === id, (state) => state.getIn(['meta', 'layout']) !== 'mobile', ], (inUse, available) => ImmutableMap({ inUse: inUse && available, diff --git a/app/javascript/mastodon/store/middlewares/errors.ts b/app/javascript/mastodon/store/middlewares/errors.ts index e11aa7817..e77cec34e 100644 --- a/app/javascript/mastodon/store/middlewares/errors.ts +++ b/app/javascript/mastodon/store/middlewares/errors.ts @@ -1,16 +1,27 @@ -import { isAction } from '@reduxjs/toolkit'; +import { + isAction, + isAsyncThunkAction, + isRejectedWithValue, +} from '@reduxjs/toolkit'; import type { Action, Middleware } from '@reduxjs/toolkit'; import type { RootState } from '..'; import { showAlertForError } from '../../actions/alerts'; +import type { AsyncThunkRejectValue } from '../typed_functions'; const defaultFailSuffix = 'FAIL'; const isFailedAction = new RegExp(`${defaultFailSuffix}$`, 'g'); -interface ActionWithMaybeAlertParams extends Action { - skipAlert?: boolean; - skipNotFound?: boolean; - error?: unknown; +interface ActionWithMaybeAlertParams extends Action, AsyncThunkRejectValue {} + +interface RejectedAction extends Action { + payload: AsyncThunkRejectValue; +} + +function isRejectedActionWithPayload( + action: unknown, +): action is RejectedAction { + return isAsyncThunkAction(action) && isRejectedWithValue(action); } function isActionWithmaybeAlertParams( @@ -19,11 +30,16 @@ function isActionWithmaybeAlertParams( return isAction(action); } -export const errorsMiddleware: Middleware, RootState> = +// eslint-disable-next-line @typescript-eslint/ban-types -- we need to use `{}` here to ensure the dispatch types can be merged +export const errorsMiddleware: Middleware<{}, RootState> = ({ dispatch }) => (next) => (action) => { - if ( + if (isRejectedActionWithPayload(action) && !action.payload.skipAlert) { + dispatch( + showAlertForError(action.payload.error, action.payload.skipNotFound), + ); + } else if ( isActionWithmaybeAlertParams(action) && !action.skipAlert && action.type.match(isFailedAction) diff --git a/app/javascript/mastodon/store/middlewares/sounds.ts b/app/javascript/mastodon/store/middlewares/sounds.ts index 51839f427..720ee163e 100644 --- a/app/javascript/mastodon/store/middlewares/sounds.ts +++ b/app/javascript/mastodon/store/middlewares/sounds.ts @@ -51,7 +51,8 @@ const play = (audio: HTMLAudioElement) => { }; export const soundsMiddleware = (): Middleware< - Record, + // eslint-disable-next-line @typescript-eslint/ban-types -- we need to use `{}` here to ensure the dispatch types can be merged + {}, RootState > => { const soundCache: Record = {}; diff --git a/app/javascript/mastodon/store/typed_functions.ts b/app/javascript/mastodon/store/typed_functions.ts index 4859b8265..b66d7545c 100644 --- a/app/javascript/mastodon/store/typed_functions.ts +++ b/app/javascript/mastodon/store/typed_functions.ts @@ -7,8 +7,14 @@ import type { AppDispatch, RootState } from './store'; export const useAppDispatch = useDispatch.withTypes(); export const useAppSelector = useSelector.withTypes(); +export interface AsyncThunkRejectValue { + skipAlert?: boolean; + skipNotFound?: boolean; + error?: unknown; +} + export const createAppAsyncThunk = createAsyncThunk.withTypes<{ state: RootState; dispatch: AppDispatch; - rejectValue: string; + rejectValue: AsyncThunkRejectValue; }>(); diff --git a/app/javascript/mastodon/utils/__tests__/html-test.s b/app/javascript/mastodon/utils/__tests__/html-test.ts similarity index 67% rename from app/javascript/mastodon/utils/__tests__/html-test.s rename to app/javascript/mastodon/utils/__tests__/html-test.ts index d948cf4c5..99bfdcb80 100644 --- a/app/javascript/mastodon/utils/__tests__/html-test.s +++ b/app/javascript/mastodon/utils/__tests__/html-test.ts @@ -3,7 +3,9 @@ import * as html from '../html'; describe('html', () => { describe('unescapeHTML', () => { it('returns unescaped HTML', () => { - const output = html.unescapeHTML('

lorem

ipsum


<br>'); + const output = html.unescapeHTML( + '

lorem

ipsum


<br>', + ); expect(output).toEqual('lorem\n\nipsum\n
'); }); }); diff --git a/app/javascript/mastodon/utils/__tests__/numbers.ts b/app/javascript/mastodon/utils/__tests__/numbers.ts new file mode 100644 index 000000000..d1d1444e8 --- /dev/null +++ b/app/javascript/mastodon/utils/__tests__/numbers.ts @@ -0,0 +1,24 @@ +import { DECIMAL_UNITS, toShortNumber } from '../numbers'; + +interface TableRow { + input: number; + base: number; + unit: number; + digits: number; +} + +describe.each` + input | base | unit | digits + ${10_000_000} | ${10} | ${DECIMAL_UNITS.MILLION} | ${0} + ${2_789_123} | ${2.789123} | ${DECIMAL_UNITS.MILLION} | ${1} + ${12_345_789} | ${12.345789} | ${DECIMAL_UNITS.MILLION} | ${0} + ${10_000_000_000} | ${10} | ${DECIMAL_UNITS.BILLION} | ${0} + ${12} | ${12} | ${DECIMAL_UNITS.ONE} | ${0} + ${123} | ${123} | ${DECIMAL_UNITS.ONE} | ${0} + ${1234} | ${1.234} | ${DECIMAL_UNITS.THOUSAND} | ${1} + ${6666} | ${6.666} | ${DECIMAL_UNITS.THOUSAND} | ${1} +`('toShortNumber', ({ input, base, unit, digits }: TableRow) => { + test(`correctly formats ${input}`, () => { + expect(toShortNumber(input)).toEqual([base, unit, digits]); + }); +}); diff --git a/app/javascript/mastodon/utils/numbers.ts b/app/javascript/mastodon/utils/numbers.ts index ee2dabf56..0c11c268d 100644 --- a/app/javascript/mastodon/utils/numbers.ts +++ b/app/javascript/mastodon/utils/numbers.ts @@ -70,10 +70,10 @@ export function roundTo10(num: number): number { return Math.round(num * 0.1) / 0.1; } -export function toCappedNumber(num: string): string { - if (parseInt(num) > 99) { - return '99+'; +export function toCappedNumber(num: number, max = 99): string { + if (num > max) { + return `${max}+`; } else { - return num; + return num.toString(); } } diff --git a/app/javascript/mastodon/uuid.ts b/app/javascript/mastodon/uuid.ts index 4d0a8a803..0b4d55beb 100644 --- a/app/javascript/mastodon/uuid.ts +++ b/app/javascript/mastodon/uuid.ts @@ -4,5 +4,6 @@ export function uuid(a?: string): string { (a as unknown as number) ^ ((Math.random() * 16) >> ((a as unknown as number) / 4)) ).toString(16) - : ('' + 1e7 + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid); + : // eslint-disable-next-line @typescript-eslint/restrict-plus-operands + ('' + 1e7 + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid); } diff --git a/app/javascript/styles/mastodon-light/diff.scss b/app/javascript/styles/mastodon-light/diff.scss index 493e377d6..07e9d9868 100644 --- a/app/javascript/styles/mastodon-light/diff.scss +++ b/app/javascript/styles/mastodon-light/diff.scss @@ -80,6 +80,7 @@ html { } .search__input, +.search__popout, .setting-text, .report-dialog-modal__textarea, .audio-player { @@ -439,7 +440,8 @@ html { .directory__tag > div, .card > a, .page-header, -.compose-form .compose-form__warning { +.compose-form, +.compose-form__warning { box-shadow: none; } @@ -481,6 +483,10 @@ html { .compose-form .autosuggest-textarea__textarea, .compose-form__highlightable, +.search__input, +.search__popout, +.emoji-mart-search input, +.language-dropdown__dropdown .emoji-mart-search input, .poll__option input[type='text'] { background: darken($ui-base-color, 10%); } diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index fadd77d13..06a3b5202 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -10,6 +10,13 @@ $content-width: 840px; width: 100%; min-height: 100vh; + .icon { + width: 16px; + height: 16px; + vertical-align: middle; + margin: 0 2px; + } + .sidebar-wrapper { min-height: 100vh; overflow: hidden; diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 4bb3216e4..9cb03bedf 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -2015,7 +2015,22 @@ a .account__avatar { white-space: nowrap; display: flex; align-items: center; - gap: 4px; + gap: 8px; +} + +.account__relationship, +.explore__suggestions__card { + .icon-button { + border: 1px solid var(--background-border-color); + border-radius: 4px; + box-sizing: content-box; + padding: 5px; + + .icon { + width: 24px; + height: 24px; + } + } } .account-authorize { @@ -2165,6 +2180,45 @@ a.account__display-name { } } +.notification__relationships-severance-event, +.notification__moderation-warning { + display: flex; + gap: 16px; + color: $secondary-text-color; + text-decoration: none; + align-items: flex-start; + padding: 16px 32px; + border-bottom: 1px solid var(--background-border-color); + + &:hover { + color: $primary-text-color; + } + + .icon { + padding: 2px; + color: $highlight-text-color; + } + + &__content { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 8px; + flex-grow: 1; + font-size: 16px; + line-height: 24px; + + strong { + font-weight: 700; + } + + .link-button { + font-size: inherit; + line-height: inherit; + } + } +} + .notification__message { padding: 16px; padding-bottom: 0; @@ -2206,14 +2260,14 @@ a.account__display-name { &.activate { & > .icon { animation: spring-rotate-in 1s linear; - transform-origin: 50% 55%; + transform-origin: 50% 52%; } } &.deactivate { & > .icon { animation: spring-rotate-out 1s linear; - transform-origin: 50% 55%; + transform-origin: 50% 52%; } } } @@ -2574,6 +2628,7 @@ a.account__display-name { } $ui-header-height: 55px; +$ui-header-logo-wordmark-width: 99px; .ui__header { display: none; @@ -2589,6 +2644,10 @@ $ui-header-height: 55px; &__logo { display: inline-flex; padding: 15px; + flex-grow: 1; + flex-shrink: 1; + overflow: hidden; + container: header-logo / inline-size; .logo { height: $ui-header-height - 30px; @@ -2599,7 +2658,7 @@ $ui-header-height: 55px; display: none; } - @media screen and (width >= 320px) { + @container header-logo (min-width: #{$ui-header-logo-wordmark-width}) { .logo--wordmark { display: block; } @@ -2616,6 +2675,7 @@ $ui-header-height: 55px; gap: 10px; padding: 0 10px; overflow: hidden; + flex-shrink: 0; .button { flex: 0 0 auto; @@ -2633,7 +2693,7 @@ $ui-header-height: 55px; } .tabs-bar__wrapper { - background: var(--background-color-tint); + background: var(--background-color); backdrop-filter: var(--background-filter); position: sticky; top: $ui-header-height; @@ -2852,24 +2912,31 @@ $ui-header-height: 55px; } } - .layout-single-column .ui__header { - display: flex; - background: var(--background-color-tint); - border-bottom: 1px solid var(--background-border-color); - } + .layout-single-column { + .ui__header { + display: flex; + background: var(--background-color); + border-bottom: 1px solid var(--background-border-color); + } - .column > .scrollable, - .tabs-bar__wrapper .column-header, - .tabs-bar__wrapper .column-back-button { - border-left: 0; - border-right: 0; - } + .column > .scrollable, + .tabs-bar__wrapper .column-header, + .tabs-bar__wrapper .column-back-button { + border-left: 0; + border-right: 0; + } - .column-header, - .column-back-button, - .scrollable, - .error-column { - border-radius: 0 !important; + .column-header, + .column-back-button, + .scrollable, + .error-column { + border-radius: 0 !important; + } + + .column-header, + .column-back-button { + border-top: 0; + } } } @@ -2901,6 +2968,75 @@ $ui-header-height: 55px; display: none; } +.explore__suggestions__card { + padding: 12px 16px; + gap: 8px; + display: flex; + flex-direction: column; + border-bottom: 1px solid var(--background-border-color); + + &:last-child { + border-bottom: 0; + } + + &__source { + padding-inline-start: 60px; + font-size: 13px; + line-height: 16px; + color: $dark-text-color; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + } + + &__body { + display: flex; + gap: 12px; + align-items: center; + + &__main { + flex: 1 1 auto; + display: flex; + flex-direction: column; + gap: 8px; + min-width: 0; + + &__name-button { + display: flex; + align-items: center; + gap: 8px; + + &__name { + display: block; + color: inherit; + text-decoration: none; + flex: 1 1 auto; + min-width: 0; + } + + .button { + min-width: 80px; + } + + .display-name { + font-size: 15px; + line-height: 20px; + color: $secondary-text-color; + + strong { + font-weight: 700; + } + + &__account { + color: $darker-text-color; + display: block; + } + } + } + } + } +} + @media screen and (max-width: $no-gap-breakpoint - 1px) { .columns-area__panels__pane--compositional { display: none; @@ -3428,10 +3564,6 @@ $ui-header-height: 55px; &:hover { text-decoration: underline; } - - @media screen and (max-width: $no-gap-breakpoint) { - border-top: 0; - } } .column-header__back-button { @@ -4195,10 +4327,6 @@ a.status-card { padding-top: 16px; } } - - @media screen and (max-width: $no-gap-breakpoint) { - border-top: 0; - } } .column-header__buttons { @@ -5047,6 +5175,7 @@ a.status-card { .language-dropdown__dropdown { box-shadow: var(--dropdown-shadow); background: var(--dropdown-background-color); + backdrop-filter: var(--background-filter); border: 1px solid var(--dropdown-border-color); padding: 4px; border-radius: 4px; @@ -7237,10 +7366,11 @@ a.status-card { content: ''; position: absolute; bottom: -1px; - left: 0; - width: 100%; + left: 50%; + transform: translateX(-50%); + width: 40px; height: 3px; - border-radius: 4px; + border-radius: 4px 4px 0 0; background: $highlight-text-color; } } @@ -7819,8 +7949,13 @@ noscript { } } - @container account-header (max-width: 372px) { - .optional { + .optional { + @container account-header (max-width: 372px) { + display: none; + } + + // Fallback for older browsers with no container queries support + @media screen and (max-width: 372px + 55px) { display: none; } } @@ -9734,18 +9869,24 @@ noscript { margin-top: 16px; display: flex; flex-wrap: wrap; - font-size: 14px; - line-height: 18px; - gap: 4px; + font-size: 12px; + line-height: 16px; + gap: 6px; color: $darker-text-color; a { display: inline-flex; color: inherit; text-decoration: none; + padding: 4px 12px; + background: $ui-base-color; + border-radius: 4px; + font-weight: 500; - &:hover span { - text-decoration: underline; + &:hover, + &:focus, + &:active { + background: lighten($ui-base-color, 4%); } } @@ -9961,10 +10102,10 @@ noscript { .filtered-notifications-banner { display: flex; align-items: center; - background: $ui-base-color; - border-bottom: 1px solid lighten($ui-base-color, 8%); - padding: 15px; - gap: 15px; + border: 1px solid var(--background-border-color); + border-top: 0; + padding: 24px 32px; + gap: 16px; color: $darker-text-color; text-decoration: none; @@ -9972,15 +10113,12 @@ noscript { &:active, &:focus { color: $secondary-text-color; - - .filtered-notifications-banner__badge { - background: $secondary-text-color; - } } .icon { width: 24px; height: 24px; + padding: 2px; } &__text { @@ -9996,13 +10134,24 @@ noscript { } &__badge { - background: $darker-text-color; - color: $ui-base-color; - border-radius: 100px; - padding: 2px 8px; + display: flex; + align-items: center; + border-radius: 999px; + background: var(--background-border-color); + color: $darker-text-color; + padding: 4px; + padding-inline-end: 8px; + gap: 6px; font-weight: 500; font-size: 11px; line-height: 16px; + + &__badge { + background: $ui-button-background-color; + color: $white; + border-radius: 100px; + padding: 2px 8px; + } } } @@ -10011,7 +10160,7 @@ noscript { align-items: center; gap: 16px; padding: 15px; - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); &__link { display: flex; @@ -10046,9 +10195,10 @@ noscript { } .filtered-notifications-banner__badge { - background-color: $highlight-text-color; + background: $ui-button-background-color; border-radius: 4px; padding: 1px 6px; + color: $white; } } @@ -10059,7 +10209,7 @@ noscript { .icon-button { border-radius: 4px; - border: 1px solid lighten($ui-base-color, 8%); + border: 1px solid var(--background-border-color); padding: 5px; } } diff --git a/app/javascript/styles/mastodon/emoji_picker.scss b/app/javascript/styles/mastodon/emoji_picker.scss index 14ce6a14b..b9fdaa584 100644 --- a/app/javascript/styles/mastodon/emoji_picker.scss +++ b/app/javascript/styles/mastodon/emoji_picker.scss @@ -112,10 +112,11 @@ border: 0; } - &::-moz-focus-inner, - &:focus, - &:active { - outline: 0 !important; + &:active, + &:focus { + outline: none !important; + border-width: 1px !important; + border-color: $ui-button-background-color; } &::-webkit-search-cancel-button { diff --git a/app/lib/account_statuses_filter.rb b/app/lib/account_statuses_filter.rb index eb7592cdc..cfc9be966 100644 --- a/app/lib/account_statuses_filter.rb +++ b/app/lib/account_statuses_filter.rb @@ -35,7 +35,7 @@ class AccountStatusesFilter return Status.none if account.unavailable? if anonymous? - account.statuses.where(visibility: %i(public unlisted)) + account.statuses.distributable_visibility elsif author? account.statuses.all # NOTE: #merge! does not work without the #all elsif blocked? diff --git a/app/lib/admin/metrics/measure/tag_servers_measure.rb b/app/lib/admin/metrics/measure/tag_servers_measure.rb index e0f1bf344..f273d739d 100644 --- a/app/lib/admin/metrics/measure/tag_servers_measure.rb +++ b/app/lib/admin/metrics/measure/tag_servers_measure.rb @@ -46,11 +46,11 @@ class Admin::Metrics::Measure::TagServersMeasure < Admin::Metrics::Measure::Base end def earliest_status_id - Mastodon::Snowflake.id_at(@start_at, with_random: false) + Mastodon::Snowflake.id_at(@start_at.beginning_of_day, with_random: false) end def latest_status_id - Mastodon::Snowflake.id_at(@end_at, with_random: false) + Mastodon::Snowflake.id_at(@end_at.end_of_day, with_random: false) end def tag diff --git a/app/lib/annual_report/top_statuses.rb b/app/lib/annual_report/top_statuses.rb index 112e5591c..1ab170952 100644 --- a/app/lib/annual_report/top_statuses.rb +++ b/app/lib/annual_report/top_statuses.rb @@ -16,6 +16,6 @@ class AnnualReport::TopStatuses < AnnualReport::Source end def base_scope - @account.statuses.with_public_visibility.joins(:status_stat).where(id: year_as_snowflake_range).reorder(nil) + @account.statuses.public_visibility.joins(:status_stat).where(id: year_as_snowflake_range).reorder(nil) end end diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 38a177e64..95a687fa4 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -18,7 +18,7 @@ class FeedManager # @yield [Account] # @return [void] def with_active_accounts(&block) - Account.joins(:user).where('users.current_sign_in_at > ?', User::ACTIVE_DURATION.ago).find_each(&block) + Account.joins(:user).merge(User.signed_in_recently).find_each(&block) end # Redis key of a feed @@ -109,7 +109,7 @@ class FeedManager def merge_into_home(from_account, into_account) timeline_key = key(:home, into_account.id) aggregate = into_account.user&.aggregates_reblogs? - query = from_account.statuses.where(visibility: [:public, :unlisted, :private]).includes(:preloadable_poll, :media_attachments, reblog: :account).limit(FeedManager::MAX_ITEMS / 4) + query = from_account.statuses.list_eligible_visibility.includes(:preloadable_poll, :media_attachments, reblog: :account).limit(FeedManager::MAX_ITEMS / 4) if redis.zcard(timeline_key) >= FeedManager::MAX_ITEMS / 4 oldest_home_score = redis.zrange(timeline_key, 0, 0, with_scores: true).first.last.to_i @@ -135,7 +135,7 @@ class FeedManager def merge_into_list(from_account, list) timeline_key = key(:list, list.id) aggregate = list.account.user&.aggregates_reblogs? - query = from_account.statuses.where(visibility: [:public, :unlisted, :private]).includes(:preloadable_poll, :media_attachments, reblog: :account).limit(FeedManager::MAX_ITEMS / 4) + query = from_account.statuses.list_eligible_visibility.includes(:preloadable_poll, :media_attachments, reblog: :account).limit(FeedManager::MAX_ITEMS / 4) if redis.zcard(timeline_key) >= FeedManager::MAX_ITEMS / 4 oldest_home_score = redis.zrange(timeline_key, 0, 0, with_scores: true).first.last.to_i @@ -274,7 +274,7 @@ class FeedManager next if last_status_score < oldest_home_score end - statuses = target_account.statuses.where(visibility: [:public, :unlisted, :private]).includes(:preloadable_poll, :media_attachments, :account, reblog: :account).limit(limit) + statuses = target_account.statuses.list_eligible_visibility.includes(:preloadable_poll, :media_attachments, :account, reblog: :account).limit(limit) crutches = build_crutches(account.id, statuses) statuses.each do |status| @@ -431,10 +431,10 @@ class FeedManager # @param [List] list # @return [Boolean] def filter_from_list?(status, list) - if status.reply? && status.in_reply_to_account_id != status.account_id - should_filter = status.in_reply_to_account_id != list.account_id - should_filter &&= !list.show_followed? - should_filter &&= !(list.show_list? && ListAccount.exists?(list_id: list.id, account_id: status.in_reply_to_account_id)) + if status.reply? && status.in_reply_to_account_id != status.account_id # Status is a reply to account other than status account + should_filter = status.in_reply_to_account_id != list.account_id # Status replies to account id other than list account + should_filter &&= !list.show_followed? # List show_followed? is false + should_filter &&= !(list.show_list? && ListAccount.exists?(list_id: list.id, account_id: status.in_reply_to_account_id)) # If show_list? true, check for a ListAccount with list and reply to account return !!should_filter end @@ -449,7 +449,11 @@ class FeedManager # @param [Hash] crutches # @return [Boolean] def filter_from_tags?(status, receiver_id, crutches) - receiver_id == status.account_id || ((crutches[:active_mentions][status.id] || []) + [status.account_id]).any? { |target_account_id| crutches[:blocking][target_account_id] || crutches[:muting][target_account_id] } || crutches[:blocked_by][status.account_id] || crutches[:domain_blocking][status.account.domain] + receiver_id == status.account_id || # Receiver is status account? + ((crutches[:active_mentions][status.id] || []) + [status.account_id]) # For mentioned accounts or status account: + .any? { |target_account_id| crutches[:blocking][target_account_id] || crutches[:muting][target_account_id] } || # - Target account is muted or blocked? + crutches[:blocked_by][status.account_id] || # Blocked by status account? + crutches[:domain_blocking][status.account.domain] # Blocking domain of status account? end # Adds a status to an account's feed, returning true if a status was diff --git a/app/lib/link_details_extractor.rb b/app/lib/link_details_extractor.rb index bb031986d..bec7d3a45 100644 --- a/app/lib/link_details_extractor.rb +++ b/app/lib/link_details_extractor.rb @@ -156,7 +156,7 @@ class LinkDetailsExtractor end def title - html_entities.decode(structured_data&.headline || opengraph_tag('og:title') || document.xpath('//title').map(&:content).first) + html_entities.decode(structured_data&.headline || opengraph_tag('og:title') || document.xpath('//title').map(&:content).first).strip end def description diff --git a/app/lib/themes.rb b/app/lib/themes.rb index 243ffb9ab..b6da98073 100644 --- a/app/lib/themes.rb +++ b/app/lib/themes.rb @@ -6,11 +6,16 @@ require 'yaml' class Themes include Singleton + THEME_COLORS = { + dark: '#191b22', + light: '#f3f5f7', + }.freeze + def initialize @conf = YAML.load_file(Rails.root.join('config', 'themes.yml')) end def names - @conf.keys + ['system'] + @conf.keys end end diff --git a/app/lib/vacuum/feeds_vacuum.rb b/app/lib/vacuum/feeds_vacuum.rb index fb0b8a847..429215760 100644 --- a/app/lib/vacuum/feeds_vacuum.rb +++ b/app/lib/vacuum/feeds_vacuum.rb @@ -21,7 +21,7 @@ class Vacuum::FeedsVacuum end def inactive_users - User.confirmed.inactive + User.confirmed.not_signed_in_recently end def inactive_users_lists diff --git a/app/lib/vacuum/imports_vacuum.rb b/app/lib/vacuum/imports_vacuum.rb index ffb9449a4..8c8bb783a 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/lib/video_metadata_extractor.rb b/app/lib/video_metadata_extractor.rb index f27d34868..df5409375 100644 --- a/app/lib/video_metadata_extractor.rb +++ b/app/lib/video_metadata_extractor.rb @@ -22,7 +22,7 @@ class VideoMetadataExtractor private def ffmpeg_command_output - command = Terrapin::CommandLine.new('ffprobe', '-i :path -print_format :format -show_format -show_streams -show_error -loglevel :loglevel') + command = Terrapin::CommandLine.new(Rails.configuration.x.ffprobe_binary, '-i :path -print_format :format -show_format -show_streams -show_error -loglevel :loglevel') command.run(path: @path, format: 'json', loglevel: 'fatal') end diff --git a/app/mailers/admin_mailer.rb b/app/mailers/admin_mailer.rb index 8990b2a84..8dd7b6e59 100644 --- a/app/mailers/admin_mailer.rb +++ b/app/mailers/admin_mailer.rb @@ -46,12 +46,16 @@ class AdminMailer < ApplicationMailer end def new_software_updates + @software_updates = SoftwareUpdate.all.to_a.sort_by(&:gem_version) + locale_for_account(@me) do mail subject: default_i18n_subject(instance: @instance) end end def new_critical_software_updates + @software_updates = SoftwareUpdate.where(urgent: true).to_a.sort_by(&:gem_version) + headers['Priority'] = 'urgent' headers['X-Priority'] = '1' headers['Importance'] = 'high' diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 96fcd51ef..f8c1c9a8d 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -5,10 +5,11 @@ class UserMailer < Devise::Mailer helper :accounts helper :application - helper :instance - helper :statuses + helper :mascot helper :formatting + helper :instance helper :routing + helper :statuses before_action :set_instance diff --git a/app/models/account.rb b/app/models/account.rb index 1e4fe0a60..a04b4f1ab 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -64,6 +64,7 @@ class Account < ApplicationRecord ) BACKGROUND_REFRESH_INTERVAL = 1.week.freeze + DEFAULT_FIELDS_SIZE = 8 INSTANCE_ACTOR_ID = -99 USERNAME_RE = /[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?/i @@ -103,7 +104,7 @@ class Account < ApplicationRecord validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? && actor_type != 'Application' } validates :display_name, length: { maximum: 30 }, if: -> { local? && will_save_change_to_display_name? } validates :note, note_length: { maximum: 500 }, if: -> { local? && will_save_change_to_note? } - validates :fields, length: { maximum: 8 }, if: -> { local? && will_save_change_to_fields? } + validates :fields, length: { maximum: DEFAULT_FIELDS_SIZE }, if: -> { local? && will_save_change_to_fields? } validates :uri, absence: true, if: :local?, on: :create validates :inbox_url, absence: true, if: :local?, on: :create validates :shared_inbox_url, absence: true, if: :local?, on: :create @@ -132,12 +133,13 @@ class Account < ApplicationRecord scope :auditable, -> { where(id: Admin::ActionLog.select(:account_id).distinct) } scope :searchable, -> { without_unapproved.without_suspended.where(moved_to_account_id: nil) } scope :discoverable, -> { searchable.without_silenced.where(discoverable: true).joins(:account_stat) } - scope :by_recent_status, -> { includes(:account_stat).merge(AccountStat.order('last_status_at DESC NULLS LAST')).references(:account_stat) } + scope :by_recent_status, -> { includes(:account_stat).merge(AccountStat.by_recent_status).references(:account_stat) } scope :by_recent_activity, -> { left_joins(:user, :account_stat).order(coalesced_activity_timestamps.desc).order(id: :desc) } scope :popular, -> { order('account_stats.followers_count desc') } scope :by_domain_and_subdomains, ->(domain) { where(domain: Instance.by_domain_and_subdomains(domain).select(:domain)) } scope :not_excluded_by_account, ->(account) { where.not(id: account.excluded_from_timeline_account_ids) } scope :not_domain_blocked_by_account, ->(account) { where(arel_table[:domain].eq(nil).or(arel_table[:domain].not_in(account.excluded_from_timeline_domains))) } + scope :dormant, -> { joins(:account_stat).merge(AccountStat.without_recent_activity) } after_update_commit :trigger_update_webhooks @@ -352,8 +354,6 @@ class Account < ApplicationRecord self[:fields] = fields end - DEFAULT_FIELDS_SIZE = 8 - def build_fields return if fields.size >= DEFAULT_FIELDS_SIZE diff --git a/app/models/account_moderation_note.rb b/app/models/account_moderation_note.rb index ff399bab0..ad49b2422 100644 --- a/app/models/account_moderation_note.rb +++ b/app/models/account_moderation_note.rb @@ -13,10 +13,12 @@ # class AccountModerationNote < ApplicationRecord + CONTENT_SIZE_LIMIT = 500 + belongs_to :account belongs_to :target_account, class_name: 'Account' scope :latest, -> { reorder('created_at DESC') } - validates :content, presence: true, length: { maximum: 500 } + validates :content, presence: true, length: { maximum: CONTENT_SIZE_LIMIT } end diff --git a/app/models/account_note.rb b/app/models/account_note.rb index 9bc704d98..317e6873f 100644 --- a/app/models/account_note.rb +++ b/app/models/account_note.rb @@ -14,9 +14,11 @@ class AccountNote < ApplicationRecord include RelationshipCacheable + COMMENT_SIZE_LIMIT = 2_000 + belongs_to :account belongs_to :target_account, class_name: 'Account' validates :account_id, uniqueness: { scope: :target_account_id } - validates :comment, length: { maximum: 2_000 } + validates :comment, length: { maximum: COMMENT_SIZE_LIMIT } end diff --git a/app/models/account_stat.rb b/app/models/account_stat.rb index 0fea7732e..14aa7ef80 100644 --- a/app/models/account_stat.rb +++ b/app/models/account_stat.rb @@ -20,6 +20,9 @@ class AccountStat < ApplicationRecord belongs_to :account, inverse_of: :account_stat + scope :by_recent_status, -> { order(arel_table[:last_status_at].desc.nulls_last) } + scope :without_recent_activity, -> { where(last_status_at: [nil, ...1.month.ago]) } + update_index('accounts', :account) def following_count diff --git a/app/models/account_warning.rb b/app/models/account_warning.rb index a54387a56..7aa474887 100644 --- a/app/models/account_warning.rb +++ b/app/models/account_warning.rb @@ -27,6 +27,8 @@ class AccountWarning < ApplicationRecord suspend: 4_000, }, suffix: :action + RECENT_PERIOD = 3.months.freeze + normalizes :text, with: ->(text) { text.to_s }, apply_to_nil: true belongs_to :account, inverse_of: :account_warnings @@ -37,7 +39,7 @@ class AccountWarning < ApplicationRecord scope :latest, -> { order(id: :desc) } scope :custom, -> { where.not(text: '') } - scope :recent, -> { where('account_warnings.created_at >= ?', 3.months.ago) } + scope :recent, -> { where(created_at: RECENT_PERIOD.ago..) } def statuses Status.with_discarded.where(id: status_ids || []) diff --git a/app/models/admin/account_action.rb b/app/models/admin/account_action.rb index 2b5560e2e..3700ce4cd 100644 --- a/app/models/admin/account_action.rb +++ b/app/models/admin/account_action.rb @@ -52,7 +52,7 @@ class Admin::AccountAction process_reports! end - process_email! + process_notification! process_queue! end @@ -158,8 +158,11 @@ class Admin::AccountAction queue_suspension_worker! if type == 'suspend' end - def process_email! - UserMailer.warning(target_account.user, warning).deliver_later! if warnable? + def process_notification! + return unless warnable? + + UserMailer.warning(target_account.user, warning).deliver_later! + LocalNotificationWorker.perform_async(target_account.id, warning.id, 'AccountWarning', 'moderation_warning') end def warnable? diff --git a/app/models/admin/import.rb b/app/models/admin/import.rb index 0fd4bdb82..c12c9a86b 100644 --- a/app/models/admin/import.rb +++ b/app/models/admin/import.rb @@ -30,12 +30,14 @@ class Admin::Import csv_converter = lambda do |field, field_info| case field_info.header - when '#domain', '#public_comment' + when '#domain' + field&.downcase&.strip + when '#public_comment' field&.strip when '#severity' - field&.strip&.to_sym + field&.downcase&.strip&.to_sym when '#reject_media', '#reject_reports', '#obfuscate' - ActiveModel::Type::Boolean.new.cast(field) + ActiveModel::Type::Boolean.new.cast(field&.downcase) else field end diff --git a/app/models/admin/status_batch_action.rb b/app/models/admin/status_batch_action.rb index 8a8e2fa37..4a1000193 100644 --- a/app/models/admin/status_batch_action.rb +++ b/app/models/admin/status_batch_action.rb @@ -65,7 +65,8 @@ class Admin::StatusBatchAction statuses.each { |status| Tombstone.find_or_create_by(uri: status.uri, account: status.account, by_moderator: true) } unless target_account.local? end - UserMailer.warning(target_account.user, @warning).deliver_later! if warnable? + process_notification! + RemovalWorker.push_bulk(status_ids) { |status_id| [status_id, { 'preserve' => target_account.local?, 'immediate' => !target_account.local? }] } end @@ -101,7 +102,7 @@ class Admin::StatusBatchAction text: text ) - UserMailer.warning(target_account.user, @warning).deliver_later! if warnable? + process_notification! end def handle_report! @@ -127,6 +128,13 @@ class Admin::StatusBatchAction !report.nil? end + def process_notification! + return unless warnable? + + UserMailer.warning(target_account.user, @warning).deliver_later! + LocalNotificationWorker.perform_async(target_account.id, @warning.id, 'AccountWarning', 'moderation_warning') + end + def warnable? send_email_notification && target_account.local? end diff --git a/app/models/admin/status_filter.rb b/app/models/admin/status_filter.rb index 4708785e7..8d20e4f6a 100644 --- a/app/models/admin/status_filter.rb +++ b/app/models/admin/status_filter.rb @@ -16,7 +16,7 @@ class Admin::StatusFilter end def results - scope = @account.statuses.where(visibility: [:public, :unlisted]) + scope = @account.statuses.distributable_visibility params.each do |key, value| next if IGNORED_PARAMS.include?(key.to_s) diff --git a/app/models/announcement.rb b/app/models/announcement.rb index e63057002..54923ed08 100644 --- a/app/models/announcement.rb +++ b/app/models/announcement.rb @@ -59,11 +59,13 @@ class Announcement < ApplicationRecord end def statuses - @statuses ||= if status_ids.nil? - [] - else - Status.where(id: status_ids, visibility: [:public, :unlisted]) - end + @statuses ||= begin + if status_ids.nil? + [] + else + Status.with_includes.distributable_visibility.where(id: status_ids) + end + end end def tags diff --git a/app/models/bulk_import.rb b/app/models/bulk_import.rb index 4cd228705..9b3f4c8a3 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/models/concerns/account/counters.rb b/app/models/concerns/account/counters.rb index 448839812..536d5ca7b 100644 --- a/app/models/concerns/account/counters.rb +++ b/app/models/concerns/account/counters.rb @@ -35,40 +35,11 @@ module Account::Counters raise ArgumentError, "Invalid key #{key}" unless ALLOWED_COUNTER_KEYS.include?(key) raise ArgumentError, 'Do not call update_count! on dirty objects' if association(:account_stat).loaded? && account_stat&.changed? && account_stat.changed_attribute_names_to_save == %w(id) - value = value.to_i - default_value = value.positive? ? value : 0 - - # We do an upsert using manually written SQL, as Rails' upsert method does - # not seem to support writing expressions in the UPDATE clause, but only - # re-insert the provided values instead. - # Even ARel seem to be missing proper handling of upserts. - sql = if value.positive? && key == :statuses_count - <<-SQL.squish - INSERT INTO account_stats(account_id, #{key}, created_at, updated_at, last_status_at) - VALUES (:account_id, :default_value, now(), now(), now()) - ON CONFLICT (account_id) DO UPDATE - SET #{key} = account_stats.#{key} + :value, - last_status_at = now(), - updated_at = now() - RETURNING id; - SQL - else - <<-SQL.squish - INSERT INTO account_stats(account_id, #{key}, created_at, updated_at) - VALUES (:account_id, :default_value, now(), now()) - ON CONFLICT (account_id) DO UPDATE - SET #{key} = account_stats.#{key} + :value, - updated_at = now() - RETURNING id; - SQL - end - - sql = AccountStat.sanitize_sql([sql, account_id: id, default_value: default_value, value: value]) - account_stat_id = AccountStat.connection.exec_query(sql)[0]['id'] + result = updated_account_stat(key, value.to_i) # Reload account_stat if it was loaded, taking into account newly-created unsaved records if association(:account_stat).loaded? - account_stat.id = account_stat_id if account_stat.new_record? + account_stat.id = result.first['id'] if account_stat.new_record? account_stat.reload end end @@ -79,6 +50,28 @@ module Account::Counters private + def updated_account_stat(key, value) + AccountStat.upsert( + initial_values(key, value), + on_duplicate: Arel.sql( + duplicate_values(key, value).join(', ') + ), + unique_by: :account_id + ) + end + + def initial_values(key, value) + { :account_id => id, key => [value, 0].max }.tap do |values| + values.merge!(last_status_at: Time.current) if key == :statuses_count + end + end + + def duplicate_values(key, value) + ["#{key} = (account_stats.#{key} + #{value})", 'updated_at = CURRENT_TIMESTAMP'].tap do |values| + values << 'last_status_at = CURRENT_TIMESTAMP' if key == :statuses_count && value.positive? + end + end + def save_account_stat return unless association(:account_stat).loaded? && account_stat&.changed? diff --git a/app/models/concerns/account/interactions.rb b/app/models/concerns/account/interactions.rb index a32697b66..536afba17 100644 --- a/app/models/concerns/account/interactions.rb +++ b/app/models/concerns/account/interactions.rb @@ -255,13 +255,13 @@ module Account::Interactions def followers_for_local_distribution followers.local .joins(:user) - .where('users.current_sign_in_at > ?', User::ACTIVE_DURATION.ago) + .merge(User.signed_in_recently) end def lists_for_local_distribution scope = lists.joins(account: :user) scope.where.not(list_accounts: { follow_id: nil }).or(scope.where(account_id: id)) - .where('users.current_sign_in_at > ?', User::ACTIVE_DURATION.ago) + .merge(User.signed_in_recently) end def remote_followers_hash(url) diff --git a/app/models/concerns/cacheable.rb b/app/models/concerns/cacheable.rb index d7524cdfd..0633f20c7 100644 --- a/app/models/concerns/cacheable.rb +++ b/app/models/concerns/cacheable.rb @@ -14,6 +14,10 @@ module Cacheable includes(@cache_associated) end + def preload_cacheable_associations(records) + ActiveRecord::Associations::Preloader.new(records: records, associations: @cache_associated).call + end + def cache_ids select(:id, :updated_at) end diff --git a/app/models/concerns/custom_filter_cache.rb b/app/models/concerns/custom_filter_cache.rb new file mode 100644 index 000000000..79b22f11f --- /dev/null +++ b/app/models/concerns/custom_filter_cache.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module CustomFilterCache + extend ActiveSupport::Concern + + included do + after_commit :invalidate_cache! + before_destroy :prepare_cache_invalidation! + before_save :prepare_cache_invalidation! + + delegate( + :invalidate_cache!, + :prepare_cache_invalidation!, + to: :custom_filter + ) + end +end diff --git a/app/models/concerns/status/threading_concern.rb b/app/models/concerns/status/threading_concern.rb index 2606fd2f2..ca8c44814 100644 --- a/app/models/concerns/status/threading_concern.rb +++ b/app/models/concerns/status/threading_concern.rb @@ -12,7 +12,7 @@ module Status::ThreadingConcern end def self_replies(limit) - account.statuses.where(in_reply_to_id: id, visibility: [:public, :unlisted]).reorder(id: :asc).limit(limit) + account.statuses.distributable_visibility.where(in_reply_to_id: id).reorder(id: :asc).limit(limit) end private diff --git a/app/models/custom_filter.rb b/app/models/custom_filter.rb index 7c148e877..2d8f5b6cb 100644 --- a/app/models/custom_filter.rb +++ b/app/models/custom_filter.rb @@ -42,6 +42,7 @@ class CustomFilter < ApplicationRecord validate :context_must_be_valid normalizes :context, with: ->(context) { context.map(&:strip).filter_map(&:presence) } + scope :unexpired, -> { where(expires_at: nil).or where.not(expires_at: ..Time.zone.now) } before_save :prepare_cache_invalidation! before_destroy :prepare_cache_invalidation! @@ -66,14 +67,16 @@ class CustomFilter < ApplicationRecord active_filters = Rails.cache.fetch("filters:v3:#{account_id}") do filters_hash = {} - scope = CustomFilterKeyword.includes(:custom_filter).where(custom_filter: { account_id: account_id }).where(Arel.sql('expires_at IS NULL OR expires_at > NOW()')) + scope = CustomFilterKeyword.left_outer_joins(:custom_filter).merge(unexpired.where(account_id: account_id)) + scope.to_a.group_by(&:custom_filter).each do |filter, keywords| keywords.map!(&:to_regex) filters_hash[filter.id] = { keywords: Regexp.union(keywords), filter: filter } end.to_h - scope = CustomFilterStatus.includes(:custom_filter).where(custom_filter: { account_id: account_id }).where(Arel.sql('expires_at IS NULL OR expires_at > NOW()')) + scope = CustomFilterStatus.left_outer_joins(:custom_filter).merge(unexpired.where(account_id: account_id)) + scope.to_a.group_by(&:custom_filter).each do |filter, statuses| filters_hash[filter.id] ||= { filter: filter } filters_hash[filter.id].merge!(status_ids: statuses.map(&:status_id)) diff --git a/app/models/custom_filter_keyword.rb b/app/models/custom_filter_keyword.rb index 979d0b822..112798b10 100644 --- a/app/models/custom_filter_keyword.rb +++ b/app/models/custom_filter_keyword.rb @@ -13,16 +13,14 @@ # class CustomFilterKeyword < ApplicationRecord + include CustomFilterCache + belongs_to :custom_filter validates :keyword, presence: true alias_attribute :phrase, :keyword - before_save :prepare_cache_invalidation! - before_destroy :prepare_cache_invalidation! - after_commit :invalidate_cache! - def to_regex if whole_word? /(?mix:#{to_regex_sb}#{Regexp.escape(keyword)}#{to_regex_eb})/ @@ -40,12 +38,4 @@ class CustomFilterKeyword < ApplicationRecord def to_regex_eb /[[:word:]]\z/.match?(keyword) ? '\b' : '' end - - def prepare_cache_invalidation! - custom_filter.prepare_cache_invalidation! - end - - def invalidate_cache! - custom_filter.invalidate_cache! - end end diff --git a/app/models/custom_filter_status.rb b/app/models/custom_filter_status.rb index 0a5650204..58b61cd79 100644 --- a/app/models/custom_filter_status.rb +++ b/app/models/custom_filter_status.rb @@ -12,27 +12,17 @@ # class CustomFilterStatus < ApplicationRecord + include CustomFilterCache + belongs_to :custom_filter belongs_to :status validates :status, uniqueness: { scope: :custom_filter } validate :validate_status_access - before_save :prepare_cache_invalidation! - before_destroy :prepare_cache_invalidation! - after_commit :invalidate_cache! - private def validate_status_access errors.add(:status_id, :invalid) unless StatusPolicy.new(custom_filter.account, status).show? end - - def prepare_cache_invalidation! - custom_filter.prepare_cache_invalidation! - end - - def invalidate_cache! - custom_filter.invalidate_cache! - end end diff --git a/app/models/featured_tag.rb b/app/models/featured_tag.rb index ea8aa4787..cdd97205e 100644 --- a/app/models/featured_tag.rb +++ b/app/models/featured_tag.rb @@ -74,6 +74,6 @@ class FeaturedTag < ApplicationRecord end def visible_tagged_account_statuses - account.statuses.where(visibility: %i(public unlisted)).tagged_with(tag) + account.statuses.distributable_visibility.tagged_with(tag) end end diff --git a/app/models/feed.rb b/app/models/feed.rb index d9cab2cd1..27e128099 100644 --- a/app/models/feed.rb +++ b/app/models/feed.rb @@ -28,7 +28,7 @@ class Feed unhydrated = redis.zrangebyscore(key, "(#{min_id}", "(#{max_id}", limit: [0, limit], with_scores: true).map { |id| id.first.to_i } end - Status.where(id: unhydrated).cache_ids + Status.where(id: unhydrated) end def key diff --git a/app/models/form/import.rb b/app/models/form/import.rb index fc83d9c58..3cc4af064 100644 --- a/app/models/form/import.rb +++ b/app/models/form/import.rb @@ -111,12 +111,14 @@ class Form::Import csv_converter = lambda do |field, field_info| case field_info.header when 'Show boosts', 'Notify on new posts', 'Hide notifications' - ActiveModel::Type::Boolean.new.cast(field) + ActiveModel::Type::Boolean.new.cast(field&.downcase) when 'Languages' field&.split(',')&.map(&:strip)&.presence when 'Account address' field.strip.gsub(/\A@/, '') - when '#domain', '#uri', 'List name' + when '#domain' + field&.strip&.downcase + when '#uri', 'List name' field.strip else field diff --git a/app/models/invite.rb b/app/models/invite.rb index c0cbc5845..2fe9f22fb 100644 --- a/app/models/invite.rb +++ b/app/models/invite.rb @@ -19,12 +19,14 @@ class Invite < ApplicationRecord include Expireable + COMMENT_SIZE_LIMIT = 420 + belongs_to :user, inverse_of: :invites has_many :users, inverse_of: :invite, dependent: nil scope :available, -> { where(expires_at: nil).or(where('expires_at >= ?', Time.now.utc)) } - validates :comment, length: { maximum: 420 } + validates :comment, length: { maximum: COMMENT_SIZE_LIMIT } before_validation :set_code diff --git a/app/models/notification.rb b/app/models/notification.rb index b2376c78a..7e0e62683 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -57,6 +57,9 @@ class Notification < ApplicationRecord severed_relationships: { filterable: false, }.freeze, + moderation_warning: { + filterable: false, + }.freeze, 'admin.sign_up': { filterable: false, }.freeze, @@ -90,6 +93,7 @@ class Notification < ApplicationRecord belongs_to :poll, inverse_of: false belongs_to :report, inverse_of: false belongs_to :account_relationship_severance_event, inverse_of: false + belongs_to :account_warning, inverse_of: false end validates :type, inclusion: { in: TYPES } @@ -180,7 +184,7 @@ class Notification < ApplicationRecord return unless new_record? case activity_type - when 'Status', 'Follow', 'Favourite', 'FollowRequest', 'Poll', 'Report' + when 'Status', 'Follow', 'Favourite', 'FollowRequest', 'Poll', 'Report', 'AccountWarning' self.from_account_id = activity&.account_id when 'Mention' self.from_account_id = activity&.status&.account_id diff --git a/app/models/preview_card_trend.rb b/app/models/preview_card_trend.rb index da2ea2f8c..58155971a 100644 --- a/app/models/preview_card_trend.rb +++ b/app/models/preview_card_trend.rb @@ -15,5 +15,7 @@ class PreviewCardTrend < ApplicationRecord include RankedTrend belongs_to :preview_card + scope :allowed, -> { where(allowed: true) } + scope :not_allowed, -> { where(allowed: false) } end diff --git a/app/models/public_feed.rb b/app/models/public_feed.rb index 1e2cca4d3..ba9473db0 100644 --- a/app/models/public_feed.rb +++ b/app/models/public_feed.rb @@ -29,7 +29,7 @@ class PublicFeed scope.merge!(media_only_scope) if media_only? scope.merge!(language_scope) if account&.chosen_languages.present? - scope.cache_ids.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id) + scope.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id) end private diff --git a/app/models/relationship_filter.rb b/app/models/relationship_filter.rb index d686f9ed8..828610e46 100644 --- a/app/models/relationship_filter.rb +++ b/app/models/relationship_filter.rb @@ -114,7 +114,7 @@ class RelationshipFilter def activity_scope(value) case value when 'dormant' - Account.joins(:account_stat).where(account_stat: { last_status_at: [nil, ...1.month.ago] }) + Account.dormant else raise Mastodon::InvalidParameterError, "Unknown activity: #{value}" end diff --git a/app/models/report.rb b/app/models/report.rb index df7e3d2ef..3df5a20e1 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -26,6 +26,8 @@ class Report < ApplicationRecord include Paginable include RateLimitable + COMMENT_SIZE_LIMIT = 1_000 + rate_limit by: :account, family: :reports belongs_to :account @@ -46,7 +48,7 @@ class Report < ApplicationRecord # A report is considered local if the reporter is local delegate :local?, to: :account - validates :comment, length: { maximum: 1_000 }, if: :local? + validates :comment, length: { maximum: COMMENT_SIZE_LIMIT }, if: :local? validates :rule_ids, absence: true, if: -> { (category_changed? || rule_ids_changed?) && !violation? } validate :validate_rule_ids, if: -> { (category_changed? || rule_ids_changed?) && violation? } diff --git a/app/models/report_note.rb b/app/models/report_note.rb index 74b46027e..b5c40a18b 100644 --- a/app/models/report_note.rb +++ b/app/models/report_note.rb @@ -13,10 +13,12 @@ # class ReportNote < ApplicationRecord + CONTENT_SIZE_LIMIT = 500 + belongs_to :account belongs_to :report, inverse_of: :notes, touch: true scope :latest, -> { reorder(created_at: :desc) } - validates :content, presence: true, length: { maximum: 500 } + validates :content, presence: true, length: { maximum: CONTENT_SIZE_LIMIT } end diff --git a/app/models/rule.rb b/app/models/rule.rb index f28dc2ffe..99a36397a 100644 --- a/app/models/rule.rb +++ b/app/models/rule.rb @@ -15,9 +15,11 @@ class Rule < ApplicationRecord include Discard::Model + TEXT_SIZE_LIMIT = 300 + self.discard_column = :deleted_at - validates :text, presence: true, length: { maximum: 300 } + validates :text, presence: true, length: { maximum: TEXT_SIZE_LIMIT } scope :ordered, -> { kept.order(priority: :asc, id: :asc) } end diff --git a/app/models/status.rb b/app/models/status.rb index c8effd3da..c2d7985b4 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -110,7 +110,7 @@ class Status < ApplicationRecord scope :without_reblogs, -> { where(statuses: { reblog_of_id: nil }) } scope :tagged_with, ->(tag_ids) { joins(:statuses_tags).where(statuses_tags: { tag_id: tag_ids }) } scope :not_excluded_by_account, ->(account) { where.not(account_id: account.excluded_from_timeline_account_ids) } - scope :not_domain_blocked_by_account, ->(account) { account.excluded_from_timeline_domains.blank? ? left_outer_joins(:account) : left_outer_joins(:account).where('accounts.domain IS NULL OR accounts.domain NOT IN (?)', account.excluded_from_timeline_domains) } + scope :not_domain_blocked_by_account, ->(account) { account.excluded_from_timeline_domains.blank? ? left_outer_joins(:account) : left_outer_joins(:account).merge(Account.not_domain_blocked_by_account(account)) } scope :tagged_with_all, lambda { |tag_ids| Array(tag_ids).map(&:to_i).reduce(self) do |result, id| result.where(<<~SQL.squish, tag_id: id) @@ -121,6 +121,8 @@ class Status < ApplicationRecord scope :tagged_with_none, lambda { |tag_ids| where('NOT EXISTS (SELECT * FROM statuses_tags forbidden WHERE forbidden.status_id = statuses.id AND forbidden.tag_id IN (?))', tag_ids) } + scope :distributable_visibility, -> { where(visibility: %i(public unlisted)) } + scope :list_eligible_visibility, -> { where(visibility: %i(public unlisted private)) } after_create_commit :trigger_create_webhooks after_update_commit :trigger_update_webhooks @@ -346,38 +348,6 @@ class Status < ApplicationRecord StatusPin.select('status_id').where(status_id: status_ids).where(account_id: account_id).each_with_object({}) { |p, h| h[p.status_id] = true } end - def reload_stale_associations!(cached_items) - account_ids = [] - - cached_items.each do |item| - account_ids << item.account_id - account_ids << item.reblog.account_id if item.reblog? - end - - account_ids.uniq! - - status_ids = cached_items.map { |item| item.reblog? ? item.reblog_of_id : item.id }.uniq - - return if account_ids.empty? - - accounts = Account.where(id: account_ids).includes(:account_stat, :user).index_by(&:id) - - status_stats = StatusStat.where(status_id: status_ids).index_by(&:status_id) - - cached_items.each do |item| - item.account = accounts[item.account_id] - item.reblog.account = accounts[item.reblog.account_id] if item.reblog? - - if item.reblog? - status_stat = status_stats[item.reblog.id] - item.reblog.status_stat = status_stat if status_stat.present? - else - status_stat = status_stats[item.id] - item.status_stat = status_stat if status_stat.present? - end - end - end - def from_text(text) return [] if text.blank? diff --git a/app/models/tag.rb b/app/models/tag.rb index f2168ae90..58baa48c0 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/app/models/tag_feed.rb b/app/models/tag_feed.rb index b8cd63557..6b5831d24 100644 --- a/app/models/tag_feed.rb +++ b/app/models/tag_feed.rb @@ -33,7 +33,7 @@ class TagFeed < PublicFeed scope.merge!(account_filters_scope) if account? scope.merge!(media_only_scope) if media_only? - scope.cache_ids.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id) + scope.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id) end private diff --git a/app/models/trends/links.rb b/app/models/trends/links.rb index 76e50aa7a..0650c4109 100644 --- a/app/models/trends/links.rb +++ b/app/models/trends/links.rb @@ -86,8 +86,8 @@ class Trends::Links < Trends::Base def request_review PreviewCardTrend.pluck('distinct language').flat_map do |language| - score_at_threshold = PreviewCardTrend.where(language: language, allowed: true).by_rank.ranked_below(options[:review_threshold]).first&.score || 0 - preview_card_trends = PreviewCardTrend.where(language: language, allowed: false).joins(:preview_card) + score_at_threshold = PreviewCardTrend.where(language: language).allowed.by_rank.ranked_below(options[:review_threshold]).first&.score || 0 + preview_card_trends = PreviewCardTrend.where(language: language).not_allowed.joins(:preview_card) preview_card_trends.filter_map do |trend| preview_card = trend.preview_card diff --git a/app/models/user.rb b/app/models/user.rb index 17ec90c9e..584120cf2 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -95,6 +95,8 @@ class User < ApplicationRecord accepts_nested_attributes_for :invite_request, reject_if: ->(attributes) { attributes['text'].blank? && !Setting.require_invite_text } validates :invite_request, presence: true, on: :create, if: :invite_text_required? + validates :email, presence: true, email_address: true + validates_with BlacklistedEmailValidator, if: -> { ENV['EMAIL_DOMAIN_LISTS_APPLY_AFTER_CONFIRMATION'] == 'true' || !confirmed? } validates_with EmailMxValidator, if: :validate_email_dns? validates :agreement, acceptance: { allow_nil: false, accept: [true, 'true', '1'] }, on: :create @@ -107,14 +109,16 @@ class User < ApplicationRecord validates :confirm_password, absence: true, on: :create validate :validate_role_elevation + scope :account_not_suspended, -> { joins(:account).merge(Account.without_suspended) } scope :recent, -> { order(id: :desc) } scope :pending, -> { where(approved: false) } scope :approved, -> { where(approved: true) } scope :confirmed, -> { where.not(confirmed_at: nil) } scope :enabled, -> { where(disabled: false) } scope :disabled, -> { where(disabled: true) } - scope :inactive, -> { where(arel_table[:current_sign_in_at].lt(ACTIVE_DURATION.ago)) } - scope :active, -> { confirmed.where(arel_table[:current_sign_in_at].gteq(ACTIVE_DURATION.ago)).joins(:account).where(accounts: { suspended_at: nil }) } + scope :active, -> { confirmed.signed_in_recently.account_not_suspended } + scope :signed_in_recently, -> { where(current_sign_in_at: ACTIVE_DURATION.ago..) } + scope :not_signed_in_recently, -> { where(current_sign_in_at: ...ACTIVE_DURATION.ago) } scope :matches_email, ->(value) { where(arel_table[:email].matches("#{value}%")) } scope :matches_ip, ->(value) { left_joins(:ips).where('user_ips.ip <<= ?', value).group('users.id') } diff --git a/app/models/user_invite_request.rb b/app/models/user_invite_request.rb index 2b76c88b9..9dd677516 100644 --- a/app/models/user_invite_request.rb +++ b/app/models/user_invite_request.rb @@ -12,6 +12,8 @@ # class UserInviteRequest < ApplicationRecord + TEXT_SIZE_LIMIT = 420 + belongs_to :user, inverse_of: :invite_request - validates :text, presence: true, length: { maximum: 420 } + validates :text, presence: true, length: { maximum: TEXT_SIZE_LIMIT } end diff --git a/app/models/user_ip.rb b/app/models/user_ip.rb index 87b86a24d..a6da2c074 100644 --- a/app/models/user_ip.rb +++ b/app/models/user_ip.rb @@ -15,4 +15,6 @@ class UserIp < ApplicationRecord self.primary_key = :user_id belongs_to :user + + scope :by_latest_used, -> { order(used_at: :desc) } end diff --git a/app/serializers/rest/account_warning_serializer.rb b/app/serializers/rest/account_warning_serializer.rb new file mode 100644 index 000000000..a0ef341d2 --- /dev/null +++ b/app/serializers/rest/account_warning_serializer.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class REST::AccountWarningSerializer < ActiveModel::Serializer + attributes :id, :action, :text, :status_ids, :created_at + + has_one :target_account, serializer: REST::AccountSerializer + has_one :appeal, serializer: REST::AppealSerializer + + def id + object.id.to_s + end + + def status_ids + object&.status_ids&.map(&:to_s) + end +end diff --git a/app/serializers/rest/announcement_serializer.rb b/app/serializers/rest/announcement_serializer.rb index 8cee27127..d1a011425 100644 --- a/app/serializers/rest/announcement_serializer.rb +++ b/app/serializers/rest/announcement_serializer.rb @@ -9,7 +9,7 @@ class REST::AnnouncementSerializer < ActiveModel::Serializer attribute :read, if: :current_user? has_many :mentions - has_many :statuses + has_many :statuses, serializer: REST::StatusSerializer has_many :tags, serializer: REST::StatusSerializer::TagSerializer has_many :emojis, serializer: REST::CustomEmojiSerializer has_many :reactions, serializer: REST::ReactionSerializer @@ -49,16 +49,4 @@ class REST::AnnouncementSerializer < ActiveModel::Serializer object.pretty_acct end end - - class StatusSerializer < ActiveModel::Serializer - attributes :id, :url - - def id - object.id.to_s - end - - def url - ActivityPub::TagManager.instance.url_for(object) - end - end end diff --git a/app/serializers/rest/appeal_serializer.rb b/app/serializers/rest/appeal_serializer.rb new file mode 100644 index 000000000..a24cabc27 --- /dev/null +++ b/app/serializers/rest/appeal_serializer.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class REST::AppealSerializer < ActiveModel::Serializer + attributes :text, :state + + def state + if object.approved? + 'approved' + elsif object.rejected? + 'rejected' + else + 'pending' + end + end +end diff --git a/app/serializers/rest/instance_serializer.rb b/app/serializers/rest/instance_serializer.rb index fa926cd28..42b73f438 100644 --- a/app/serializers/rest/instance_serializer.rb +++ b/app/serializers/rest/instance_serializer.rb @@ -54,6 +54,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer accounts: { max_featured_tags: FeaturedTag::LIMIT, + max_pinned_statuses: StatusPinValidator::PIN_LIMIT, }, statuses: { diff --git a/app/serializers/rest/marker_serializer.rb b/app/serializers/rest/marker_serializer.rb index 2eaf3d507..b0c1c553f 100644 --- a/app/serializers/rest/marker_serializer.rb +++ b/app/serializers/rest/marker_serializer.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class REST::MarkerSerializer < ActiveModel::Serializer + # Please update `app/javascript/mastodon/api_types/markers.ts` when making changes to the attributes + attributes :last_read_id, :version, :updated_at def last_read_id diff --git a/app/serializers/rest/media_attachment_serializer.rb b/app/serializers/rest/media_attachment_serializer.rb index f27dda832..90a2a9727 100644 --- a/app/serializers/rest/media_attachment_serializer.rb +++ b/app/serializers/rest/media_attachment_serializer.rb @@ -3,6 +3,8 @@ class REST::MediaAttachmentSerializer < ActiveModel::Serializer include RoutingHelper + # Please update `app/javascript/mastodon/api_types/media_attachments.ts` when making changes to the attributes + attributes :id, :type, :url, :preview_url, :remote_url, :preview_remote_url, :text_url, :meta, :description, :blurhash diff --git a/app/serializers/rest/notification_policy_serializer.rb b/app/serializers/rest/notification_policy_serializer.rb index 4967c3e32..a50ba9e66 100644 --- a/app/serializers/rest/notification_policy_serializer.rb +++ b/app/serializers/rest/notification_policy_serializer.rb @@ -9,8 +9,8 @@ class REST::NotificationPolicySerializer < ActiveModel::Serializer def summary { - pending_requests_count: object.pending_requests_count.to_s, - pending_notifications_count: object.pending_notifications_count.to_s, + pending_requests_count: object.pending_requests_count.to_i, + pending_notifications_count: object.pending_notifications_count.to_i, } end end diff --git a/app/serializers/rest/notification_serializer.rb b/app/serializers/rest/notification_serializer.rb index 36a0adfec..417245d19 100644 --- a/app/serializers/rest/notification_serializer.rb +++ b/app/serializers/rest/notification_serializer.rb @@ -7,6 +7,7 @@ class REST::NotificationSerializer < ActiveModel::Serializer belongs_to :target_status, key: :status, if: :status_type?, serializer: REST::StatusSerializer belongs_to :report, if: :report_type?, serializer: REST::ReportSerializer belongs_to :account_relationship_severance_event, key: :event, if: :relationship_severance_event?, serializer: REST::AccountRelationshipSeveranceEventSerializer + belongs_to :account_warning, key: :moderation_warning, if: :moderation_warning_event?, serializer: REST::AccountWarningSerializer def id object.id.to_s @@ -23,4 +24,8 @@ class REST::NotificationSerializer < ActiveModel::Serializer def relationship_severance_event? object.type == :severed_relationships end + + def moderation_warning_event? + object.type == :moderation_warning + end end diff --git a/app/serializers/rest/poll_serializer.rb b/app/serializers/rest/poll_serializer.rb index df6ebd0d4..6e0006073 100644 --- a/app/serializers/rest/poll_serializer.rb +++ b/app/serializers/rest/poll_serializer.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class REST::PollSerializer < ActiveModel::Serializer + # Please update `app/javascript/mastodon/api_types/polls.ts` when making changes to the attributes + attributes :id, :expires_at, :expired, :multiple, :votes_count, :voters_count diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb index d32621541..e17e8c823 100644 --- a/app/serializers/rest/status_serializer.rb +++ b/app/serializers/rest/status_serializer.rb @@ -3,6 +3,8 @@ class REST::StatusSerializer < ActiveModel::Serializer include FormattingHelper + # Please update `app/javascript/mastodon/api_types/statuses.ts` when making changes to the attributes + attributes :id, :created_at, :in_reply_to_id, :in_reply_to_account_id, :sensitive, :spoiler_text, :visibility, :language, :uri, :url, :replies_count, :reblogs_count, diff --git a/app/services/after_block_domain_from_account_service.rb b/app/services/after_block_domain_from_account_service.rb index adb17845c..fc5dc6568 100644 --- a/app/services/after_block_domain_from_account_service.rb +++ b/app/services/after_block_domain_from_account_service.rb @@ -12,6 +12,7 @@ class AfterBlockDomainFromAccountService < BaseService @domain_block_event = nil clear_notifications! + clear_notification_permissions! remove_follows! reject_existing_followers! reject_pending_follow_requests! @@ -31,6 +32,10 @@ class AfterBlockDomainFromAccountService < BaseService Notification.where(account: @account).where(from_account: Account.where(domain: @domain)).in_batches.delete_all end + def clear_notification_permissions! + NotificationPermission.where(account: @account, from_account: Account.where(domain: @domain)).in_batches.delete_all + end + def reject_existing_followers! @account.passive_relationships.where(account: Account.where(domain: @domain)).includes(:account).reorder(nil).in_batches do |follows| domain_block_event.import_from_passive_follows!(follows) diff --git a/app/services/block_service.rb b/app/services/block_service.rb index 266a0f4b9..98229d98c 100644 --- a/app/services/block_service.rb +++ b/app/services/block_service.rb @@ -10,6 +10,8 @@ class BlockService < BaseService UnfollowService.new.call(target_account, account) if target_account.following?(account) RejectFollowService.new.call(target_account, account) if target_account.requested?(account) + NotificationPermission.where(account: account, from_account: target_account).destroy_all + block = account.block!(target_account) BlockWorker.perform_async(account.id, target_account.id) diff --git a/app/services/bulk_import_row_service.rb b/app/services/bulk_import_row_service.rb index ef4c18e78..26909dfe0 100644 --- a/app/services/bulk_import_row_service.rb +++ b/app/services/bulk_import_row_service.rb @@ -10,7 +10,7 @@ class BulkImportRowService when :following, :blocking, :muting, :lists target_acct = @data['acct'] target_domain = domain(target_acct) - @target_account = stoplight_wrap_request(target_domain) { ResolveAccountService.new.call(target_acct, { check_delivery_availability: true }) } + @target_account = stoplight_wrapper(target_domain).run { ResolveAccountService.new.call(target_acct, { check_delivery_availability: true }) } return false if @target_account.nil? when :bookmarks target_uri = @data['uri'] @@ -18,7 +18,7 @@ class BulkImportRowService @target_status = ActivityPub::TagManager.instance.uri_to_resource(target_uri, Status) return false if @target_status.nil? && ActivityPub::TagManager.instance.local_uri?(target_uri) - @target_status ||= stoplight_wrap_request(target_domain) { ActivityPub::FetchRemoteStatusService.new.call(target_uri) } + @target_status ||= stoplight_wrapper(target_domain).run { ActivityPub::FetchRemoteStatusService.new.call(target_uri) } return false if @target_status.nil? end @@ -51,16 +51,15 @@ class BulkImportRowService TagManager.instance.local_domain?(domain) ? nil : TagManager.instance.normalize_domain(domain) end - def stoplight_wrap_request(domain, &block) + def stoplight_wrapper(domain) if domain.present? - Stoplight("source:#{domain}", &block) + Stoplight("source:#{domain}") .with_fallback { nil } .with_threshold(1) .with_cool_off_time(5.minutes.seconds) .with_error_handler { |error, handle| error.is_a?(HTTP::Error) || error.is_a?(OpenSSL::SSL::SSLError) ? handle.call(error) : raise(error) } - .run else - yield + Stoplight('domain-blank') end end end diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb index c83e4c017..e56562c0a 100644 --- a/app/services/notify_service.rb +++ b/app/services/notify_service.rb @@ -9,6 +9,7 @@ class NotifyService < BaseService update poll status + moderation_warning # TODO: this probably warrants an email notification severed_relationships ).freeze @@ -22,7 +23,7 @@ class NotifyService < BaseService def dismiss? blocked = @recipient.unavailable? - blocked ||= from_self? && @notification.type != :poll && @notification.type != :severed_relationships + blocked ||= from_self? && %i(poll severed_relationships moderation_warning).exclude?(@notification.type) return blocked if message? && from_staff? @@ -75,6 +76,7 @@ class NotifyService < BaseService admin.report poll update + account_warning ).freeze def initialize(notification) diff --git a/app/validators/email_address_validator.rb b/app/validators/email_address_validator.rb new file mode 100644 index 000000000..ed0bb1165 --- /dev/null +++ b/app/validators/email_address_validator.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# NOTE: I initially wrote this as `EmailValidator` but it ended up clashing +# with an indirect dependency of ours, `validate_email`, which, turns out, +# has the same approach as we do, but with an extra check disallowing +# single-label domains. Decided to not switch to `validate_email` because +# we do want to allow at least `localhost`. + +class EmailAddressValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + value = value.strip + + address = Mail::Address.new(value) + record.errors.add(attribute, :invalid) if address.address != value + rescue Mail::Field::FieldError + record.errors.add(attribute, :invalid) + end +end diff --git a/app/views/admin/account_warnings/_account_warning.html.haml b/app/views/admin/account_warnings/_account_warning.html.haml index 5702e4f6d..368e69e63 100644 --- a/app/views/admin/account_warnings/_account_warning.html.haml +++ b/app/views/admin/account_warnings/_account_warning.html.haml @@ -2,7 +2,7 @@ .log-entry__header .log-entry__avatar .indicator-icon{ class: account_warning.overruled? ? 'success' : 'failure' } - = fa_icon 'warning' + = material_symbol 'warning' .log-entry__content .log-entry__title = t(account_warning.action, diff --git a/app/views/admin/accounts/_local_account.html.haml b/app/views/admin/accounts/_local_account.html.haml index 82197cda4..3ed392cd1 100644 --- a/app/views/admin/accounts/_local_account.html.haml +++ b/app/views/admin/accounts/_local_account.html.haml @@ -62,13 +62,7 @@ %td %time.formatted{ datetime: account.created_at.iso8601, title: l(account.created_at) }= l account.created_at %td -- recent_ips = account.user.ips.order(used_at: :desc).to_a -- recent_ips.each_with_index do |recent_ip, i| - %tr - - if i.zero? - %th{ rowspan: recent_ips.size }= t('admin.accounts.most_recent_ip') - %td= recent_ip.ip - %td= table_link_to 'search', t('admin.accounts.search_same_ip'), admin_accounts_path(ip: recent_ip.ip) + = render partial: 'admin/accounts/user_ip', collection: account.user.ips.by_latest_used %tr %th= t('admin.accounts.most_recent_activity') %td diff --git a/app/views/admin/accounts/_remote_account.html.haml b/app/views/admin/accounts/_remote_account.html.haml index 99996e1d4..6755af249 100644 --- a/app/views/admin/accounts/_remote_account.html.haml +++ b/app/views/admin/accounts/_remote_account.html.haml @@ -2,14 +2,14 @@ %th= t('admin.accounts.inbox_url') %td = account.inbox_url - = fa_icon DeliveryFailureTracker.available?(account.inbox_url) ? 'check' : 'times' + = material_symbol DeliveryFailureTracker.available?(account.inbox_url) ? 'check' : 'close' %td = table_link_to 'search', domain_block.present? ? t('admin.domain_blocks.view') : t('admin.accounts.view_domain'), admin_instance_path(account.domain) %tr %th= t('admin.accounts.shared_inbox_url') %td = account.shared_inbox_url - = fa_icon DeliveryFailureTracker.available?(account.shared_inbox_url) ? 'check' : 'times' + = material_symbol DeliveryFailureTracker.available?(account.shared_inbox_url) ? 'check' : 'close' %td - if domain_block.nil? = table_link_to 'ban', t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: account.domain) diff --git a/app/views/admin/accounts/_user_ip.html.haml b/app/views/admin/accounts/_user_ip.html.haml new file mode 100644 index 000000000..1938cf7ed --- /dev/null +++ b/app/views/admin/accounts/_user_ip.html.haml @@ -0,0 +1,5 @@ +%tr + - if user_ip_iteration.first? + %th{ rowspan: user_ip_iteration.size }= t('admin.accounts.most_recent_ip') + %td= user_ip.ip + %td= table_link_to 'search', t('admin.accounts.search_same_ip'), admin_accounts_path(ip: user_ip.ip) diff --git a/app/views/admin/accounts/index.html.haml b/app/views/admin/accounts/index.html.haml index 0ca457f39..01b072938 100644 --- a/app/views/admin/accounts/index.html.haml +++ b/app/views/admin/accounts/index.html.haml @@ -53,19 +53,19 @@ = check_box_tag :batch_checkbox_all, nil, false .batch-table__toolbar__actions - if @accounts.any?(&:user_pending?) - = f.button safe_join([fa_icon('check'), t('admin.accounts.approve')]), + = f.button safe_join([material_symbol('check'), t('admin.accounts.approve')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :approve, type: :submit - = f.button safe_join([fa_icon('times'), t('admin.accounts.reject')]), + = f.button safe_join([material_symbol('close'), t('admin.accounts.reject')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :reject, type: :submit - = f.button safe_join([fa_icon('lock'), t('admin.accounts.perform_full_suspension')]), + = f.button safe_join([material_symbol('lock'), t('admin.accounts.perform_full_suspension')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :suspend, diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index d380d807a..41fcafa29 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -20,7 +20,7 @@ %dd{ title: field.value, class: custom_field_classes(field) } - if field.verified? %span.verified__mark{ title: t('accounts.link_verified_on', date: l(field.verified_at)) } - = fa_icon 'check' + = material_symbol 'check' = prerender_custom_emojis(account_field_value_format(field, with_rel_me: false), account.emojis) - if account.note.present? diff --git a/app/views/admin/announcements/_form.html.haml b/app/views/admin/announcements/_form.html.haml new file mode 100644 index 000000000..3a9b37190 --- /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 23c568a88..8cec7d36c 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 a681ed789..266ca65e8 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 diff --git a/app/views/admin/custom_emojis/index.html.haml b/app/views/admin/custom_emojis/index.html.haml index bea6a7cd2..e87dd4128 100644 --- a/app/views/admin/custom_emojis/index.html.haml +++ b/app/views/admin/custom_emojis/index.html.haml @@ -48,19 +48,19 @@ - if params[:local] == '1' = f.button safe_join([fa_icon('save'), t('generic.save_changes')]), name: :update, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } - = f.button safe_join([fa_icon('eye'), t('admin.custom_emojis.list')]), name: :list, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = f.button safe_join([material_symbol('visibility'), t('admin.custom_emojis.list')]), name: :list, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } - = f.button safe_join([fa_icon('eye-slash'), t('admin.custom_emojis.unlist')]), name: :unlist, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = f.button safe_join([material_symbol('visibility_off'), t('admin.custom_emojis.unlist')]), name: :unlist, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } = f.button safe_join([fa_icon('power-off'), t('admin.custom_emojis.enable')]), name: :enable, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } = f.button safe_join([fa_icon('power-off'), t('admin.custom_emojis.disable')]), name: :disable, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } - if can?(:destroy, :custom_emoji) - = f.button safe_join([fa_icon('times'), t('admin.custom_emojis.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = f.button safe_join([material_symbol('close'), t('admin.custom_emojis.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } - if can?(:copy, :custom_emoji) && params[:local] != '1' - = f.button safe_join([fa_icon('copy'), t('admin.custom_emojis.copy')]), name: :copy, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = f.button safe_join([material_symbol('content_copy'), t('admin.custom_emojis.copy')]), name: :copy, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } - if params[:local] == '1' .batch-table__form.simple_form diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index 8a8099278..8430dd3c4 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -57,19 +57,19 @@ .dashboard__item = link_to admin_reports_path, class: 'dashboard__quick-access' do %span= t('admin.dashboard.pending_reports_html', count: @pending_reports_count) - = fa_icon 'chevron-right fw' + = material_symbol 'chevron_right' = link_to admin_accounts_path(status: 'pending'), class: 'dashboard__quick-access' do %span= t('admin.dashboard.pending_users_html', count: @pending_users_count) - = fa_icon 'chevron-right fw' + = material_symbol 'chevron_right' = link_to admin_trends_tags_path(status: 'pending_review'), class: 'dashboard__quick-access' do %span= t('admin.dashboard.pending_tags_html', count: @pending_tags_count) - = fa_icon 'chevron-right fw' + = material_symbol 'chevron_right' = link_to admin_disputes_appeals_path(status: 'pending'), class: 'dashboard__quick-access' do %span= t('admin.dashboard.pending_appeals_html', count: @pending_appeals_count) - = fa_icon 'chevron-right fw' + = material_symbol 'chevron_right' .dashboard__item = react_admin_component :dimension, dimension: 'sources', diff --git a/app/views/admin/domain_blocks/_form.html.haml b/app/views/admin/domain_blocks/_form.html.haml new file mode 100644 index 000000000..f1785a1fd --- /dev/null +++ b/app/views/admin/domain_blocks/_form.html.haml @@ -0,0 +1,46 @@ +.fields-row + .fields-row__column.fields-row__column-6.fields-group + = form.input :domain, + disabled: form.object.persisted?, + hint: t('admin.domain_blocks.new.hint'), + label: t('admin.domain_blocks.domain'), + readonly: form.object.persisted?, + required: true, + wrapper: :with_label + .fields-row__column.fields-row__column-6.fields-group + = form.input :severity, + collection: DomainBlock.severities.keys, + hint: t('admin.domain_blocks.new.severity.desc_html'), + include_blank: false, + label_method: ->(type) { t("admin.domain_blocks.new.severity.#{type}") }, + wrapper: :with_label +.fields-group + = form.input :reject_media, + as: :boolean, + hint: I18n.t('admin.domain_blocks.reject_media_hint'), + label: I18n.t('admin.domain_blocks.reject_media'), + wrapper: :with_label +.fields-group + = form.input :reject_reports, + as: :boolean, + hint: I18n.t('admin.domain_blocks.reject_reports_hint'), + label: I18n.t('admin.domain_blocks.reject_reports'), + wrapper: :with_label +.fields-group + = form.input :obfuscate, + as: :boolean, + hint: I18n.t('admin.domain_blocks.obfuscate_hint'), + label: I18n.t('admin.domain_blocks.obfuscate'), + wrapper: :with_label +.field-group + = form.input :private_comment, + as: :string, + hint: t('admin.domain_blocks.private_comment_hint'), + label: I18n.t('admin.domain_blocks.private_comment'), + wrapper: :with_label +.field-group + = form.input :public_comment, + as: :string, + hint: t('admin.domain_blocks.public_comment_hint'), + label: I18n.t('admin.domain_blocks.public_comment'), + wrapper: :with_label diff --git a/app/views/admin/domain_blocks/edit.html.haml b/app/views/admin/domain_blocks/edit.html.haml index 7c0a9823a..40c46b8b6 100644 --- a/app/views/admin/domain_blocks/edit.html.haml +++ b/app/views/admin/domain_blocks/edit.html.haml @@ -1,63 +1,12 @@ - content_for :page_title do = t('admin.domain_blocks.edit') -= simple_form_for @domain_block, url: admin_domain_block_path(@domain_block), method: :put do |f| += simple_form_for @domain_block, url: admin_domain_block_path(@domain_block), method: :put do |form| = render 'shared/error_messages', object: @domain_block - .fields-row - .fields-row__column.fields-row__column-6.fields-group - = f.input :domain, - disabled: true, - hint: t('admin.domain_blocks.new.hint'), - label: t('admin.domain_blocks.domain'), - readonly: true, - required: true, - wrapper: :with_label - - .fields-row__column.fields-row__column-6.fields-group - = f.input :severity, - collection: DomainBlock.severities.keys, - hint: t('admin.domain_blocks.new.severity.desc_html'), - include_blank: false, - label_method: ->(type) { t("admin.domain_blocks.new.severity.#{type}") }, - wrapper: :with_label - - .fields-group - = f.input :reject_media, - as: :boolean, - hint: I18n.t('admin.domain_blocks.reject_media_hint'), - label: I18n.t('admin.domain_blocks.reject_media'), - wrapper: :with_label - - .fields-group - = f.input :reject_reports, - as: :boolean, - hint: I18n.t('admin.domain_blocks.reject_reports_hint'), - label: I18n.t('admin.domain_blocks.reject_reports'), - wrapper: :with_label - - .fields-group - = f.input :obfuscate, - as: :boolean, - hint: I18n.t('admin.domain_blocks.obfuscate_hint'), - label: I18n.t('admin.domain_blocks.obfuscate'), - wrapper: :with_label - - .field-group - = f.input :private_comment, - as: :string, - hint: t('admin.domain_blocks.private_comment_hint'), - label: I18n.t('admin.domain_blocks.private_comment'), - wrapper: :with_label - - .field-group - = f.input :public_comment, - as: :string, - hint: t('admin.domain_blocks.public_comment_hint'), - label: I18n.t('admin.domain_blocks.public_comment'), - wrapper: :with_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/domain_blocks/new.html.haml b/app/views/admin/domain_blocks/new.html.haml index 6a9855529..78bcfcba8 100644 --- a/app/views/admin/domain_blocks/new.html.haml +++ b/app/views/admin/domain_blocks/new.html.haml @@ -1,61 +1,12 @@ - content_for :page_title do = t('.title') -= simple_form_for @domain_block, url: admin_domain_blocks_path do |f| += simple_form_for @domain_block, url: admin_domain_blocks_path do |form| = render 'shared/error_messages', object: @domain_block - .fields-row - .fields-row__column.fields-row__column-6.fields-group - = f.input :domain, - hint: t('.hint'), - label: t('admin.domain_blocks.domain'), - required: true, - wrapper: :with_label - - .fields-row__column.fields-row__column-6.fields-group - = f.input :severity, - collection: DomainBlock.severities.keys, - hint: t('.severity.desc_html'), - include_blank: false, - label_method: ->(type) { t(".severity.#{type}") }, - wrapper: :with_label - - .fields-group - = f.input :reject_media, - as: :boolean, - hint: I18n.t('admin.domain_blocks.reject_media_hint'), - label: I18n.t('admin.domain_blocks.reject_media'), - wrapper: :with_label - - .fields-group - = f.input :reject_reports, - as: :boolean, - hint: I18n.t('admin.domain_blocks.reject_reports_hint'), - label: I18n.t('admin.domain_blocks.reject_reports'), - wrapper: :with_label - - .fields-group - = f.input :obfuscate, - as: :boolean, - hint: I18n.t('admin.domain_blocks.obfuscate_hint'), - label: I18n.t('admin.domain_blocks.obfuscate'), - wrapper: :with_label - - .field-group - = f.input :private_comment, - as: :string, - hint: t('admin.domain_blocks.private_comment_hint'), - label: I18n.t('admin.domain_blocks.private_comment'), - wrapper: :with_label - - .field-group - = f.input :public_comment, - as: :string, - hint: t('admin.domain_blocks.public_comment_hint'), - label: I18n.t('admin.domain_blocks.public_comment'), - wrapper: :with_label + = render form .actions - = f.button :button, - t('.create'), - type: :submit + = form.button :button, + t('.create'), + type: :submit diff --git a/app/views/admin/email_domain_blocks/index.html.haml b/app/views/admin/email_domain_blocks/index.html.haml index 59036f899..684735c20 100644 --- a/app/views/admin/email_domain_blocks/index.html.haml +++ b/app/views/admin/email_domain_blocks/index.html.haml @@ -12,7 +12,7 @@ %label.batch-table__toolbar__select.batch-checkbox-all = check_box_tag :batch_checkbox_all, nil, false .batch-table__toolbar__actions - = f.button safe_join([fa_icon('times'), t('admin.email_domain_blocks.delete')]), + = f.button safe_join([material_symbol('close'), t('admin.email_domain_blocks.delete')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :delete, diff --git a/app/views/admin/export_domain_blocks/_domain_block.html.haml b/app/views/admin/export_domain_blocks/_domain_block.html.haml index cdce4fd28..79cc5595c 100644 --- a/app/views/admin/export_domain_blocks/_domain_block.html.haml +++ b/app/views/admin/export_domain_blocks/_domain_block.html.haml @@ -23,5 +23,5 @@ = f.object.public_comment - if existing_relationships · - = fa_icon 'warning fw' + = material_symbol 'warning' = t('admin.export_domain_blocks.import.existing_relationships_warning') diff --git a/app/views/admin/export_domain_blocks/import.html.haml b/app/views/admin/export_domain_blocks/import.html.haml index 48016a9ab..52ffc3d46 100644 --- a/app/views/admin/export_domain_blocks/import.html.haml +++ b/app/views/admin/export_domain_blocks/import.html.haml @@ -12,7 +12,7 @@ %label.batch-table__toolbar__select.batch-checkbox-all = check_box_tag :batch_checkbox_all, nil, false .batch-table__toolbar__actions - = f.button safe_join([fa_icon('copy'), t('admin.domain_blocks.import')]), + = f.button safe_join([material_symbol('content_copy'), t('admin.domain_blocks.import')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :save, diff --git a/app/views/admin/follow_recommendations/show.html.haml b/app/views/admin/follow_recommendations/show.html.haml index 9d23f9ba5..c8ad653a8 100644 --- a/app/views/admin/follow_recommendations/show.html.haml +++ b/app/views/admin/follow_recommendations/show.html.haml @@ -31,13 +31,13 @@ = check_box_tag :batch_checkbox_all, nil, false .batch-table__toolbar__actions - if params[:status].blank? && can?(:suppress, :follow_recommendation) - = f.button safe_join([fa_icon('times'), t('admin.follow_recommendations.suppress')]), + = f.button safe_join([material_symbol('close'), t('admin.follow_recommendations.suppress')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :suppress, type: :submit - if params[:status] == 'suppressed' && can?(:unsuppress, :follow_recommendation) - = f.button safe_join([fa_icon('plus'), t('admin.follow_recommendations.unsuppress')]), + = f.button safe_join([material_symbol('add'), t('admin.follow_recommendations.unsuppress')]), class: 'table-action-link', name: :unsuppress, type: :submit diff --git a/app/views/admin/instances/show.html.haml b/app/views/admin/instances/show.html.haml index 5bf4e899f..d916203d0 100644 --- a/app/views/admin/instances/show.html.haml +++ b/app/views/admin/instances/show.html.haml @@ -9,7 +9,7 @@ - if @instance.persisted? %p - = fa_icon 'info fw' + = material_symbol 'info' = t('admin.instances.totals_time_period_hint_html') .dashboard diff --git a/app/views/admin/invites/_invite.html.haml b/app/views/admin/invites/_invite.html.haml index e6ad9de34..f9cd6003f 100644 --- a/app/views/admin/invites/_invite.html.haml +++ b/app/views/admin/invites/_invite.html.haml @@ -12,7 +12,7 @@ - if invite.valid_for_use? %td - = fa_icon 'user fw' + = material_symbol 'person' = invite.uses = " / #{invite.max_uses}" unless invite.max_uses.nil? %td diff --git a/app/views/admin/ip_blocks/index.html.haml b/app/views/admin/ip_blocks/index.html.haml index f1d2b3dc4..9eba6c68f 100644 --- a/app/views/admin/ip_blocks/index.html.haml +++ b/app/views/admin/ip_blocks/index.html.haml @@ -14,7 +14,7 @@ = check_box_tag :batch_checkbox_all, nil, false .batch-table__toolbar__actions - if can?(:destroy, :ip_block) - = f.button safe_join([fa_icon('times'), t('admin.ip_blocks.delete')]), + = f.button safe_join([material_symbol('close'), t('admin.ip_blocks.delete')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :delete, diff --git a/app/views/admin/relationships/index.html.haml b/app/views/admin/relationships/index.html.haml index 8260430d8..c2daefb42 100644 --- a/app/views/admin/relationships/index.html.haml +++ b/app/views/admin/relationships/index.html.haml @@ -19,7 +19,7 @@ .back-link = link_to admin_account_path(@account.id) do - = fa_icon 'chevron-left fw' + = material_symbol 'chevron_left' = t('admin.statuses.back_to_account') %hr.spacer/ @@ -30,7 +30,7 @@ %label.batch-table__toolbar__select.batch-checkbox-all = check_box_tag :batch_checkbox_all, nil, false .batch-table__toolbar__actions - = f.button safe_join([fa_icon('lock'), t('admin.accounts.perform_full_suspension')]), + = f.button safe_join([material_symbol('lock'), t('admin.accounts.perform_full_suspension')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :suspend, diff --git a/app/views/admin/relays/_relay.html.haml b/app/views/admin/relays/_relay.html.haml index f1dd2b2dd..0960124cc 100644 --- a/app/views/admin/relays/_relay.html.haml +++ b/app/views/admin/relays/_relay.html.haml @@ -4,7 +4,7 @@ %td - if relay.accepted? %span.positive-hint - = fa_icon('check') + = material_symbol('check')   = t 'admin.relays.enabled' - elsif relay.pending? @@ -13,7 +13,7 @@ = t 'admin.relays.pending' - else %span.negative-hint - = fa_icon('times') + = material_symbol('close')   = t 'admin.relays.disabled' %td diff --git a/app/views/admin/reports/_header_card.html.haml b/app/views/admin/reports/_header_card.html.haml index e90e3f9c9..52e62b449 100644 --- a/app/views/admin/reports/_header_card.html.haml +++ b/app/views/admin/reports/_header_card.html.haml @@ -16,7 +16,7 @@ %strong.emojify.p-name= display_name(report.target_account, custom_emojify: true) %span = acct(report.target_account) - = fa_icon('lock') if report.target_account.locked? + = material_symbol('lock') if report.target_account.locked? - if report.target_account.note.present? .account-card__bio.emojify = prerender_custom_emojis(account_bio_format(report.target_account), report.target_account.emojis) diff --git a/app/views/admin/reports/_status.html.haml b/app/views/admin/reports/_status.html.haml index 3775a1101..66820f0a6 100644 --- a/app/views/admin/reports/_status.html.haml +++ b/app/views/admin/reports/_status.html.haml @@ -37,5 +37,5 @@ = t("statuses.visibilities.#{status.visibility}") - if status.proper.sensitive? · - = fa_icon('eye-slash fw') + = material_symbol('visibility_off') = t('stream_entries.sensitive_content') diff --git a/app/views/admin/reports/actions/preview.html.haml b/app/views/admin/reports/actions/preview.html.haml index 8634bb215..7a737d4f7 100644 --- a/app/views/admin/reports/actions/preview.html.haml +++ b/app/views/admin/reports/actions/preview.html.haml @@ -58,7 +58,7 @@ - status.ordered_media_attachments.each do |media_attachment| %abbr{ title: media_attachment.description } - = fa_icon 'link' + = material_symbol 'link' = media_attachment.file_file_name .strike-card__statuses-list__item__meta = link_to ActivityPub::TagManager.instance.url_for(status), target: '_blank', rel: 'noopener noreferrer' do diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml index e37fa2590..c880021cf 100644 --- a/app/views/admin/reports/show.html.haml +++ b/app/views/admin/reports/show.html.haml @@ -41,7 +41,7 @@ %p = t 'admin.reports.statuses_description_html' — - = link_to safe_join([fa_icon('plus'), t('admin.reports.add_to_report')]), + = link_to safe_join([material_symbol('add'), t('admin.reports.add_to_report')]), admin_account_statuses_path(@report.target_account_id, report_id: @report.id), class: 'table-action-link' @@ -52,7 +52,7 @@ = check_box_tag :batch_checkbox_all, nil, false .batch-table__toolbar__actions - if !@statuses.empty? && @report.unresolved? - = f.button safe_join([fa_icon('times'), t('admin.statuses.batch.remove_from_report')]), name: :remove_from_report, class: 'table-action-link', type: :submit + = f.button safe_join([material_symbol('close'), t('admin.statuses.batch.remove_from_report')]), name: :remove_from_report, class: 'table-action-link', type: :submit .batch-table__body - if @statuses.empty? = nothing_here 'nothing-here--under-tabs' diff --git a/app/views/admin/roles/_role.html.haml b/app/views/admin/roles/_role.html.haml index d6c6b62c8..fd37644c8 100644 --- a/app/views/admin/roles/_role.html.haml +++ b/app/views/admin/roles/_role.html.haml @@ -2,7 +2,7 @@ - if can?(:update, role) = link_to edit_admin_role_path(role), class: 'announcements-list__item__title' do %span.user-role{ class: "user-role-#{role.id}" } - = fa_icon 'users fw' + = material_symbol 'group' - if role.everyone? = t('admin.roles.everyone') @@ -11,7 +11,7 @@ - else %span.announcements-list__item__title %span.user-role{ class: "user-role-#{role.id}" } - = fa_icon 'users fw' + = material_symbol 'group' - if role.everyone? = t('admin.roles.everyone') diff --git a/app/views/admin/rules/_rule.html.haml b/app/views/admin/rules/_rule.html.haml index a0896fe80..5f37f6935 100644 --- a/app/views/admin/rules/_rule.html.haml +++ b/app/views/admin/rules/_rule.html.haml @@ -5,7 +5,7 @@ .announcements-list__item__action-bar .announcements-list__item__meta - = rule.text + = rule.hint %div = table_link_to 'trash', t('admin.rules.delete'), admin_rule_path(rule), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:destroy, rule) diff --git a/app/views/admin/settings/shared/_links.html.haml b/app/views/admin/settings/shared/_links.html.haml index d8b697592..8b0678d4c 100644 --- a/app/views/admin/settings/shared/_links.html.haml +++ b/app/views/admin/settings/shared/_links.html.haml @@ -3,7 +3,7 @@ :ruby primary.item :branding, safe_join([fa_icon('pencil fw'), t('admin.settings.branding.title')]), admin_settings_branding_path primary.item :about, safe_join([fa_icon('file-text fw'), t('admin.settings.about.title')]), admin_settings_about_path - primary.item :registrations, safe_join([fa_icon('users fw'), t('admin.settings.registrations.title')]), admin_settings_registrations_path + primary.item :registrations, safe_join([material_symbol('group'), t('admin.settings.registrations.title')]), admin_settings_registrations_path primary.item :discovery, safe_join([fa_icon('search fw'), t('admin.settings.discovery.title')]), admin_settings_discovery_path primary.item :content_retention, safe_join([fa_icon('history fw'), t('admin.settings.content_retention.title')]), admin_settings_content_retention_path primary.item :appearance, safe_join([fa_icon('desktop fw'), t('admin.settings.appearance.title')]), admin_settings_appearance_path diff --git a/app/views/admin/status_edits/_status_edit.html.haml b/app/views/admin/status_edits/_status_edit.html.haml index 725477721..0bec0159e 100644 --- a/app/views/admin/status_edits/_status_edit.html.haml +++ b/app/views/admin/status_edits/_status_edit.html.haml @@ -26,5 +26,5 @@ - if status_edit.sensitive? · - = fa_icon('eye-slash fw') + = material_symbol('visibility_off') = t('stream_entries.sensitive_content') diff --git a/app/views/admin/statuses/index.html.haml b/app/views/admin/statuses/index.html.haml index 33a41bd36..a41a6332d 100644 --- a/app/views/admin/statuses/index.html.haml +++ b/app/views/admin/statuses/index.html.haml @@ -12,11 +12,11 @@ .back-link - if params[:report_id] = link_to admin_report_path(params[:report_id].to_i) do - = fa_icon 'chevron-left fw' + = material_symbol 'chevron_left' = t('admin.statuses.back_to_report') - else = link_to admin_account_path(@account.id) do - = fa_icon 'chevron-left fw' + = material_symbol 'chevron_left' = t('admin.statuses.back_to_account') %hr.spacer/ diff --git a/app/views/admin/tags/show.html.haml b/app/views/admin/tags/show.html.haml index 2e4424bec..f2d87b54b 100644 --- a/app/views/admin/tags/show.html.haml +++ b/app/views/admin/tags/show.html.haml @@ -52,26 +52,26 @@ = link_to admin_tag_path(@tag.id), class: ['dashboard__quick-access', @tag.usable? ? 'positive' : 'negative'] do - if @tag.usable? %span= t('admin.trends.tags.usable') - = fa_icon 'check fw' + = material_symbol 'check' - else %span= t('admin.trends.tags.not_usable') - = fa_icon 'lock fw' + = material_symbol 'lock' = link_to admin_tag_path(@tag.id), class: ['dashboard__quick-access', @tag.trendable? ? 'positive' : 'negative'] do - if @tag.trendable? %span= t('admin.trends.tags.trendable') - = fa_icon 'check fw' + = material_symbol 'check' - else %span= t('admin.trends.tags.not_trendable') - = fa_icon 'lock fw' + = material_symbol 'lock' = link_to admin_tag_path(@tag.id), class: ['dashboard__quick-access', @tag.listable? ? 'positive' : 'negative'] do - if @tag.listable? %span= t('admin.trends.tags.listable') - = fa_icon 'check fw' + = material_symbol 'check' - else %span= t('admin.trends.tags.not_listable') - = fa_icon 'lock fw' + = material_symbol 'lock' %hr.spacer/ diff --git a/app/views/admin/trends/links/index.html.haml b/app/views/admin/trends/links/index.html.haml index 965d2b2e5..c503b2d39 100644 --- a/app/views/admin/trends/links/index.html.haml +++ b/app/views/admin/trends/links/index.html.haml @@ -24,7 +24,7 @@ .back-link = link_to admin_trends_links_preview_card_providers_path do = t('admin.trends.preview_card_providers.title') - = fa_icon 'chevron-right fw' + = material_symbol 'chevron_right' = form_for(@form, url: batch_admin_trends_links_path) do |f| = hidden_field_tag :page, params[:page] || 1 @@ -37,22 +37,22 @@ %label.batch-table__toolbar__select.batch-checkbox-all = check_box_tag :batch_checkbox_all, nil, false .batch-table__toolbar__actions - = f.button safe_join([fa_icon('check'), t('admin.trends.links.allow')]), + = f.button safe_join([material_symbol('check'), t('admin.trends.links.allow')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :approve, type: :submit - = f.button safe_join([fa_icon('check'), t('admin.trends.links.allow_provider')]), + = f.button safe_join([material_symbol('check'), t('admin.trends.links.allow_provider')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :approve_providers, type: :submit - = f.button safe_join([fa_icon('times'), t('admin.trends.links.disallow')]), + = f.button safe_join([material_symbol('close'), t('admin.trends.links.disallow')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :reject, type: :submit - = f.button safe_join([fa_icon('times'), t('admin.trends.links.disallow_provider')]), + = f.button safe_join([material_symbol('close'), t('admin.trends.links.disallow_provider')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :reject_providers, diff --git a/app/views/admin/trends/links/preview_card_providers/index.html.haml b/app/views/admin/trends/links/preview_card_providers/index.html.haml index c91822fb7..706c60701 100644 --- a/app/views/admin/trends/links/preview_card_providers/index.html.haml +++ b/app/views/admin/trends/links/preview_card_providers/index.html.haml @@ -15,7 +15,7 @@ %li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{PreviewCardProvider.pending_review.count})"], ' '), status: 'pending_review' .back-link = link_to admin_trends_links_path do - = fa_icon 'chevron-left fw' + = material_symbol 'chevron_left' = t('admin.trends.links.title') %hr.spacer/ @@ -31,12 +31,12 @@ %label.batch-table__toolbar__select.batch-checkbox-all = check_box_tag :batch_checkbox_all, nil, false .batch-table__toolbar__actions - = f.button safe_join([fa_icon('check'), t('admin.trends.allow')]), + = f.button safe_join([material_symbol('check'), t('admin.trends.allow')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :approve, type: :submit - = f.button safe_join([fa_icon('times'), t('admin.trends.disallow')]), + = f.button safe_join([material_symbol('close'), t('admin.trends.disallow')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :reject, diff --git a/app/views/admin/trends/statuses/_status.html.haml b/app/views/admin/trends/statuses/_status.html.haml index 095f3f218..09547ff03 100644 --- a/app/views/admin/trends/statuses/_status.html.haml +++ b/app/views/admin/trends/statuses/_status.html.haml @@ -11,7 +11,7 @@ - status.ordered_media_attachments.each do |media_attachment| %abbr{ title: media_attachment.description } - = fa_icon 'link' + = material_symbol 'link' = media_attachment.file_file_name = t 'admin.trends.statuses.shared_by', diff --git a/app/views/admin/trends/statuses/index.html.haml b/app/views/admin/trends/statuses/index.html.haml index 0891d15fc..66151ad31 100644 --- a/app/views/admin/trends/statuses/index.html.haml +++ b/app/views/admin/trends/statuses/index.html.haml @@ -31,22 +31,22 @@ %label.batch-table__toolbar__select.batch-checkbox-all = check_box_tag :batch_checkbox_all, nil, false .batch-table__toolbar__actions - = f.button safe_join([fa_icon('check'), t('admin.trends.statuses.allow')]), + = f.button safe_join([material_symbol('check'), t('admin.trends.statuses.allow')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :approve, type: :submit - = f.button safe_join([fa_icon('check'), t('admin.trends.statuses.allow_account')]), + = f.button safe_join([material_symbol('check'), t('admin.trends.statuses.allow_account')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :approve_accounts, type: :submit - = f.button safe_join([fa_icon('times'), t('admin.trends.statuses.disallow')]), + = f.button safe_join([material_symbol('close'), t('admin.trends.statuses.disallow')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :reject, type: :submit - = f.button safe_join([fa_icon('times'), t('admin.trends.statuses.disallow_account')]), + = f.button safe_join([material_symbol('close'), t('admin.trends.statuses.disallow_account')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :reject_accounts, diff --git a/app/views/admin/trends/tags/_tag.html.haml b/app/views/admin/trends/tags/_tag.html.haml index 70c7d8dbd..8cc0d713b 100644 --- a/app/views/admin/trends/tags/_tag.html.haml +++ b/app/views/admin/trends/tags/_tag.html.haml @@ -5,7 +5,7 @@ .batch-table__row__content.pending-account .pending-account__header = link_to admin_tag_path(tag.id) do - = fa_icon 'hashtag' + = material_symbol 'tag' = tag.display_name %br/ diff --git a/app/views/admin/trends/tags/index.html.haml b/app/views/admin/trends/tags/index.html.haml index effde7b0e..655955f7f 100644 --- a/app/views/admin/trends/tags/index.html.haml +++ b/app/views/admin/trends/tags/index.html.haml @@ -25,12 +25,12 @@ %label.batch-table__toolbar__select.batch-checkbox-all = check_box_tag :batch_checkbox_all, nil, false .batch-table__toolbar__actions - = f.button safe_join([fa_icon('check'), t('admin.trends.allow')]), + = f.button safe_join([material_symbol('check'), t('admin.trends.allow')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :approve, type: :submit - = f.button safe_join([fa_icon('times'), t('admin.trends.disallow')]), + = f.button safe_join([material_symbol('close'), t('admin.trends.disallow')]), class: 'table-action-link', data: { confirm: t('admin.reports.are_you_sure') }, name: :reject, diff --git a/app/views/admin_mailer/new_critical_software_updates.text.erb b/app/views/admin_mailer/new_critical_software_updates.text.erb index 63c170dc0..a3f031bda 100644 --- a/app/views/admin_mailer/new_critical_software_updates.text.erb +++ b/app/views/admin_mailer/new_critical_software_updates.text.erb @@ -1,3 +1,7 @@ <%= raw t('admin_mailer.new_critical_software_updates.body') %> +<% @software_updates.each do |update| %> +- Mastodon <%= update.version %>: <%= update.release_notes %> +<% end %> + <%= raw t('application_mailer.view')%> <%= admin_software_updates_url %> diff --git a/app/views/admin_mailer/new_software_updates.text.erb b/app/views/admin_mailer/new_software_updates.text.erb index 96808f3cb..0eccbbf9e 100644 --- a/app/views/admin_mailer/new_software_updates.text.erb +++ b/app/views/admin_mailer/new_software_updates.text.erb @@ -1,3 +1,7 @@ <%= raw t('admin_mailer.new_software_updates.body') %> +<% @software_updates.each do |update| %> +- Mastodon <%= update.version %>: <%= update.release_notes %> +<% end %> + <%= raw t('application_mailer.view')%> <%= admin_software_updates_url %> diff --git a/app/views/application/mailer/_checklist.html.haml b/app/views/application/mailer/_checklist.html.haml index 324fd7e6f..91c7c98f2 100644 --- a/app/views/application/mailer/_checklist.html.haml +++ b/app/views/application/mailer/_checklist.html.haml @@ -16,16 +16,14 @@ = image_tag frontend_asset_url('images/mailer-new/welcome/checkbox-off.png'), alt: '', width: 20, height: 20 %td.email-checklist-icons-step-td - if defined?(key) - = image_tag frontend_asset_url("images/mailer-new/welcome-icons/#{key}-#{checked ? 'on' : 'off'}.png"), alt: '', width: 40, height: 40 + = image_tag frontend_asset_url("images/mailer-new/welcome-icons/#{key}_step-#{checked ? 'on' : 'off'}.png"), alt: '', width: 40, height: 40 %td.email-checklist-text-td .email-desktop-flex /[if mso]
%div - - if defined?(title) - %h3= title - - if defined?(text) - %p= text + %h3= t("user_mailer.welcome.#{key}_title") + %p= t("user_mailer.welcome.#{key}_step") /[if mso] %div diff --git a/app/views/application/mailer/_feature.html.haml b/app/views/application/mailer/_feature.html.haml index d051338a9..94dd4b9cf 100644 --- a/app/views/application/mailer/_feature.html.haml +++ b/app/views/application/mailer/_feature.html.haml @@ -4,17 +4,15 @@ %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } %tr %td.email-feature-td - .email-desktop-flex{ class: ('email-dir-rtl' if defined?(text_first_on_desktop) && !text_first_on_desktop) } + .email-desktop-flex{ class: ('email-dir-rtl' if feature_iteration.index.odd?) } /[if mso]
.email-desktop-column %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } %tr %td.email-column-td - - if defined?(feature_title) - %h2.email-h2= feature_title - - if defined?(feature_text) - %p.email-p= feature_text + %h2.email-h2= t("user_mailer.welcome.feature_#{feature}_title") + %p.email-p= t("user_mailer.welcome.feature_#{feature}") - if defined?(feature_btn_url) = link_to '', href: feature_btn_url, class: 'email-link-with-arrow' do #{t('user_mailer.welcome.feature_action')}  @@ -25,8 +23,8 @@ %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } %tr %td.email-column-td - - if defined?(key) - %p{ class: ('email-desktop-text-right' if defined?(text_first_on_desktop) && text_first_on_desktop) } - = image_tag frontend_asset_url("images/mailer-new/welcome/#{key}.png"), alt: '', width: 240, height: 230 + - if defined?(feature) + %p{ class: ('email-desktop-text-right' if feature_iteration.index.even?) } + = image_tag frontend_asset_url("images/mailer-new/welcome/feature_#{feature}.png"), alt: '', width: 240, height: 230 /[if mso]
diff --git a/app/views/application/mailer/_hashtag.html.haml b/app/views/application/mailer/_hashtag.html.haml index fcedfa80a..b740ba31b 100644 --- a/app/views/application/mailer/_hashtag.html.haml +++ b/app/views/application/mailer/_hashtag.html.haml @@ -1,4 +1,4 @@ -- accounts = hashtag.statuses.with_public_visibility.joins(:account).merge(Account.without_suspended.without_silenced).includes(:account).limit(3).map(&:account) +- accounts = hashtag.statuses.public_visibility.joins(:account).merge(Account.without_suspended.without_silenced).includes(:account).limit(3).map(&:account) %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } %tr @@ -17,4 +17,5 @@ %span.email-mini-hashtag-img-span = image_tag full_asset_url(account.avatar.url), alt: '', width: 16, height: 16 %td - %p= t('user_mailer.welcome.hashtags_recent_count', people: number_with_delimiter(hashtag.history.aggregate(2.days.ago.to_date..Time.zone.today).accounts)) + - people = hashtag.history.aggregate(2.days.ago.to_date..Time.zone.today).accounts + %p= t('user_mailer.welcome.hashtags_recent_count', people: number_with_delimiter(people), count: people) diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 449657f8c..9d7669d68 100755 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -21,13 +21,13 @@ %link{ rel: 'mask-icon', href: frontend_asset_path('images/logo-symbol-icon.svg'), color: '#6364FF' }/ %link{ rel: 'manifest', href: manifest_path(format: :json) }/ - %meta{ name: 'theme-color', content: '#191b22' }/ + = theme_color_tags current_theme %meta{ name: 'apple-mobile-web-app-capable', content: 'yes' }/ %title= html_title = stylesheet_pack_tag 'common', media: 'all', crossorigin: 'anonymous' - = stylesheet_pack_tag current_theme, media: 'all', crossorigin: 'anonymous' + = theme_style_tags current_theme -# Needed for the wicg-inert polyfill. It needs to be on it's own